Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Large version bubble Support #21727

Merged
merged 30 commits into from
Jan 15, 2019
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d4a84e4
Preliminary Changes
A-And Nov 2, 2018
802198e
Module Index Resolution
A-And Nov 3, 2018
6225fe0
Change infoModule encoding
A-And Nov 20, 2018
9501e85
Change referencing module in R2R
A-And Nov 21, 2018
2b4078c
Pre-condition Check
A-And Nov 27, 2018
e186935
Virtual Method Module Resolution
A-And Nov 28, 2018
77bd515
Remove Workarounds and add conditional import loading
A-And Nov 29, 2018
0a493d3
Add signature kind module override
A-And Dec 6, 2018
52b3b14
Add ELEMENT_TYPE_MODULE_ZAPSIG
A-And Dec 14, 2018
9d5c7f1
Add switch to enable large version bubble
A-And Dec 19, 2018
dfde969
Cleanup
A-And Dec 28, 2018
2243d12
Change Native header check
A-And Jan 1, 2019
772fb76
Add large version bubble test
A-And Jan 8, 2019
c2936e5
Merge branch 'master' into LargeVersionBubble
A-And Jan 8, 2019
a9bd79f
Add Large Version Bubble Checks
A-And Jan 9, 2019
ec660bd
Cleanup
A-And Jan 9, 2019
662fc7e
Revert unnecessary check
A-And Jan 9, 2019
ecaaddd
Change EncodeMethod Version Bubble Condition
A-And Jan 10, 2019
7868a56
Add Large Version Bubble asserts
A-And Jan 10, 2019
50f2bb0
Cleanup
A-And Jan 10, 2019
8254212
Add default argument to runtests.py
A-And Jan 10, 2019
87159c9
Change test PreCommands
A-And Jan 10, 2019
8e1ab01
Revert whitespace changes
A-And Jan 10, 2019
70711fd
Change breaking conditional check
A-And Jan 10, 2019
ea0880d
Merge branch 'master' into LargeVersionBubble
A-And Jan 10, 2019
1a423c9
Streamline Version Bubble test
A-And Jan 10, 2019
1dbbcf2
Address PR Feedback
A-And Jan 10, 2019
9d1cb13
Address PR Feedback #2
A-And Jan 11, 2019
01a3b82
Remove dead code
A-And Jan 12, 2019
a1e0594
Add crossgen-time ifdef
A-And Jan 12, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/inc/corcompile.h
Original file line number Diff line number Diff line change
Expand Up @@ -1812,6 +1812,7 @@ extern bool g_fNGenWinMDResilient;

#ifdef FEATURE_READYTORUN_COMPILER
extern bool g_fReadyToRunCompilation;
extern bool g_fLargeVersionBubble;
#endif

inline bool IsReadyToRunCompilation()
Expand All @@ -1823,4 +1824,13 @@ inline bool IsReadyToRunCompilation()
#endif
}

inline bool IsLargeVersionBubbleEnabled()
A-And marked this conversation as resolved.
Show resolved Hide resolved
{
#ifdef FEATURE_READYTORUN_COMPILER
return g_fLargeVersionBubble;
#else
return false;
#endif
}

#endif /* COR_COMPILE_H_ */
1 change: 1 addition & 0 deletions src/inc/coregen.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define NGENWORKER_FLAGS_TUNING 0x0001

#define NGENWORKER_FLAGS_MISSINGDEPENDENCIESOK 0x0004
#define NGENWORKER_FLAGS_LARGEVERSIONBUBBLE 0x0008

#define NGENWORKER_FLAGS_WINMD_RESILIENT 0x1000
#define NGENWORKER_FLAGS_READYTORUN 0x2000
Expand Down
3 changes: 2 additions & 1 deletion src/inc/pedecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ typedef DPTR(struct CORCOMPILE_HEADER) PTR_CORCOMPILE_HEADER;

#include "readytorun.h"
typedef DPTR(struct READYTORUN_HEADER) PTR_READYTORUN_HEADER;
typedef DPTR(struct READYTORUN_SECTION) PTR_READYTORUN_SECTION;

typedef DPTR(IMAGE_COR20_HEADER) PTR_IMAGE_COR20_HEADER;

