diff --git a/src/coreclr/src/inc/corinfo.h b/src/coreclr/src/inc/corinfo.h index 2c8c1260b73925..159b8ad92a6401 100644 --- a/src/coreclr/src/inc/corinfo.h +++ b/src/coreclr/src/inc/corinfo.h @@ -822,7 +822,7 @@ enum CorInfoFlag CORINFO_FLG_ARRAY = 0x00080000, // class is an array class (initialized differently) CORINFO_FLG_OVERLAPPING_FIELDS = 0x00100000, // struct or class has fields that overlap (aka union) CORINFO_FLG_INTERFACE = 0x00200000, // it is an interface - // unused = 0x00400000, + CORINFO_FLG_DONT_PROMOTE = 0x00400000, // don't try to promote fields (used for types outside of AOT compilation version bubble) CORINFO_FLG_CUSTOMLAYOUT = 0x00800000, // does this struct have custom layout? CORINFO_FLG_CONTAINS_GC_PTR = 0x01000000, // does the class contain a gc ptr ? CORINFO_FLG_DELEGATE = 0x02000000, // is this a subclass of delegate or multicast delegate ? diff --git a/src/coreclr/src/jit/compiler.hpp b/src/coreclr/src/jit/compiler.hpp index f3e590a7303a45..4dc68abbc476a9 100644 --- a/src/coreclr/src/jit/compiler.hpp +++ b/src/coreclr/src/jit/compiler.hpp @@ -4670,6 +4670,11 @@ inline static bool StructHasCustomLayout(DWORD attribs) return ((attribs & CORINFO_FLG_CUSTOMLAYOUT) != 0); } +inline static bool StructHasNoPromotionFlagSet(DWORD attribs) +{ + return ((attribs & CORINFO_FLG_DONT_PROMOTE) != 0); +} + /***************************************************************************** * This node should not be referenced by anyone now. Set its values to garbage * to catch extra references diff --git a/src/coreclr/src/jit/lclvars.cpp b/src/coreclr/src/jit/lclvars.cpp index 608b4410cd9421..4788b6c84a6c76 100644 --- a/src/coreclr/src/jit/lclvars.cpp +++ b/src/coreclr/src/jit/lclvars.cpp @@ -1686,6 +1686,13 @@ bool Compiler::StructPromotionHelper::CanPromoteStructType(CORINFO_CLASS_HANDLE structPromotionInfo.fieldCnt = (unsigned char)fieldCnt; DWORD typeFlags = compHandle->getClassAttribs(typeHnd); + if (StructHasNoPromotionFlagSet(typeFlags)) + { + // In AOT ReadyToRun compilation, don't try to promote fields of types + // outside of the current version bubble. + return false; + } + bool overlappingFields = StructHasOverlappingFields(typeFlags); if (overlappingFields) { diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs index 205304c49a36b9..fef6e6e5eb5ed7 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs @@ -1070,7 +1070,7 @@ private void resolveToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken) #if READYTORUN TypeDesc owningType = methodIL.OwningMethod.GetTypicalMethodDefinition().OwningType; - bool recordToken = _compilation.NodeFactory.CompilationModuleGroup.VersionsWithType(owningType) && owningType is EcmaType; + bool recordToken = _compilation.CompilationModuleGroup.VersionsWithType(owningType) && owningType is EcmaType; #endif if (result is MethodDesc) @@ -1220,7 +1220,9 @@ private CorInfoType asCorInfoType(CORINFO_CLASS_STRUCT_* cls) private byte* getClassName(CORINFO_CLASS_STRUCT_* cls) { var type = HandleToObject(cls); - return (byte*)GetPin(StringToUTF8(type.ToString())); + StringBuilder nameBuilder = new StringBuilder(); + TypeString.Instance.AppendName(nameBuilder, type); + return (byte*)GetPin(StringToUTF8(nameBuilder.ToString())); } private byte* getClassNameFromMetadata(CORINFO_CLASS_STRUCT_* cls, byte** namespaceName) @@ -1357,6 +1359,15 @@ private uint getClassAttribsInternal(TypeDesc type) result |= CorInfoFlag.CORINFO_FLG_ABSTRACT; } +#if READYTORUN + if (!_compilation.CompilationModuleGroup.VersionsWithType(type)) + { + // Prevent the JIT from drilling into types outside of the current versioning bubble + result |= CorInfoFlag.CORINFO_FLG_DONT_PROMOTE; + result &= ~CorInfoFlag.CORINFO_FLG_BEFOREFIELDINIT; + } +#endif + return (uint)result; } diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs index 990c2713de72c9..2313d5e58b7a00 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs @@ -634,7 +634,7 @@ public enum CorInfoFlag : uint CORINFO_FLG_ARRAY = 0x00080000, // class is an array class (initialized differently) CORINFO_FLG_OVERLAPPING_FIELDS = 0x00100000, // struct or class has fields that overlap (aka union) CORINFO_FLG_INTERFACE = 0x00200000, // it is an interface - // CORINFO_FLG_UNUSED = 0x00400000, + CORINFO_FLG_DONT_PROMOTE = 0x00400000, // don't try to promote fieds of types outside of AOT compilation version bubble CORINFO_FLG_CUSTOMLAYOUT = 0x00800000, // does this struct have custom layout? CORINFO_FLG_CONTAINS_GC_PTR = 0x01000000, // does the class contain a gc ptr ? CORINFO_FLG_DELEGATE = 0x02000000, // is this a subclass of delegate or multicast delegate ?