diff options
-rw-r--r-- | src/utilcode/pedecoder.cpp | 16 | ||||
-rw-r--r-- | src/vm/ceeload.cpp | 61 | ||||
-rw-r--r-- | src/vm/ceeload.h | 5 | ||||
-rw-r--r-- | src/vm/methodtablebuilder.cpp | 32 |
4 files changed, 107 insertions, 7 deletions
diff --git a/src/utilcode/pedecoder.cpp b/src/utilcode/pedecoder.cpp index a3e3b7367f..47f1574f15 100644 --- a/src/utilcode/pedecoder.cpp +++ b/src/utilcode/pedecoder.cpp @@ -2839,7 +2839,7 @@ PTR_CVOID PEDecoder::GetNativeManifestMetadata(COUNT_T *pSize) const } CONTRACT_END; - IMAGE_DATA_DIRECTORY *pDir; + IMAGE_DATA_DIRECTORY *pDir = NULL; #ifdef FEATURE_PREJIT if (!HasReadyToRunHeader()) { @@ -2858,8 +2858,22 @@ PTR_CVOID PEDecoder::GetNativeManifestMetadata(COUNT_T *pSize) const 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; + break; + } + } + + // ReadyToRun file without large version bubble support doesn't have the READYTORUN_SECTION_MANIFEST_METADATA + if (pDir == NULL) + { + if (pSize != NULL) + { + *pSize = 0; + } + + RETURN NULL; } } diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp index 423537614b..49d5fb58b4 100644 --- a/src/vm/ceeload.cpp +++ b/src/vm/ceeload.cpp @@ -3406,6 +3406,67 @@ BOOL Module::IsInCurrentVersionBubble() #endif // FEATURE_NATIVE_IMAGE_GENERATION } +#if defined(FEATURE_READYTORUN) && !defined(FEATURE_READYTORUN_COMPILER) +//--------------------------------------------------------------------------------------- +// Check if the target module is in the same version bubble as this one +// The current implementation uses the presence of an AssemblyRef for the target module's assembly in +// the native manifest metadata. +// +// Arguments: +// * target - target module to check +// +// Return Value: +// TRUE if the target module is in the same version bubble as this one +// +BOOL Module::IsInSameVersionBubble(Module *target) +{ + CONTRACT(BOOL) + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + } + CONTRACT_END; + + if (this == target) + { + RETURN TRUE; + } + + if (!HasNativeOrReadyToRunImage()) + { + RETURN FALSE; + } + + // Check if the current module's image has native manifest metadata, otherwise the current->GetNativeAssemblyImport() asserts. + COUNT_T cMeta=0; + const void* pMeta = GetFile()->GetOpenedILimage()->GetNativeManifestMetadata(&cMeta); + if (pMeta == NULL) + { + RETURN FALSE; + } + + IMDInternalImport* pMdImport = GetNativeAssemblyImport(); + + LPCUTF8 targetName = target->GetAssembly()->GetSimpleName(); + + HENUMInternal assemblyEnum; + HRESULT hr = pMdImport->EnumAllInit(mdtAssemblyRef, &assemblyEnum); + mdAssemblyRef assemblyRef; + while (pMdImport->EnumNext(&assemblyEnum, &assemblyRef)) + { + LPCSTR assemblyName; + hr = pMdImport->GetAssemblyRefProps(assemblyRef, NULL, NULL, &assemblyName, NULL, NULL, NULL, NULL); + if (strcmp(assemblyName, targetName) == 0) + { + RETURN TRUE; + } + } + + RETURN FALSE; +} +#endif // FEATURE_READYTORUN && !FEATURE_READYTORUN_COMPILER + //--------------------------------------------------------------------------------------- // // WinMD-aware helper to grab a readable public metadata interface. Any place that thinks diff --git a/src/vm/ceeload.h b/src/vm/ceeload.h index 5cffacd9a8..b602ac6e6d 100644 --- a/src/vm/ceeload.h +++ b/src/vm/ceeload.h @@ -1952,6 +1952,11 @@ protected: BOOL IsInCurrentVersionBubble(); +#if defined(FEATURE_READYTORUN) && !defined(FEATURE_READYTORUN_COMPILER) + BOOL IsInSameVersionBubble(Module *target); +#endif // FEATURE_READYTORUN && !FEATURE_READYTORUN_COMPILER + + LPCWSTR GetPathForErrorMessages(); diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp index 31c4b0a5ee..2a59be4f33 100644 --- a/src/vm/methodtablebuilder.cpp +++ b/src/vm/methodtablebuilder.cpp @@ -11302,6 +11302,12 @@ BOOL MethodTableBuilder::NeedsAlignedBaseOffset() if (IsValueClass()) return FALSE; + MethodTable * pParentMT = GetParentMethodTable(); + + // Trivial parents + if (pParentMT == NULL || pParentMT == g_pObjectClass) + return FALSE; + // Always use the ReadyToRun field layout algorithm if the source IL image was ReadyToRun, independent on // whether ReadyToRun is actually enabled for the module. It is required to allow mixing and matching // ReadyToRun images with NGen. @@ -11312,17 +11318,31 @@ BOOL MethodTableBuilder::NeedsAlignedBaseOffset() return FALSE; } - MethodTable * pParentMT = GetParentMethodTable(); - - // Trivial parents - if (pParentMT == NULL || pParentMT == g_pObjectClass) - return FALSE; - if (pParentMT->GetModule() == GetModule()) { if (!pParentMT->GetClass()->HasLayoutDependsOnOtherModules()) return FALSE; } + else + { +#ifdef FEATURE_READYTORUN_COMPILER + if (IsReadyToRunCompilation()) + { + if (pParentMT->GetModule()->IsInCurrentVersionBubble()) + { + return FALSE; + } + } +#else // FEATURE_READYTORUN_COMPILER + if (GetModule()->GetFile()->IsILImageReadyToRun()) + { + if (GetModule()->IsInSameVersionBubble(pParentMT->GetModule())) + { + return FALSE; + } + } +#endif // FEATURE_READYTORUN_COMPILER + } return TRUE; } |