Expand Down Expand Up @@ -400,7 +401,7 @@ class PEDecoder
IMAGE_NT_HEADERS *FindNTHeaders() const;
IMAGE_COR20_HEADER *FindCorHeader() const;
CORCOMPILE_HEADER *FindNativeHeader() const;
READYTORUN_HEADER *FindReadyToRunHeader() const;
READYTORUN_HEADER *FindReadyToRunHeader() const;

// Flat mapping utilities
RVA InternalAddressToRva(SIZE_T address) const;
Expand Down
3 changes: 2 additions & 1 deletion src/inc/readytorun.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ enum ReadyToRunSectionType
READYTORUN_SECTION_AVAILABLE_TYPES = 108,
READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS = 109,
READYTORUN_SECTION_INLINING_INFO = 110, // Added in V2.1
READYTORUN_SECTION_PROFILEDATA_INFO = 111 // Added in V2.2
READYTORUN_SECTION_PROFILEDATA_INFO = 111, // Added in V2.2
READYTORUN_SECTION_MANIFEST_METADATA = 112 // Added in V2.3

// If you add a new section consider whether it is a breaking or non-breaking change.
// Usually it is non-breaking, but if it is preferable to have older runtimes fail
Expand Down
9 changes: 9 additions & 0 deletions src/tools/crossgen/crossgen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ void PrintUsageHelper()
#ifdef FEATURE_READYTORUN_COMPILER
W(" /ReadyToRun - Generate images resilient to the runtime and\n")
W(" dependency versions\n")
W(" /LargeVersionBubble - Generate image with a version bubble including all\n")
W(" input assemblies\n")

#endif
#ifdef FEATURE_WINMD_RESILIENT
W(" WinMD Parameters\n")
Expand Down Expand Up @@ -422,6 +425,7 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
LPWSTR pwzSearchPathForManagedPDB = NULL;
LPCWSTR pwzOutputFilename = NULL;
LPCWSTR pwzPublicKeys = nullptr;
bool fLargeVersionBubbleSwitch = false;

#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
LPCWSTR pwszCLRJITPath = nullptr;
Expand Down Expand Up @@ -518,6 +522,11 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
{
dwFlags &= ~NGENWORKER_FLAGS_READYTORUN;
}
else if (MatchParameter(*argv, W("LargeVersionBubble")))
{
dwFlags |= NGENWORKER_FLAGS_LARGEVERSIONBUBBLE;
fLargeVersionBubbleSwitch = true;
}
#endif
else if (MatchParameter(*argv, W("NoMetaData")))
{
Expand Down
24 changes: 22 additions & 2 deletions src/utilcode/pedecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2481,14 +2481,34 @@ PTR_CVOID PEDecoder::GetNativeManifestMetadata(COUNT_T *pSize) const
CONTRACT(PTR_CVOID)
{
INSTANCE_CHECK;
PRECONDITION(CheckNativeHeader());
PRECONDITION(HasReadyToRunHeader() || CheckNativeHeader());
POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); // TBD - may not store metadata for IJW
NOTHROW;
GC_NOTRIGGER;
}
CONTRACT_END;

IMAGE_DATA_DIRECTORY *pDir;
if (HasReadyToRunHeader())
{
READYTORUN_HEADER * pHeader = GetReadyToRunHeader();

IMAGE_DATA_DIRECTORY *pDir = GetMetaDataHelper(METADATA_SECTION_MANIFEST);
PTR_READYTORUN_SECTION pSections = dac_cast<PTR_READYTORUN_SECTION>(dac_cast<TADDR>(pHeader) + sizeof(READYTORUN_HEADER));
for (DWORD i = 0; i < pHeader->NumberOfSections; i++)
{
// Verify that section types are sorted
_ASSERTE(i == 0 || (pSections[i - 1].Type < pSections[i].Type));

READYTORUN_SECTION * pSection = pSections + i;
if (pSection->Type == READYTORUN_SECTION_MANIFEST_METADATA)
// Set pDir to the address of the manifest metadata section
pDir = &pSection->Section;
}
}
else
{
pDir = GetMetaDataHelper(METADATA_SECTION_MANIFEST);
}

