summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/utilcode/pedecoder.cpp16
-rw-r--r--src/vm/ceeload.cpp61
-rw-r--r--src/vm/ceeload.h5
-rw-r--r--src/vm/methodtablebuilder.cpp32
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;
}