if (pSize != NULL)
*pSize = VAL32(pDir->Size);
Expand Down
23 changes: 16 additions & 7 deletions src/vm/ceeload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3537,7 +3537,7 @@ BOOL Module::IsInCurrentVersionBubble()
return TRUE;

if (IsReadyToRunCompilation())
return FALSE;
return IsLargeVersionBubbleEnabled();

#ifdef FEATURE_COMINTEROP
if (g_fNGenWinMDResilient)
Expand Down Expand Up @@ -9977,7 +9977,7 @@ Module *Module::GetModuleFromIndex(DWORD ix)
}
CONTRACT_END;

if (HasNativeImage())
if (HasNativeOrReadyToRunImage())
{
RETURN ZapSig::DecodeModuleFromIndex(this, ix);
}
Expand Down Expand Up @@ -10010,7 +10010,7 @@ Module *Module::GetModuleFromIndexIfLoaded(DWORD ix)
NOTHROW;
GC_NOTRIGGER;
MODE_ANY;
PRECONDITION(HasNativeImage());
PRECONDITION(HasNativeOrReadyToRunImage());
POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
}
CONTRACT_END;
Expand Down Expand Up @@ -10050,15 +10050,24 @@ IMDInternalImport *Module::GetNativeAssemblyImport(BOOL loadAllowed)
if (loadAllowed) THROWS; else NOTHROW;
if (loadAllowed) INJECT_FAULT(COMPlusThrowOM()); else FORBID_FAULT;
MODE_ANY;
PRECONDITION(HasNativeImage());
POSTCONDITION(CheckPointer(RETVAL));
PRECONDITION(HasNativeOrReadyToRunImage());
POSTCONDITION(loadAllowed ?
CheckPointer(RETVAL):
CheckPointer(RETVAL, NULL_OK));
}
CONTRACT_END;

RETURN GetFile()->GetPersistentNativeImage()->GetNativeMDImport(loadAllowed);
// Check if image is R2R
if (GetFile()->IsILImageReadyToRun())
{
RETURN GetFile()->GetOpenedILimage()->GetNativeMDImport(loadAllowed);
}
else
{
RETURN GetFile()->GetPersistentNativeImage()->GetNativeMDImport(loadAllowed);
}
}


/*static*/
void Module::RestoreMethodTablePointerRaw(MethodTable ** ppMT,
Module *pContainingModule,
Expand Down
1 change: 1 addition & 0 deletions src/vm/ceeload.h
Original file line number Diff line number Diff line change
Expand Up @@ -2743,6 +2743,7 @@ class Module
BYTE *GetNativeFixupBlobData(RVA fixup);

IMDInternalImport *GetNativeAssemblyImport(BOOL loadAllowed = TRUE);
IMDInternalImport *GetNativeAssemblyImportIfLoaded();

BOOL FixupNativeEntry(CORCOMPILE_IMPORT_SECTION * pSection, SIZE_T fixupIndex, SIZE_T *fixup);

Expand Down
16 changes: 14 additions & 2 deletions src/vm/genericdict.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -686,8 +686,20 @@ Dictionary::PopulateEntry(
pBlob = p.GetPtr();
}

CORCOMPILE_FIXUP_BLOB_KIND signatureKind = (CORCOMPILE_FIXUP_BLOB_KIND)CorSigUncompressData(pBlob);
switch (signatureKind)
BYTE signatureKind = *pBlob++;
if (signatureKind & ENCODE_MODULE_OVERRIDE)
{
DWORD moduleIndex = CorSigUncompressData(pBlob);
Module * pSignatureModule = pModule->GetModuleFromIndex(moduleIndex);
if (pInfoModule == pModule)
{
pInfoModule = pSignatureModule;
}
_ASSERTE(pInfoModule == pSignatureModule);
signatureKind &= ~ENCODE_MODULE_OVERRIDE;
}

switch ((CORCOMPILE_FIXUP_BLOB_KIND) signatureKind)
{
case ENCODE_DECLARINGTYPE_HANDLE: kind = DeclaringTypeHandleSlot; break;
case ENCODE_TYPE_HANDLE: kind = TypeHandleSlot; break;
Expand Down
2 changes: 1 addition & 1 deletion src/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ bool IsInSameVersionBubble(Assembly * current, Assembly * target)
if (current == target)
return true;

return false;
return IsLargeVersionBubbleEnabled();
}

// Returns true if the assemblies defining current and target are in the same version bubble
Expand Down
4 changes: 2 additions & 2 deletions src/vm/peimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ IMDInternalImport* PEImage::GetNativeMDImport(BOOL loadAllowed)
CONTRACTL
{
INSTANCE_CHECK;
PRECONDITION(HasNativeHeader());
PRECONDITION(HasNativeHeader() || HasReadyToRunHeader());
if (loadAllowed) GC_TRIGGERS; else GC_NOTRIGGER;
if (loadAllowed) THROWS; else NOTHROW;
if (loadAllowed) INJECT_FAULT(COMPlusThrowOM()); else FORBID_FAULT;
Expand All @@ -485,7 +485,7 @@ void PEImage::OpenNativeMDImport()
CONTRACTL
{
INSTANCE_CHECK;
PRECONDITION(HasNativeHeader());
PRECONDITION(HasNativeHeader() || HasReadyToRunHeader());
GC_TRIGGERS;
THROWS;
MODE_ANY;
Expand Down
13 changes: 12 additions & 1 deletion src/vm/readytoruninfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,8 @@ ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYT
pamTracker, &m_pPersistentInlineTrackingMap);
}
}
// Fpr format version 2.2 and later, there is an optional profile-data section

// For format version 2.2 and later, there is an optional profile-data section
if (IsImageVersionAtLeast(2, 2))
{
IMAGE_DATA_DIRECTORY * pProfileDataInfoDir = FindSection(READYTORUN_SECTION_PROFILEDATA_INFO);
Expand All @@ -619,6 +620,16 @@ ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYT
pModule->SetMethodProfileList(pMethodProfileList);
}
}

if (IsLargeVersionBubbleEnabled())
{
IMAGE_DATA_DIRECTORY * pManifestMetadata = FindSection(READYTORUN_SECTION_MANIFEST_METADATA);
if (pManifestMetadata != NULL)
{
NativeParser parser = NativeParser(&m_nativeReader, pManifestMetadata->VirtualAddress);
m_pMetaDataHashtable = NativeHashtable(parser);
}
}
}

static bool SigMatchesMethodDesc(MethodDesc* pMD, SigPointer &sig, Module * pModule)
Expand Down
1 change: 1 addition & 0 deletions src/vm/readytoruninfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class ReadyToRunInfo
NativeFormat::NativeArray m_methodDefEntryPoints;
NativeFormat::NativeHashtable m_instMethodEntryPoints;
NativeFormat::NativeHashtable m_availableTypesHashtable;
NativeFormat::NativeHashtable m_pMetaDataHashtable;

Crst m_Crst;
PtrHashMap m_entryPointToMethodDescMap;
Expand Down
1 change: 1 addition & 0 deletions src/vm/vars.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,7 @@ extern CEECompileInfo *g_pCEECompileInfo;

#ifdef FEATURE_READYTORUN_COMPILER
extern bool g_fReadyToRunCompilation;
extern bool g_fLargeVersionBubble;
#endif

// Returns true if this is NGen compilation process.
Expand Down
25 changes: 19 additions & 6 deletions src/vm/zapsig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ Module *ZapSig::DecodeModuleFromIndexIfLoaded(Module *fromModule,
fValidAssemblyRef = FALSE;
}
}

if (fValidAssemblyRef)
{
pAssembly = fromModule->GetAssemblyIfLoaded(
Expand Down Expand Up @@ -803,11 +803,11 @@ TypeHandle ZapSig::DecodeType(Module *pEncodeModuleContext,
TypeHandle th = p.GetTypeHandleThrowing(pInfoModule,
&typeContext,
ClassLoader::LoadTypes,
level,
level,
level < CLASS_LOADED, // For non-full loads, drop a level when loading generic arguments
NULL,
pZapSigContext);

return th;
}

Expand Down Expand Up @@ -1127,7 +1127,11 @@ BOOL ZapSig::EncodeMethod(
TypeHandle ownerType;

#ifdef FEATURE_READYTORUN_COMPILER
if (IsReadyToRunCompilation())

// For methods encoded outside of the version bubble, we use pResolvedToken which describes the metadata token from which the method originated
// For tokens inside the version bubble we are not constrained by the contents of pResolvedToken and as such we skip this codepath
// FUTURE: This condition should likely be changed or reevaluated once support for smaller version bubbles is implemented.
if (IsReadyToRunCompilation() && (!IsLargeVersionBubbleEnabled() || !pMethod->GetModule()->IsInCurrentVersionBubble()))
{
if (pResolvedToken == NULL)
{
Expand Down Expand Up @@ -1186,7 +1190,9 @@ BOOL ZapSig::EncodeMethod(
}

#ifdef FEATURE_READYTORUN_COMPILER
if (IsReadyToRunCompilation())

// FUTURE: This condition should likely be changed or reevaluated once support for smaller version bubbles is implemented.
if (IsReadyToRunCompilation() && (!IsLargeVersionBubbleEnabled() || !pMethod->GetModule()->IsInCurrentVersionBubble()))
{
if (pConstrainedResolvedToken != NULL)
{
Expand All @@ -1202,7 +1208,6 @@ BOOL ZapSig::EncodeMethod(
// GetSvcLogger()->Printf(W("ReadyToRun: Method reference outside of current version bubble cannot be encoded\n"));
ThrowHR(E_FAIL);
}
_ASSERTE(pReferencingModule == GetAppDomain()->ToCompilationDomain()->GetTargetModule());

methodToken = pResolvedToken->token;

Expand Down Expand Up @@ -1312,6 +1317,14 @@ BOOL ZapSig::EncodeMethod(
if (fEncodeUsingResolvedTokenSpecStreams && pResolvedToken != NULL && pResolvedToken->pTypeSpec != NULL)
{
_ASSERTE(pResolvedToken->cbTypeSpec > 0);

if (IsReadyToRunCompilation() && pMethod->GetModule()->IsInCurrentVersionBubble() && pInfoModule != (Module *) pResolvedToken->tokenScope)
{
pSigBuilder->AppendElementType((CorElementType)ELEMENT_TYPE_MODULE_ZAPSIG);
DWORD index = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, (Module *) pResolvedToken->tokenScope);
pSigBuilder->AppendData(index);
}

pSigBuilder->AppendBlob((PVOID)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
}
else
Expand Down
6 changes: 5 additions & 1 deletion src/zap/zapimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1082,7 +1082,7 @@ HANDLE ZapImage::GenerateFile(LPCWSTR wszOutputFileName, CORCOMPILE_NGEN_SIGNATU

HANDLE ZapImage::SaveImage(LPCWSTR wszOutputFileName, LPCWSTR wszDllPath, CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
{
if (!IsReadyToRunCompilation())
if(!IsReadyToRunCompilation() || IsLargeVersionBubbleEnabled())
{
OutputManifestMetadata();
}
Expand Down Expand Up @@ -1835,6 +1835,10 @@ void ZapImage::Compile()
OutputTypesTableForReadyToRun(m_pMDImport);
OutputInliningTableForReadyToRun();
OutputProfileDataForReadyToRun();
if (IsLargeVersionBubbleEnabled())
{
OutputManifestMetadataForReadyToRun();
}
}
else
#endif
Expand Down
2 changes: 2 additions & 0 deletions src/zap/zapimage.h
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,7 @@ class ZapImage
void OutputTypesTableForReadyToRun(IMDInternalImport * pMDImport);
void OutputInliningTableForReadyToRun();
void OutputProfileDataForReadyToRun();
void OutputManifestMetadataForReadyToRun();

void CopyDebugDirEntry();
void CopyWin32VersionResource();
Expand Down Expand Up @@ -691,6 +692,7 @@ class ZapImage
}

static void __stdcall TryCompileMethodStub(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, CORJIT_FLAGS jitFlags);
static DWORD EncodeModuleHelper(LPVOID compileContext, CORINFO_MODULE_HANDLE referencedModule);

BOOL IsVTableGapMethod(mdMethodDef md);

Expand Down
Loading