From 0d96a4d89c9182c9a97d083c370050050707628c Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 29 Apr 2023 20:57:21 +0200 Subject: [PATCH 01/20] Allocate empty arrays on frozen segments --- .../src/System/GC.CoreCLR.cs | 12 +++ src/coreclr/vm/comutilnative.cpp | 18 +++++ src/coreclr/vm/comutilnative.h | 1 + src/coreclr/vm/ecalllist.h | 1 + src/coreclr/vm/gchelpers.cpp | 79 +++++++++++++++++++ src/coreclr/vm/gchelpers.h | 3 + src/coreclr/vm/jitinterface.cpp | 22 ++++-- src/coreclr/vm/object.h | 1 + .../src/System/Array.cs | 6 ++ 9 files changed, 137 insertions(+), 6 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs index 3bd17b2e1bc19..219418f6fa1d8 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs @@ -104,6 +104,9 @@ internal enum GC_ALLOC_FLAGS [MethodImpl(MethodImplOptions.InternalCall)] internal static extern Array AllocateNewArray(IntPtr typeHandle, int length, GC_ALLOC_FLAGS flags); + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern Array AllocateFrozenArray(IntPtr typeHandle, int length); + [MethodImpl(MethodImplOptions.InternalCall)] private static extern int GetGenerationWR(IntPtr handle); @@ -709,6 +712,15 @@ public static T[] AllocateArray(int length, bool pinned = false) // T[] rathe return Unsafe.As(AllocateNewArray(typeof(T[]).TypeHandle.Value, length, flags)); } + /// + /// Allocate an array with a "prefer frozen segments" hint. If VM can't allocate it on a frozen segment, + /// it will fallback to a normal heap allocation. + /// + internal static T[] AllocateFrozenArray(int length) + { + return Unsafe.As(AllocateFrozenArray(typeof(T[]).TypeHandle.Value, length)); + } + [MethodImpl(MethodImplOptions.InternalCall)] private static extern long _GetTotalPauseDuration(); diff --git a/src/coreclr/vm/comutilnative.cpp b/src/coreclr/vm/comutilnative.cpp index 488655ee7a62c..fbf7ae8e79f84 100644 --- a/src/coreclr/vm/comutilnative.cpp +++ b/src/coreclr/vm/comutilnative.cpp @@ -976,6 +976,24 @@ FCIMPL3(Object*, GCInterface::AllocateNewArray, void* arrayTypeHandle, INT32 len } FCIMPLEND +FCIMPL2(Object*, GCInterface::AllocateFrozenArray, void* arrayTypeHandle, INT32 length) +{ + CONTRACTL { + FCALL_CHECK; + } CONTRACTL_END; + + OBJECTREF pRet = NULL; + TypeHandle arrayType = TypeHandle::FromPtr(arrayTypeHandle); + + HELPER_METHOD_FRAME_BEGIN_RET_0(); + + pRet = AllocateFrozenSzArray(arrayType.AsMethodTable(), length); + + HELPER_METHOD_FRAME_END(); + + return OBJECTREFToObject(pRet); +} +FCIMPLEND FCIMPL1(INT64, GCInterface::GetTotalAllocatedBytes, CLR_BOOL precise) { diff --git a/src/coreclr/vm/comutilnative.h b/src/coreclr/vm/comutilnative.h index 496c4747b0b39..bf61a1cc0c20a 100644 --- a/src/coreclr/vm/comutilnative.h +++ b/src/coreclr/vm/comutilnative.h @@ -178,6 +178,7 @@ class GCInterface { static FCDECL1(INT64, GetTotalAllocatedBytes, CLR_BOOL precise); static FCDECL3(Object*, AllocateNewArray, void* elementTypeHandle, INT32 length, INT32 flags); + static FCDECL2(Object*, AllocateFrozenArray, void* elementTypeHandle, INT32 length); NOINLINE static void SendEtwRemoveMemoryPressureEvent(UINT64 bytesAllocated); static void SendEtwAddMemoryPressureEvent(UINT64 bytesAllocated); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index acda36bace331..d50c1cac44380 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -457,6 +457,7 @@ FCFuncStart(gGCInterfaceFuncs) FCFuncElement("GetTotalAllocatedBytes", GCInterface::GetTotalAllocatedBytes) FCFuncElement("AllocateNewArray", GCInterface::AllocateNewArray) + FCFuncElement("AllocateFrozenArray", GCInterface::AllocateFrozenArray) FCFuncEnd() FCFuncStart(gGCSettingsFuncs) diff --git a/src/coreclr/vm/gchelpers.cpp b/src/coreclr/vm/gchelpers.cpp index cccf11914aad2..69173149eeea9 100644 --- a/src/coreclr/vm/gchelpers.cpp +++ b/src/coreclr/vm/gchelpers.cpp @@ -493,6 +493,85 @@ OBJECTREF AllocateSzArray(MethodTable* pArrayMT, INT32 cElements, GC_ALLOC_FLAGS return ObjectToOBJECTREF((Object*)orArray); } +// Same as AllocateSzArray but attempts to allocate the array on a frozen segment. +// It fallbacks to AllocateSzArray if it fails to allocate on a frozen segment. +OBJECTREF AllocateFrozenSzArray(MethodTable* pArrayMT, INT32 cElements) +{ + CONTRACTL{ + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } CONTRACTL_END; + + SetTypeHandleOnThreadForAlloc(TypeHandle(pArrayMT)); + + _ASSERTE(pArrayMT->CheckInstanceActivated()); + _ASSERTE(pArrayMT->GetInternalCorElementType() == ELEMENT_TYPE_SZARRAY); + + // The initial validation is copied from AllocateSzArray impl + + CorElementType elemType = pArrayMT->GetArrayElementType(); + + if (pArrayMT->ContainsPointers() && cElements > 0) + { + // For arrays with GC pointers we can only work with empty arrays + return AllocateSzArray(pArrayMT, cElements); + } + + // Disallow the creation of void[] (an array of System.Void) + if (elemType == ELEMENT_TYPE_VOID) + COMPlusThrow(kArgumentException); + + if (cElements < 0) + COMPlusThrow(kOverflowException); + + if ((SIZE_T)cElements > MaxArrayLength()) + ThrowOutOfMemoryDimensionsExceeded(); + + SIZE_T componentSize = pArrayMT->GetComponentSize(); +#ifdef TARGET_64BIT + // POSITIVE_INT32 * UINT16 + SMALL_CONST + // this cannot overflow on 64bit + size_t totalSize = cElements * componentSize + pArrayMT->GetBaseSize(); + +#else + S_SIZE_T safeTotalSize = S_SIZE_T((DWORD)cElements) * S_SIZE_T((DWORD)componentSize) + S_SIZE_T((DWORD)pArrayMT->GetBaseSize()); + if (safeTotalSize.IsOverflow()) + ThrowOutOfMemoryDimensionsExceeded(); + + size_t totalSize = safeTotalSize.Value(); +#endif + + // FrozenObjectHeapManager doesn't yet support objects with a custom alignment, + // so we give up on arrays of value types requiring 8 byte alignment on 32bit platforms. + if ((DATA_ALIGNMENT < sizeof(double)) && (elemType == ELEMENT_TYPE_R8)) + { + return AllocateSzArray(pArrayMT, cElements); + } +#ifdef FEATURE_64BIT_ALIGNMENT + MethodTable* pElementMT = pArrayMT->GetArrayElementTypeHandle().GetMethodTable(); + if (pElementMT->RequiresAlign8() && pElementMT->IsValueType()) + { + return AllocateSzArray(pArrayMT, cElements); + } +#endif + + FrozenObjectHeapManager* foh = SystemDomain::GetFrozenObjectHeapManager(); + ArrayBase* orArray = static_cast(foh->TryAllocateObject(pArrayMT, totalSize, /*publish*/ false)); + if (orArray == nullptr) + { + // We failed to allocate on a frozen segment, fallback to AllocateSzArray + // E.g. if the array is too big to fit on a frozen segment + return AllocateSzArray(pArrayMT, cElements); + } + orArray->m_NumComponents = cElements; + + // Publish needs to be postponed in this case because we need to specify array length + PublishObjectAndNotify(orArray, GC_ALLOC_NO_FLAGS); + + return ObjectToOBJECTREF(orArray); +} + void ThrowOutOfMemoryDimensionsExceeded() { CONTRACTL { diff --git a/src/coreclr/vm/gchelpers.h b/src/coreclr/vm/gchelpers.h index 3a0382f6f6bb6..967aec987aeb0 100644 --- a/src/coreclr/vm/gchelpers.h +++ b/src/coreclr/vm/gchelpers.h @@ -23,6 +23,9 @@ OBJECTREF AllocateSzArray(MethodTable *pArrayMT, INT32 length, GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS); OBJECTREF AllocateSzArray(TypeHandle arrayType, INT32 length, GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS); +// Allocate single-dimensional array with a hint to prefer frozen segments +OBJECTREF AllocateFrozenSzArray(MethodTable* pArrayMT, INT32 length); + // The main Array allocation routine, can do multi-dimensional OBJECTREF AllocateArrayEx(MethodTable *pArrayMT, INT32 *pArgs, DWORD dwNumArgs, GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS); OBJECTREF AllocateArrayEx(TypeHandle arrayType, INT32 *pArgs, DWORD dwNumArgs, GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS); diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 30ba16e9770ea..6e07254e7f5c6 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -747,7 +747,7 @@ size_t CEEInfo::printObjectDescription ( } else { - _ASSERTE(!"Unexpected object type"); + obj->GetMethodTable()->_GetFullyQualifiedNameForClass(stackStr); } const UTF8* utf8data = stackStr.GetUTF8(); @@ -6157,20 +6157,30 @@ bool CEEInfo::isObjectImmutable(CORINFO_OBJECT_HANDLE objHandle) _ASSERT(objHandle != NULL); -#ifdef DEBUG + bool isImmutable = false; + JIT_TO_EE_TRANSITION(); GCX_COOP(); OBJECTREF obj = getObjectFromJitHandle(objHandle); MethodTable* type = obj->GetMethodTable(); - _ASSERTE(type->IsString() || type == g_pRuntimeTypeClass); + if (type->IsString() || type == g_pRuntimeTypeClass) + { + // These types are always immutable + isImmutable = true; + } + else if (type->IsArray() && ((ArrayBase*)OBJECTREFToObject(obj))->GetComponentSize() == 0) + { + // Empty arrays are always immutable + isImmutable = true; + } + // delegates and types with no instance fields are also immutable but we never allocate + // them on frozen segments (yet). EE_TO_JIT_TRANSITION(); -#endif - // All currently allocated frozen objects can be treated as immutable - return true; + return isImmutable; } /***********************************************************************/ diff --git a/src/coreclr/vm/object.h b/src/coreclr/vm/object.h index d608fe0493a55..5399b005cbdee 100644 --- a/src/coreclr/vm/object.h +++ b/src/coreclr/vm/object.h @@ -522,6 +522,7 @@ class ArrayBase : public Object friend class CObjectHeader; friend class Object; friend OBJECTREF AllocateSzArray(MethodTable *pArrayMT, INT32 length, GC_ALLOC_FLAGS flags); + friend OBJECTREF AllocateFrozenSzArray(MethodTable* pArrayMT, INT32 length); friend OBJECTREF AllocateArrayEx(MethodTable *pArrayMT, INT32 *pArgs, DWORD dwNumArgs, GC_ALLOC_FLAGS flags); friend FCDECL2(Object*, JIT_NewArr1VC_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size); friend FCDECL2(Object*, JIT_NewArr1OBJ_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size); diff --git a/src/libraries/System.Private.CoreLib/src/System/Array.cs b/src/libraries/System.Private.CoreLib/src/System/Array.cs index 78ca760bcd620..07d15111246ef 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Array.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Array.cs @@ -947,7 +947,13 @@ public void CopyTo(Array array, long index) private static class EmptyArray { #pragma warning disable CA1825 // this is the implementation of Array.Empty() +#if CORECLR + internal static readonly T[] Value = GC.AllocateFrozenArray(0); +#else + // NativeAOT will preallocate this field on a frozen segment as is. + // Mono doesn't support frozen heaps internal static readonly T[] Value = new T[0]; +#endif #pragma warning restore CA1825 } From b00a31ed7c039ec3dd56bb92d8066776178c4d9e Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 29 Apr 2023 21:15:17 +0200 Subject: [PATCH 02/20] ignore arrays of collectible types --- src/coreclr/vm/gchelpers.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/coreclr/vm/gchelpers.cpp b/src/coreclr/vm/gchelpers.cpp index 69173149eeea9..e4c704ca9d014 100644 --- a/src/coreclr/vm/gchelpers.cpp +++ b/src/coreclr/vm/gchelpers.cpp @@ -518,6 +518,12 @@ OBJECTREF AllocateFrozenSzArray(MethodTable* pArrayMT, INT32 cElements) return AllocateSzArray(pArrayMT, cElements); } + if (pArrayMT->Collectible()) + { + // Ignore arrays of collectible types + return AllocateSzArray(pArrayMT, cElements); + } + // Disallow the creation of void[] (an array of System.Void) if (elemType == ELEMENT_TYPE_VOID) COMPlusThrow(kArgumentException); From 326e743e8e5464500ac6ca8a0dc90f372d46fcef Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Apr 2023 00:14:24 +0200 Subject: [PATCH 03/20] Rewrite to JIT side --- .../src/System/GC.CoreCLR.cs | 12 ----- src/coreclr/inc/corinfo.h | 1 + src/coreclr/inc/corjitflags.h | 2 +- src/coreclr/inc/jiteeversionguid.h | 10 ++-- src/coreclr/inc/jithelpers.h | 1 + src/coreclr/jit/gentree.cpp | 2 + src/coreclr/jit/importer.cpp | 51 +++++++++++++++++-- src/coreclr/jit/importercalls.cpp | 1 + src/coreclr/jit/jitee.h | 3 +- src/coreclr/jit/utils.cpp | 1 + src/coreclr/jit/valuenum.cpp | 1 + .../Common/JitInterface/CorInfoHelpFunc.cs | 1 + .../tools/Common/JitInterface/CorInfoTypes.cs | 1 + .../superpmi-shared/methodcontext.cpp | 2 + src/coreclr/vm/comutilnative.cpp | 19 ------- src/coreclr/vm/comutilnative.h | 1 - src/coreclr/vm/ecalllist.h | 1 - src/coreclr/vm/jithelpers.cpp | 40 +++++++++++++++ src/coreclr/vm/jitinterface.cpp | 6 +++ .../src/System/Array.cs | 6 --- 20 files changed, 112 insertions(+), 50 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs index 219418f6fa1d8..3bd17b2e1bc19 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs @@ -104,9 +104,6 @@ internal enum GC_ALLOC_FLAGS [MethodImpl(MethodImplOptions.InternalCall)] internal static extern Array AllocateNewArray(IntPtr typeHandle, int length, GC_ALLOC_FLAGS flags); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern Array AllocateFrozenArray(IntPtr typeHandle, int length); - [MethodImpl(MethodImplOptions.InternalCall)] private static extern int GetGenerationWR(IntPtr handle); @@ -712,15 +709,6 @@ public static T[] AllocateArray(int length, bool pinned = false) // T[] rathe return Unsafe.As(AllocateNewArray(typeof(T[]).TypeHandle.Value, length, flags)); } - /// - /// Allocate an array with a "prefer frozen segments" hint. If VM can't allocate it on a frozen segment, - /// it will fallback to a normal heap allocation. - /// - internal static T[] AllocateFrozenArray(int length) - { - return Unsafe.As(AllocateFrozenArray(typeof(T[]).TypeHandle.Value, length)); - } - [MethodImpl(MethodImplOptions.InternalCall)] private static extern long _GetTotalPauseDuration(); diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 4e80bb79ca8b9..8334d11df9751 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -412,6 +412,7 @@ enum CorInfoHelpFunc CORINFO_HELP_NEW_MDARR,// multi-dim array helper for arrays Rank != 1 (with or without lower bounds - dimensions passed in as unmanaged array) CORINFO_HELP_NEW_MDARR_RARE,// rare multi-dim array helper (Rank == 1) CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creation + CORINFO_HELP_NEWARR_1_FROZEN, // helper for any one dimensional array creation on a frozen segment CORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arrays CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays CORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array start diff --git a/src/coreclr/inc/corjitflags.h b/src/coreclr/inc/corjitflags.h index c90753bb4d55c..d9fffdbb97a22 100644 --- a/src/coreclr/inc/corjitflags.h +++ b/src/coreclr/inc/corjitflags.h @@ -55,7 +55,7 @@ class CORJIT_FLAGS CORJIT_FLAG_OSR = 13, // Generate alternate method for On Stack Replacement CORJIT_FLAG_ALT_JIT = 14, // JIT should consider itself an ALT_JIT - CORJIT_FLAG_UNUSED8 = 15, + CORJIT_FLAG_FROZEN_ALLOC_ALLOWED = 15, // JIT is allowed to use *_FROZEN allocators CORJIT_FLAG_UNUSED9 = 16, CORJIT_FLAG_UNUSED10 = 17, diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index be6cc1e7f4f8d..d539e04c6b168 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -43,11 +43,11 @@ typedef const GUID *LPCGUID; #define GUID_DEFINED #endif // !GUID_DEFINED -constexpr GUID JITEEVersionIdentifier = { /* 387bcec3-9a71-4422-a11c-e7ce3b73c592 */ - 0x387bcec3, - 0x9a71, - 0x4422, - {0xa1, 0x1c, 0xe7, 0xce, 0x3b, 0x73, 0xc5, 0x92} +constexpr GUID JITEEVersionIdentifier = { /* 4e6355a0-3844-45e2-8cef-082c18217e14 */ + 0x4e6355a0, + 0x3844, + 0x45e2, + {0x8c, 0xef, 0x8, 0x2c, 0x18, 0x21, 0x7e, 0x14} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index 30f8fe38ae450..36b58e63b2799 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -78,6 +78,7 @@ JITHELPER(CORINFO_HELP_NEW_MDARR, JIT_NewMDArr,CORINFO_HELP_SIG_4_STACK) JITHELPER(CORINFO_HELP_NEW_MDARR_RARE, JIT_NewMDArr,CORINFO_HELP_SIG_4_STACK) JITHELPER(CORINFO_HELP_NEWARR_1_DIRECT, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY) + JITHELPER(CORINFO_HELP_NEWARR_1_FROZEN, JIT_NewArr1Frozen,CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_OBJ, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_VC, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_ALIGN8, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 8bb778f9d326e..ab71c1472fd2f 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -2158,6 +2158,7 @@ GenTree* Compiler::getArrayLengthFromAllocation(GenTree* tree DEBUGARG(BasicBloc switch (eeGetHelperNum(call->gtCallMethHnd)) { case CORINFO_HELP_NEWARR_1_DIRECT: + case CORINFO_HELP_NEWARR_1_FROZEN: case CORINFO_HELP_NEWARR_1_OBJ: case CORINFO_HELP_NEWARR_1_VC: case CORINFO_HELP_NEWARR_1_ALIGN8: @@ -18300,6 +18301,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetHelperCallClassHandle(GenTreeCall* call, boo } case CORINFO_HELP_NEWARR_1_DIRECT: + case CORINFO_HELP_NEWARR_1_FROZEN: case CORINFO_HELP_NEWARR_1_OBJ: case CORINFO_HELP_NEWARR_1_VC: case CORINFO_HELP_NEWARR_1_ALIGN8: diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index b8e9bfde05453..325b7e7c6708b 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -9779,7 +9779,6 @@ void Compiler::impImportBlockCode(BasicBlock* block) case CEE_NEWARR: { - /* Get the class type index operand */ _impResolveToken(CORINFO_TOKENKIND_Newarr); @@ -9810,10 +9809,13 @@ void Compiler::impImportBlockCode(BasicBlock* block) // So if we have an int, explicitly extend it to be a native int. op2 = impImplicitIorI4Cast(op2, TYP_I_IMPL); + CorInfoHelpFunc helper = CORINFO_HELP_UNDEF; + #ifdef FEATURE_READYTORUN if (opts.IsReadyToRun()) { - op1 = impReadyToRunHelperToTree(&resolvedToken, CORINFO_HELP_READYTORUN_NEWARR_1, TYP_REF, nullptr, + helper = CORINFO_HELP_READYTORUN_NEWARR_1; + op1 = impReadyToRunHelperToTree(&resolvedToken, helper, TYP_REF, nullptr, op2); usingReadyToRunHelper = (op1 != nullptr); @@ -9839,11 +9841,52 @@ void Compiler::impImportBlockCode(BasicBlock* block) #endif { /* Create a call to 'new' */ + helper = info.compCompHnd->getNewArrHelper(resolvedToken.hClass); // Note that this only works for shared generic code because the same helper is used for all // reference array types - op1 = - gtNewHelperCallNode(info.compCompHnd->getNewArrHelper(resolvedToken.hClass), TYP_REF, op1, op2); + op1 = gtNewHelperCallNode(helper, TYP_REF, op1, op2); + } + + // If we're jitting a static constructor and detect the following code pattern: + // + // newarr + // stsfld + // ret + // + // We replace default heap allocator for newarr with the one that prefers frozen segments. + // This is a very simple and conservative implementation targeting Array.Empty(), ideally + // we want to be able to use frozen allocators more broadly, but that analysis is not trivial. + // + if (((info.compFlags & FLG_CCTOR) == FLG_CCTOR) && + // Does VM allow us to use frozen allocators? (e.g. are we in a non-collectible assembly) + opts.jitFlags->IsSet(JitFlags::JIT_FLAG_FROZEN_ALLOC_ALLOWED)) + { + // Check next two opcodes + const BYTE* nextOpcode1 = codeAddr + sizeof(mdToken); + const BYTE* nextOpcode2 = nextOpcode1 + sizeof(mdToken) + 1; + if (nextOpcode2 <= codeEndp && getU1LittleEndian(nextOpcode1) == CEE_STSFLD) + { + if (getU1LittleEndian(nextOpcode2) == CEE_RET) + { + // TODO in this PR: R2R + if (helper == CORINFO_HELP_NEWARR_1_OBJ || + helper == CORINFO_HELP_NEWARR_1_VC) + { + // Check that the field is "static readonly" + CORINFO_RESOLVED_TOKEN fldToken; + impResolveToken(nextOpcode1 + 1, &fldToken, CORINFO_TOKENKIND_Field); + CORINFO_FIELD_INFO fi; + eeGetFieldInfo(&fldToken, CORINFO_ACCESS_SET, &fi); + unsigned flagsToCheck = CORINFO_FLG_FIELD_STATIC | CORINFO_FLG_FIELD_FINAL; + if ((fi.fieldFlags & flagsToCheck) == flagsToCheck) + { + // Replace the helper with the frozen version + op1->AsCall()->gtCallMethHnd = eeFindHelper(CORINFO_HELP_NEWARR_1_FROZEN); + } + } + } + } } op1->AsCall()->compileTimeHelperArgumentHandle = (CORINFO_GENERIC_HANDLE)resolvedToken.hClass; diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 1cd5cc5dd18ff..e6b838a485299 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -1872,6 +1872,7 @@ GenTree* Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig) bool isMDArray = false; if (newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_DIRECT) && + newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_FROZEN) && newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_OBJ) && newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_VC) && newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_ALIGN8) diff --git a/src/coreclr/jit/jitee.h b/src/coreclr/jit/jitee.h index 7d3b4f6a624b4..6088afaf8fa85 100644 --- a/src/coreclr/jit/jitee.h +++ b/src/coreclr/jit/jitee.h @@ -40,7 +40,7 @@ class JitFlags JIT_FLAG_OSR = 13, // Generate alternate version for On Stack Replacement JIT_FLAG_ALT_JIT = 14, // JIT should consider itself an ALT_JIT - JIT_FLAG_UNUSED8 = 15, + JIT_FLAG_FROZEN_ALLOC_ALLOWED = 15, // JIT is allowed to use *_FROZEN allocators JIT_FLAG_UNUSED9 = 16, #if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) @@ -187,6 +187,7 @@ class JitFlags #endif FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT, JIT_FLAG_ALT_JIT); + FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_FROZEN_ALLOC_ALLOWED, JIT_FLAG_FROZEN_ALLOC_ALLOWED); FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE, JIT_FLAG_MAKEFINALCODE); FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_READYTORUN, JIT_FLAG_READYTORUN); FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE, JIT_FLAG_PROF_ENTERLEAVE); diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index 5dcb315af0a35..db784abb8f06b 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -1335,6 +1335,7 @@ void HelperCallProperties::init() case CORINFO_HELP_NEW_MDARR: case CORINFO_HELP_NEW_MDARR_RARE: case CORINFO_HELP_NEWARR_1_DIRECT: + case CORINFO_HELP_NEWARR_1_FROZEN: case CORINFO_HELP_NEWARR_1_OBJ: case CORINFO_HELP_READYTORUN_NEWARR_1: diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 28d8e85abaa73..51a497663a8eb 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -12172,6 +12172,7 @@ VNFunc Compiler::fgValueNumberJitHelperMethodVNFunc(CorInfoHelpFunc helpFunc) break; case CORINFO_HELP_NEWARR_1_DIRECT: + case CORINFO_HELP_NEWARR_1_FROZEN: case CORINFO_HELP_NEWARR_1_OBJ: case CORINFO_HELP_NEWARR_1_VC: case CORINFO_HELP_NEWARR_1_ALIGN8: diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs index 2c7ba7aec14e9..7c456180bbb2e 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs @@ -55,6 +55,7 @@ which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_NEW_MDARR, // multi-dim array helper for arrays Rank != 1 (with or without lower bounds - dimensions passed in as unmanaged array) CORINFO_HELP_NEW_MDARR_RARE, // rare multi-dim array helper (Rank == 1) CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creation + CORINFO_HELP_NEWARR_1_FROZEN, // helper for any one dimensional array creation on a frozen segment CORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arrays CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays CORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array start diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index 68895109bb56d..671148bb05281 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -1411,6 +1411,7 @@ public enum CorJitFlag : uint CORJIT_FLAG_UNUSED6 = 12, CORJIT_FLAG_OSR = 13, // Generate alternate version for On Stack Replacement CORJIT_FLAG_ALT_JIT = 14, // JIT should consider itself an ALT_JIT + CORJIT_FLAG_FROZEN_ALLOC_ALLOWED = 15, // JIT is allowed to use *_FROZEN allocators CORJIT_FLAG_UNUSED10 = 17, CORJIT_FLAG_MAKEFINALCODE = 18, // Use the final code generator, i.e., not the interpreter. CORJIT_FLAG_READYTORUN = 19, // Use version-resilient code generation diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 43032b7616103..71d56a94935a7 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -1201,6 +1201,8 @@ const char* CorJitFlagToString(CORJIT_FLAGS::CorJitFlag flag) return "CORJIT_FLAG_OSR"; case CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_ALT_JIT: return "CORJIT_FLAG_ALT_JIT"; + case CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_FROZEN_ALLOC_ALLOWED: + return "CORJIT_FLAG_FROZEN_ALLOC_ALLOWED"; case CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_MAKEFINALCODE: return "CORJIT_FLAG_MAKEFINALCODE"; case CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_READYTORUN: diff --git a/src/coreclr/vm/comutilnative.cpp b/src/coreclr/vm/comutilnative.cpp index fbf7ae8e79f84..c99452eaca94a 100644 --- a/src/coreclr/vm/comutilnative.cpp +++ b/src/coreclr/vm/comutilnative.cpp @@ -976,25 +976,6 @@ FCIMPL3(Object*, GCInterface::AllocateNewArray, void* arrayTypeHandle, INT32 len } FCIMPLEND -FCIMPL2(Object*, GCInterface::AllocateFrozenArray, void* arrayTypeHandle, INT32 length) -{ - CONTRACTL { - FCALL_CHECK; - } CONTRACTL_END; - - OBJECTREF pRet = NULL; - TypeHandle arrayType = TypeHandle::FromPtr(arrayTypeHandle); - - HELPER_METHOD_FRAME_BEGIN_RET_0(); - - pRet = AllocateFrozenSzArray(arrayType.AsMethodTable(), length); - - HELPER_METHOD_FRAME_END(); - - return OBJECTREFToObject(pRet); -} -FCIMPLEND - FCIMPL1(INT64, GCInterface::GetTotalAllocatedBytes, CLR_BOOL precise) { FCALL_CONTRACT; diff --git a/src/coreclr/vm/comutilnative.h b/src/coreclr/vm/comutilnative.h index bf61a1cc0c20a..496c4747b0b39 100644 --- a/src/coreclr/vm/comutilnative.h +++ b/src/coreclr/vm/comutilnative.h @@ -178,7 +178,6 @@ class GCInterface { static FCDECL1(INT64, GetTotalAllocatedBytes, CLR_BOOL precise); static FCDECL3(Object*, AllocateNewArray, void* elementTypeHandle, INT32 length, INT32 flags); - static FCDECL2(Object*, AllocateFrozenArray, void* elementTypeHandle, INT32 length); NOINLINE static void SendEtwRemoveMemoryPressureEvent(UINT64 bytesAllocated); static void SendEtwAddMemoryPressureEvent(UINT64 bytesAllocated); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index d50c1cac44380..acda36bace331 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -457,7 +457,6 @@ FCFuncStart(gGCInterfaceFuncs) FCFuncElement("GetTotalAllocatedBytes", GCInterface::GetTotalAllocatedBytes) FCFuncElement("AllocateNewArray", GCInterface::AllocateNewArray) - FCFuncElement("AllocateFrozenArray", GCInterface::AllocateFrozenArray) FCFuncEnd() FCFuncStart(gGCSettingsFuncs) diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index a6654618a9541..31b5742f13b43 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -2719,6 +2719,46 @@ HCIMPL2(Object*, JIT_NewArr1, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size) } HCIMPLEND + +/*************************************************************/ +HCIMPL2(Object*, JIT_NewArr1Frozen, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size) +{ + FCALL_CONTRACT; + + OBJECTREF newArray = NULL; + + HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame + + MethodTable* pArrayMT = (MethodTable*)arrayMT; + + _ASSERTE(pArrayMT->IsFullyLoaded()); + _ASSERTE(pArrayMT->IsArray()); + _ASSERTE(!pArrayMT->IsMultiDimArray()); + + if (size < 0) + COMPlusThrow(kOverflowException); + +#ifdef HOST_64BIT + // Even though ECMA allows using a native int as the argument to newarr instruction + // (therefore size is INT_PTR), ArrayBase::m_NumComponents is 32-bit, so even on 64-bit + // platforms we can't create an array whose size exceeds 32 bits. + if (size > INT_MAX) + EX_THROW(EEMessageException, (kOverflowException, IDS_EE_ARRAY_DIMENSIONS_EXCEEDED)); +#endif + +#ifdef _DEBUG + if (g_pConfig->FastGCStressLevel()) { + GetThread()->DisableStressHeap(); + } +#endif // _DEBUG + + newArray = AllocateFrozenSzArray(pArrayMT, (INT32)size); + HELPER_METHOD_FRAME_END(); + + return(OBJECTREFToObject(newArray)); +} +HCIMPLEND + /*************************************************************/ HCIMPL3(Object*, JIT_NewMDArr, CORINFO_CLASS_HANDLE classHnd, unsigned dwNumArgs, INT32 * pArgList) { diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 6e07254e7f5c6..53a1219c2103e 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -12879,6 +12879,12 @@ CORJIT_FLAGS GetCompileFlags(MethodDesc * ftn, CORJIT_FLAGS flags, CORINFO_METHO flags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_NO_PINVOKE_INLINE); #endif // PROFILING_SUPPORTED + // Don't allow allocations on FOH from collectible contexts to avoid memory leaks + if (!ftn->GetLoaderAllocator()->CanUnload()) + { + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_FROZEN_ALLOC_ALLOWED); + } + // Set optimization flags if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT)) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Array.cs b/src/libraries/System.Private.CoreLib/src/System/Array.cs index 07d15111246ef..78ca760bcd620 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Array.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Array.cs @@ -947,13 +947,7 @@ public void CopyTo(Array array, long index) private static class EmptyArray { #pragma warning disable CA1825 // this is the implementation of Array.Empty() -#if CORECLR - internal static readonly T[] Value = GC.AllocateFrozenArray(0); -#else - // NativeAOT will preallocate this field on a frozen segment as is. - // Mono doesn't support frozen heaps internal static readonly T[] Value = new T[0]; -#endif #pragma warning restore CA1825 } From 2df09dc6a10d847f1a2accaf74e33cf02bf6ba7d Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Apr 2023 00:16:41 +0200 Subject: [PATCH 04/20] Formatting --- src/coreclr/jit/importer.cpp | 11 +++++------ src/coreclr/vm/comutilnative.cpp | 1 + 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 325b7e7c6708b..3de4d67f36858 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -9779,6 +9779,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) case CEE_NEWARR: { + /* Get the class type index operand */ _impResolveToken(CORINFO_TOKENKIND_Newarr); @@ -9814,9 +9815,8 @@ void Compiler::impImportBlockCode(BasicBlock* block) #ifdef FEATURE_READYTORUN if (opts.IsReadyToRun()) { - helper = CORINFO_HELP_READYTORUN_NEWARR_1; - op1 = impReadyToRunHelperToTree(&resolvedToken, helper, TYP_REF, nullptr, - op2); + helper = CORINFO_HELP_READYTORUN_NEWARR_1; + op1 = impReadyToRunHelperToTree(&resolvedToken, helper, TYP_REF, nullptr, op2); usingReadyToRunHelper = (op1 != nullptr); if (!usingReadyToRunHelper) @@ -9857,7 +9857,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) // We replace default heap allocator for newarr with the one that prefers frozen segments. // This is a very simple and conservative implementation targeting Array.Empty(), ideally // we want to be able to use frozen allocators more broadly, but that analysis is not trivial. - // + // if (((info.compFlags & FLG_CCTOR) == FLG_CCTOR) && // Does VM allow us to use frozen allocators? (e.g. are we in a non-collectible assembly) opts.jitFlags->IsSet(JitFlags::JIT_FLAG_FROZEN_ALLOC_ALLOWED)) @@ -9870,8 +9870,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) if (getU1LittleEndian(nextOpcode2) == CEE_RET) { // TODO in this PR: R2R - if (helper == CORINFO_HELP_NEWARR_1_OBJ || - helper == CORINFO_HELP_NEWARR_1_VC) + if (helper == CORINFO_HELP_NEWARR_1_OBJ || helper == CORINFO_HELP_NEWARR_1_VC) { // Check that the field is "static readonly" CORINFO_RESOLVED_TOKEN fldToken; diff --git a/src/coreclr/vm/comutilnative.cpp b/src/coreclr/vm/comutilnative.cpp index c99452eaca94a..488655ee7a62c 100644 --- a/src/coreclr/vm/comutilnative.cpp +++ b/src/coreclr/vm/comutilnative.cpp @@ -976,6 +976,7 @@ FCIMPL3(Object*, GCInterface::AllocateNewArray, void* arrayTypeHandle, INT32 len } FCIMPLEND + FCIMPL1(INT64, GCInterface::GetTotalAllocatedBytes, CLR_BOOL precise) { FCALL_CONTRACT; From 2011d12712d1890486b2b4b4776e85ba70db304b Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Apr 2023 01:37:13 +0200 Subject: [PATCH 05/20] align array object size --- src/coreclr/vm/frozenobjectheap.cpp | 1 + src/coreclr/vm/gchelpers.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/frozenobjectheap.cpp b/src/coreclr/vm/frozenobjectheap.cpp index 036177d1b7e95..46c0dce83ce5c 100644 --- a/src/coreclr/vm/frozenobjectheap.cpp +++ b/src/coreclr/vm/frozenobjectheap.cpp @@ -164,6 +164,7 @@ Object* FrozenObjectSegment::TryAllocateObject(PTR_MethodTable type, size_t obje { _ASSERT(m_pStart != nullptr && m_Size > 0 && m_SegmentHandle != nullptr); // Expected to be inited _ASSERT(IS_ALIGNED(m_pCurrent, DATA_ALIGNMENT)); + _ASSERT(IS_ALIGNED(objectSize, DATA_ALIGNMENT)); _ASSERT(objectSize <= FOH_COMMIT_SIZE); _ASSERT(m_pCurrent >= m_pStart + sizeof(ObjHeader)); diff --git a/src/coreclr/vm/gchelpers.cpp b/src/coreclr/vm/gchelpers.cpp index e4c704ca9d014..16fc51992c8e5 100644 --- a/src/coreclr/vm/gchelpers.cpp +++ b/src/coreclr/vm/gchelpers.cpp @@ -563,7 +563,7 @@ OBJECTREF AllocateFrozenSzArray(MethodTable* pArrayMT, INT32 cElements) #endif FrozenObjectHeapManager* foh = SystemDomain::GetFrozenObjectHeapManager(); - ArrayBase* orArray = static_cast(foh->TryAllocateObject(pArrayMT, totalSize, /*publish*/ false)); + ArrayBase* orArray = static_cast(foh->TryAllocateObject(pArrayMT, PtrAlign(totalSize), /*publish*/ false)); if (orArray == nullptr) { // We failed to allocate on a frozen segment, fallback to AllocateSzArray From 3510dfbc5f3dc1cea8ec41c5d82802b4fdf5b812 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Apr 2023 14:45:33 +0200 Subject: [PATCH 06/20] R2R support --- docs/design/coreclr/botr/readytorun-format.md | 2 ++ src/coreclr/inc/readytorun.h | 7 +++++-- src/coreclr/inc/readytorunhelpers.h | 1 + src/coreclr/jit/importer.cpp | 9 +++++++-- src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h | 2 +- .../tools/Common/Internal/Runtime/ModuleHeaders.cs | 2 +- .../tools/Common/Internal/Runtime/ReadyToRunConstants.cs | 2 ++ .../JitInterface/CorInfoImpl.ReadyToRun.cs | 3 +++ .../ReadyToRunSignature.cs | 4 ++++ 9 files changed, 26 insertions(+), 6 deletions(-) diff --git a/docs/design/coreclr/botr/readytorun-format.md b/docs/design/coreclr/botr/readytorun-format.md index fa6bb18b114c9..81a9232e34e36 100644 --- a/docs/design/coreclr/botr/readytorun-format.md +++ b/docs/design/coreclr/botr/readytorun-format.md @@ -798,6 +798,8 @@ enum ReadyToRunHelper READYTORUN_HELPER_GenericNonGcTlsBase = 0x67, READYTORUN_HELPER_VirtualFuncPtr = 0x68, READYTORUN_HELPER_IsInstanceOfException = 0x69, + READYTORUN_HELPER_NewFrozenArray = 0x6A, + READYTORUN_HELPER_NewFrozenObject = 0x6B, // Long mul/div/shift ops READYTORUN_HELPER_LMul = 0xC0, diff --git a/src/coreclr/inc/readytorun.h b/src/coreclr/inc/readytorun.h index 4754e0a294fe8..a4485ba4689c7 100644 --- a/src/coreclr/inc/readytorun.h +++ b/src/coreclr/inc/readytorun.h @@ -17,10 +17,10 @@ // Keep these in sync with // src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs // src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h -#define READYTORUN_MAJOR_VERSION 0x0009 +#define READYTORUN_MAJOR_VERSION 0x000A #define READYTORUN_MINOR_VERSION 0x0000 -#define MINIMUM_READYTORUN_MAJOR_VERSION 0x009 +#define MINIMUM_READYTORUN_MAJOR_VERSION 0x00A // R2R Version 2.1 adds the InliningInfo section // R2R Version 2.2 adds the ProfileDataInfo section @@ -30,6 +30,7 @@ // R2R 6.0 is not backward compatible with 5.x or earlier. // R2R Version 8.0 Changes the alignment of the Int128 type // R2R Version 9.0 adds support for the Vector512 type +// R2R Version 10.0 adds support for "frozen" allocators struct READYTORUN_CORE_HEADER { @@ -335,6 +336,8 @@ enum ReadyToRunHelper READYTORUN_HELPER_GenericNonGcTlsBase = 0x67, READYTORUN_HELPER_VirtualFuncPtr = 0x68, READYTORUN_HELPER_IsInstanceOfException = 0x69, + READYTORUN_HELPER_NewFrozenArray = 0x6A, + READYTORUN_HELPER_NewFrozenObject = 0x6B, // Long mul/div/shift ops READYTORUN_HELPER_LMul = 0xC0, diff --git a/src/coreclr/inc/readytorunhelpers.h b/src/coreclr/inc/readytorunhelpers.h index b9d904b9c4193..fea00b47959b1 100644 --- a/src/coreclr/inc/readytorunhelpers.h +++ b/src/coreclr/inc/readytorunhelpers.h @@ -45,6 +45,7 @@ HELPER(READYTORUN_HELPER_NewMultiDimArr, CORINFO_HELP_NEW_MDARR, HELPER(READYTORUN_HELPER_NewObject, CORINFO_HELP_NEWFAST, ) HELPER(READYTORUN_HELPER_NewArray, CORINFO_HELP_NEWARR_1_DIRECT, ) +HELPER(READYTORUN_HELPER_NewFrozenArray, CORINFO_HELP_NEWARR_1_FROZEN, ) HELPER(READYTORUN_HELPER_CheckCastAny, CORINFO_HELP_CHKCASTANY, ) HELPER(READYTORUN_HELPER_CheckInstanceAny, CORINFO_HELP_ISINSTANCEOFANY, ) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 3de4d67f36858..c94de1eedc669 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -9859,6 +9859,8 @@ void Compiler::impImportBlockCode(BasicBlock* block) // we want to be able to use frozen allocators more broadly, but that analysis is not trivial. // if (((info.compFlags & FLG_CCTOR) == FLG_CCTOR) && + // NativeAOT is able to preinitialize objects on frozen segments without our help + !IsTargetAbi(CORINFO_NATIVEAOT_ABI) && // Does VM allow us to use frozen allocators? (e.g. are we in a non-collectible assembly) opts.jitFlags->IsSet(JitFlags::JIT_FLAG_FROZEN_ALLOC_ALLOWED)) { @@ -9869,8 +9871,11 @@ void Compiler::impImportBlockCode(BasicBlock* block) { if (getU1LittleEndian(nextOpcode2) == CEE_RET) { - // TODO in this PR: R2R - if (helper == CORINFO_HELP_NEWARR_1_OBJ || helper == CORINFO_HELP_NEWARR_1_VC) + if (CORINFO_HELP_NEWARR_1_OBJ || helper == CORINFO_HELP_NEWARR_1_VC +#ifdef FEATURE_READYTORUN + || helper == CORINFO_HELP_READYTORUN_NEWARR_1 +#endif + ) { // Check that the field is "static readonly" CORINFO_RESOLVED_TOKEN fldToken; diff --git a/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h b/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h index 7d0c985486c9d..6ec3885afc042 100644 --- a/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h +++ b/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h @@ -11,7 +11,7 @@ struct ReadyToRunHeaderConstants { static const uint32_t Signature = 0x00525452; // 'RTR' - static const uint32_t CurrentMajorVersion = 9; + static const uint32_t CurrentMajorVersion = 10; static const uint32_t CurrentMinorVersion = 0; }; diff --git a/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs b/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs index f198538949666..9363994c99ab2 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs @@ -15,7 +15,7 @@ internal struct ReadyToRunHeaderConstants { public const uint Signature = 0x00525452; // 'RTR' - public const ushort CurrentMajorVersion = 9; + public const ushort CurrentMajorVersion = 10; public const ushort CurrentMinorVersion = 0; } #if READYTORUN diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs index 36e50e0185736..644a5566bd297 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs @@ -256,6 +256,8 @@ public enum ReadyToRunHelper GenericNonGcTlsBase = 0x67, VirtualFuncPtr = 0x68, IsInstanceOfException = 0x69, + NewFrozenArray = 0x6A, + NewFrozenObject = 0x6B, // Long mul/div/shift ops LMul = 0xC0, diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index e0617683dce46..ce0f0dddfd83b 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -898,6 +898,9 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_DIRECT: id = ReadyToRunHelper.NewArray; break; + case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_FROZEN: + id = ReadyToRunHelper.NewFrozenArray; + break; case CorInfoHelpFunc.CORINFO_HELP_VIRTUAL_FUNC_PTR: id = ReadyToRunHelper.VirtualFuncPtr; break; diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs index 2d123c39d6178..b47d772f01d73 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs @@ -1774,6 +1774,10 @@ private void ParseHelper(StringBuilder builder) builder.Append("NEW_ARRAY"); break; + case ReadyToRunHelper.NewFrozenArray: + builder.Append("NEW_FROZEN_ARRAY"); + break; + case ReadyToRunHelper.CheckCastAny: builder.Append("CHECK_CAST_ANY"); break; From 09692d7fb1aca3d5627ecb72d0d98357aab08db3 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Apr 2023 15:39:32 +0200 Subject: [PATCH 07/20] Address feedback --- src/coreclr/inc/readytorun.h | 8 ++++---- src/coreclr/jit/gentree.cpp | 18 +++++++++++++----- src/coreclr/jit/importer.cpp | 5 +++-- src/coreclr/jit/importercalls.cpp | 3 ++- src/coreclr/jit/valuenum.cpp | 5 ++++- .../nativeaot/Runtime/inc/ModuleHeaders.h | 4 ++-- .../Common/Internal/Runtime/ModuleHeaders.cs | 4 ++-- 7 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/coreclr/inc/readytorun.h b/src/coreclr/inc/readytorun.h index a4485ba4689c7..a91a5718d0b0b 100644 --- a/src/coreclr/inc/readytorun.h +++ b/src/coreclr/inc/readytorun.h @@ -17,10 +17,10 @@ // Keep these in sync with // src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs // src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h -#define READYTORUN_MAJOR_VERSION 0x000A -#define READYTORUN_MINOR_VERSION 0x0000 +#define READYTORUN_MAJOR_VERSION 0x0009 +#define READYTORUN_MINOR_VERSION 0x0001 -#define MINIMUM_READYTORUN_MAJOR_VERSION 0x00A +#define MINIMUM_READYTORUN_MAJOR_VERSION 0x009 // R2R Version 2.1 adds the InliningInfo section // R2R Version 2.2 adds the ProfileDataInfo section @@ -30,7 +30,7 @@ // R2R 6.0 is not backward compatible with 5.x or earlier. // R2R Version 8.0 Changes the alignment of the Int128 type // R2R Version 9.0 adds support for the Vector512 type -// R2R Version 10.0 adds support for "frozen" allocators +// R2R Version 9.1 adds new helpers to allocate objects on frozen segments struct READYTORUN_CORE_HEADER { diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index ab71c1472fd2f..a78f234ac45f0 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -2155,17 +2155,25 @@ GenTree* Compiler::getArrayLengthFromAllocation(GenTree* tree DEBUGARG(BasicBloc if (call->gtCallType == CT_HELPER) { - switch (eeGetHelperNum(call->gtCallMethHnd)) + CorInfoHelpFunc helper = eeGetHelperNum(call->gtCallMethHnd); + switch (helper) { - case CORINFO_HELP_NEWARR_1_DIRECT: case CORINFO_HELP_NEWARR_1_FROZEN: + case CORINFO_HELP_NEWARR_1_DIRECT: case CORINFO_HELP_NEWARR_1_OBJ: case CORINFO_HELP_NEWARR_1_VC: case CORINFO_HELP_NEWARR_1_ALIGN8: { - // This is an array allocation site. Grab the array length node. - arrayLength = call->gtArgs.GetArgByIndex(1)->GetNode(); - break; + if (opts.IsReadyToRun() && helper == CORINFO_HELP_NEWARR_1_FROZEN) + { + FALLTHROUGH; + } + else + { + // This is an array allocation site. Grab the array length node. + arrayLength = call->gtArgs.GetArgByIndex(1)->GetNode(); + break; + } } case CORINFO_HELP_READYTORUN_NEWARR_1: diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index c94de1eedc669..4d4a0b1973350 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -9860,9 +9860,10 @@ void Compiler::impImportBlockCode(BasicBlock* block) // if (((info.compFlags & FLG_CCTOR) == FLG_CCTOR) && // NativeAOT is able to preinitialize objects on frozen segments without our help - !IsTargetAbi(CORINFO_NATIVEAOT_ABI) && + !IsTargetAbi(CORINFO_NATIVEAOT_ABI) // Does VM allow us to use frozen allocators? (e.g. are we in a non-collectible assembly) opts.jitFlags->IsSet(JitFlags::JIT_FLAG_FROZEN_ALLOC_ALLOWED)) + ) { // Check next two opcodes const BYTE* nextOpcode1 = codeAddr + sizeof(mdToken); @@ -9873,7 +9874,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) { if (CORINFO_HELP_NEWARR_1_OBJ || helper == CORINFO_HELP_NEWARR_1_VC #ifdef FEATURE_READYTORUN - || helper == CORINFO_HELP_READYTORUN_NEWARR_1 + || helper == CORINFO_HELP_READYTORUN_NEWARR_1 #endif ) { diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index e6b838a485299..66c5ee06c1686 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -2043,7 +2043,8 @@ GenTree* Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig) GenTree* arrayLengthNode; #ifdef FEATURE_READYTORUN - if (newArrayCall->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_READYTORUN_NEWARR_1)) + if (newArrayCall->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_READYTORUN_NEWARR_1) || + newArrayCall->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_FROZEN)) { // Array length is 1st argument for readytorun helper arrayLengthNode = newArrayCall->AsCall()->gtArgs.GetArgByIndex(0)->GetNode(); diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 51a497663a8eb..8755533c24dee 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -12172,7 +12172,6 @@ VNFunc Compiler::fgValueNumberJitHelperMethodVNFunc(CorInfoHelpFunc helpFunc) break; case CORINFO_HELP_NEWARR_1_DIRECT: - case CORINFO_HELP_NEWARR_1_FROZEN: case CORINFO_HELP_NEWARR_1_OBJ: case CORINFO_HELP_NEWARR_1_VC: case CORINFO_HELP_NEWARR_1_ALIGN8: @@ -12188,6 +12187,10 @@ VNFunc Compiler::fgValueNumberJitHelperMethodVNFunc(CorInfoHelpFunc helpFunc) vnf = VNF_JitReadyToRunNewArr; break; + case CORINFO_HELP_NEWARR_1_FROZEN: + vnf = opts.IsReadyToRun() ? VNF_JitReadyToRunNewArr : VNF_JitNewArr; + break; + case CORINFO_HELP_GETGENERICS_GCSTATIC_BASE: vnf = VNF_GetgenericsGcstaticBase; break; diff --git a/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h b/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h index 6ec3885afc042..e343de0dab7a0 100644 --- a/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h +++ b/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h @@ -11,8 +11,8 @@ struct ReadyToRunHeaderConstants { static const uint32_t Signature = 0x00525452; // 'RTR' - static const uint32_t CurrentMajorVersion = 10; - static const uint32_t CurrentMinorVersion = 0; + static const uint32_t CurrentMajorVersion = 9; + static const uint32_t CurrentMinorVersion = 1; }; struct ReadyToRunHeader diff --git a/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs b/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs index 9363994c99ab2..52d098a0ebc6a 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs @@ -15,8 +15,8 @@ internal struct ReadyToRunHeaderConstants { public const uint Signature = 0x00525452; // 'RTR' - public const ushort CurrentMajorVersion = 10; - public const ushort CurrentMinorVersion = 0; + public const ushort CurrentMajorVersion = 9; + public const ushort CurrentMinorVersion = 1; } #if READYTORUN #pragma warning disable 0169 From 049598042511a3061ecb74f657daa98e2a52a2dc Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Apr 2023 15:40:23 +0200 Subject: [PATCH 08/20] formatting --- src/coreclr/jit/importer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 4d4a0b1973350..b69a09b4422d8 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -9860,10 +9860,9 @@ void Compiler::impImportBlockCode(BasicBlock* block) // if (((info.compFlags & FLG_CCTOR) == FLG_CCTOR) && // NativeAOT is able to preinitialize objects on frozen segments without our help - !IsTargetAbi(CORINFO_NATIVEAOT_ABI) + !IsTargetAbi(CORINFO_NATIVEAOT_ABI) && // Does VM allow us to use frozen allocators? (e.g. are we in a non-collectible assembly) opts.jitFlags->IsSet(JitFlags::JIT_FLAG_FROZEN_ALLOC_ALLOWED)) - ) { // Check next two opcodes const BYTE* nextOpcode1 = codeAddr + sizeof(mdToken); From 2525fc11088d43f6ca158bcb7aac3e582da0b2e0 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Apr 2023 16:28:40 +0200 Subject: [PATCH 09/20] fix build --- src/coreclr/inc/readytorunhelpers.h | 2 +- src/coreclr/jit/importer.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/coreclr/inc/readytorunhelpers.h b/src/coreclr/inc/readytorunhelpers.h index fea00b47959b1..f26feed650fdb 100644 --- a/src/coreclr/inc/readytorunhelpers.h +++ b/src/coreclr/inc/readytorunhelpers.h @@ -45,7 +45,6 @@ HELPER(READYTORUN_HELPER_NewMultiDimArr, CORINFO_HELP_NEW_MDARR, HELPER(READYTORUN_HELPER_NewObject, CORINFO_HELP_NEWFAST, ) HELPER(READYTORUN_HELPER_NewArray, CORINFO_HELP_NEWARR_1_DIRECT, ) -HELPER(READYTORUN_HELPER_NewFrozenArray, CORINFO_HELP_NEWARR_1_FROZEN, ) HELPER(READYTORUN_HELPER_CheckCastAny, CORINFO_HELP_CHKCASTANY, ) HELPER(READYTORUN_HELPER_CheckInstanceAny, CORINFO_HELP_ISINSTANCEOFANY, ) @@ -56,6 +55,7 @@ HELPER(READYTORUN_HELPER_GenericNonGcTlsBase, CORINFO_HELP_GETGENERICS_NON HELPER(READYTORUN_HELPER_VirtualFuncPtr, CORINFO_HELP_VIRTUAL_FUNC_PTR, ) HELPER(READYTORUN_HELPER_IsInstanceOfException, CORINFO_HELP_ISINSTANCEOF_EXCEPTION, ) +HELPER(READYTORUN_HELPER_NewFrozenArray, CORINFO_HELP_NEWARR_1_FROZEN, ) HELPER(READYTORUN_HELPER_LMul, CORINFO_HELP_LMUL, ) HELPER(READYTORUN_HELPER_LMulOfv, CORINFO_HELP_LMUL_OVF, ) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index b69a09b4422d8..d9472f3ef4d41 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -9860,9 +9860,10 @@ void Compiler::impImportBlockCode(BasicBlock* block) // if (((info.compFlags & FLG_CCTOR) == FLG_CCTOR) && // NativeAOT is able to preinitialize objects on frozen segments without our help - !IsTargetAbi(CORINFO_NATIVEAOT_ABI) && + !IsTargetAbi(CORINFO_NATIVEAOT_ABI) // Does VM allow us to use frozen allocators? (e.g. are we in a non-collectible assembly) - opts.jitFlags->IsSet(JitFlags::JIT_FLAG_FROZEN_ALLOC_ALLOWED)) + // && opts.jitFlags->IsSet(JitFlags::JIT_FLAG_FROZEN_ALLOC_ALLOWED)) + ) { // Check next two opcodes const BYTE* nextOpcode1 = codeAddr + sizeof(mdToken); @@ -9871,7 +9872,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) { if (getU1LittleEndian(nextOpcode2) == CEE_RET) { - if (CORINFO_HELP_NEWARR_1_OBJ || helper == CORINFO_HELP_NEWARR_1_VC + if (helper == CORINFO_HELP_NEWARR_1_OBJ || helper == CORINFO_HELP_NEWARR_1_VC #ifdef FEATURE_READYTORUN || helper == CORINFO_HELP_READYTORUN_NEWARR_1 #endif From 7e0a6dcd66e14867ff5c6e0101817788953c174a Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Apr 2023 17:17:42 +0200 Subject: [PATCH 10/20] Clean up --- src/coreclr/jit/importer.cpp | 95 +++++++++---------- .../ReadyToRunCodegenCompilationBuilder.cs | 2 + 2 files changed, 47 insertions(+), 50 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index d9472f3ef4d41..0e401b5c3d831 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -9810,10 +9810,52 @@ void Compiler::impImportBlockCode(BasicBlock* block) // So if we have an int, explicitly extend it to be a native int. op2 = impImplicitIorI4Cast(op2, TYP_I_IMPL); - CorInfoHelpFunc helper = CORINFO_HELP_UNDEF; + bool isFrozenAllocator = false; + // If we're jitting a static constructor and detect the following code pattern: + // + // newarr + // stsfld + // ret + // + // We replace default heap allocator for newarr with the one that prefers frozen segments. + // This is a very simple and conservative implementation targeting Array.Empty(), ideally + // we want to be able to use frozen allocators more broadly, but that analysis is not trivial. + // + if (((info.compFlags & FLG_CCTOR) == FLG_CCTOR) && + // Does VM allow us to use frozen allocators? + opts.jitFlags->IsSet(JitFlags::JIT_FLAG_FROZEN_ALLOC_ALLOWED)) + { + // Check next two opcodes + const BYTE* nextOpcode1 = codeAddr + sizeof(mdToken); + const BYTE* nextOpcode2 = nextOpcode1 + sizeof(mdToken) + 1; + if (nextOpcode2 <= codeEndp && getU1LittleEndian(nextOpcode1) == CEE_STSFLD) + { + if (getU1LittleEndian(nextOpcode2) == CEE_RET) + { + // Check that the field is "static readonly" + CORINFO_RESOLVED_TOKEN fldToken; + impResolveToken(nextOpcode1 + 1, &fldToken, CORINFO_TOKENKIND_Field); + CORINFO_FIELD_INFO fi; + eeGetFieldInfo(&fldToken, CORINFO_ACCESS_SET, &fi); + unsigned flagsToCheck = CORINFO_FLG_FIELD_STATIC | CORINFO_FLG_FIELD_FINAL; + if ((fi.fieldFlags & flagsToCheck) == flagsToCheck) + { +#ifdef FEATURE_READYTORUN + if (opts.IsReadyToRun()) + { + // Need to restore array classes before creating array objects on the heap + op1 = impTokenToHandle(&resolvedToken, nullptr, true /*mustRestoreHandle*/); + } +#endif + op1 = gtNewHelperCallNode(CORINFO_HELP_NEWARR_1_FROZEN, TYP_REF, op1, op2); + isFrozenAllocator = true; + } + } + } + } #ifdef FEATURE_READYTORUN - if (opts.IsReadyToRun()) + if (opts.IsReadyToRun() && !isFrozenAllocator) { helper = CORINFO_HELP_READYTORUN_NEWARR_1; op1 = impReadyToRunHelperToTree(&resolvedToken, helper, TYP_REF, nullptr, op2); @@ -9828,7 +9870,6 @@ void Compiler::impImportBlockCode(BasicBlock* block) // 3) Allocate the new array // Reason: performance (today, we'll always use the slow helper for the R2R generics case) - // Need to restore array classes before creating array objects on the heap op1 = impTokenToHandle(&resolvedToken, nullptr, true /*mustRestoreHandle*/); if (op1 == nullptr) { // compDonotInline() @@ -9837,7 +9878,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) } } - if (!usingReadyToRunHelper) + if (!usingReadyToRunHelper && !isFrozenAllocator) #endif { /* Create a call to 'new' */ @@ -9848,52 +9889,6 @@ void Compiler::impImportBlockCode(BasicBlock* block) op1 = gtNewHelperCallNode(helper, TYP_REF, op1, op2); } - // If we're jitting a static constructor and detect the following code pattern: - // - // newarr - // stsfld - // ret - // - // We replace default heap allocator for newarr with the one that prefers frozen segments. - // This is a very simple and conservative implementation targeting Array.Empty(), ideally - // we want to be able to use frozen allocators more broadly, but that analysis is not trivial. - // - if (((info.compFlags & FLG_CCTOR) == FLG_CCTOR) && - // NativeAOT is able to preinitialize objects on frozen segments without our help - !IsTargetAbi(CORINFO_NATIVEAOT_ABI) - // Does VM allow us to use frozen allocators? (e.g. are we in a non-collectible assembly) - // && opts.jitFlags->IsSet(JitFlags::JIT_FLAG_FROZEN_ALLOC_ALLOWED)) - ) - { - // Check next two opcodes - const BYTE* nextOpcode1 = codeAddr + sizeof(mdToken); - const BYTE* nextOpcode2 = nextOpcode1 + sizeof(mdToken) + 1; - if (nextOpcode2 <= codeEndp && getU1LittleEndian(nextOpcode1) == CEE_STSFLD) - { - if (getU1LittleEndian(nextOpcode2) == CEE_RET) - { - if (helper == CORINFO_HELP_NEWARR_1_OBJ || helper == CORINFO_HELP_NEWARR_1_VC -#ifdef FEATURE_READYTORUN - || helper == CORINFO_HELP_READYTORUN_NEWARR_1 -#endif - ) - { - // Check that the field is "static readonly" - CORINFO_RESOLVED_TOKEN fldToken; - impResolveToken(nextOpcode1 + 1, &fldToken, CORINFO_TOKENKIND_Field); - CORINFO_FIELD_INFO fi; - eeGetFieldInfo(&fldToken, CORINFO_ACCESS_SET, &fi); - unsigned flagsToCheck = CORINFO_FLG_FIELD_STATIC | CORINFO_FLG_FIELD_FINAL; - if ((fi.fieldFlags & flagsToCheck) == flagsToCheck) - { - // Replace the helper with the frozen version - op1->AsCall()->gtCallMethHnd = eeFindHelper(CORINFO_HELP_NEWARR_1_FROZEN); - } - } - } - } - } - op1->AsCall()->compileTimeHelperArgumentHandle = (CORINFO_GENERIC_HANDLE)resolvedToken.hClass; // Remember that this function contains 'new' of an SD array. diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs index 33388962e8679..d0b2539ca1c83 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs @@ -291,6 +291,8 @@ public override ICompilation ToCompilation() break; } + corJitFlags.Add(CorJitFlag.CORJIT_FLAG_FROZEN_ALLOC_ALLOWED); + if (!_isJitInitialized) { JitConfigProvider.Initialize(_context.Target, corJitFlags, _ryujitOptions, _jitPath); From 3cd4e4ff5c485ca440253d3e45305a52cfc3dff8 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Apr 2023 17:38:06 +0200 Subject: [PATCH 11/20] Remove CORINFO_HELP_ARE_TYPES_EQUIVALENT --- docs/design/coreclr/botr/readytorun-format.md | 1 - src/coreclr/inc/corinfo.h | 2 -- src/coreclr/inc/jithelpers.h | 2 -- src/coreclr/inc/readytorun.h | 1 - src/coreclr/jit/gentree.cpp | 23 ++----------------- src/coreclr/jit/utils.cpp | 1 - src/coreclr/jit/valuenum.cpp | 4 ---- src/coreclr/jit/valuenumfuncs.h | 2 -- .../Internal/Runtime/ReadyToRunConstants.cs | 3 --- .../Common/JitInterface/CorInfoHelpFunc.cs | 2 -- .../ILCompiler.Compiler/Compiler/JitHelper.cs | 4 ---- .../JitInterface/CorInfoImpl.RyuJit.cs | 4 ---- src/coreclr/vm/gchelpers.cpp | 6 ----- 13 files changed, 2 insertions(+), 53 deletions(-) diff --git a/docs/design/coreclr/botr/readytorun-format.md b/docs/design/coreclr/botr/readytorun-format.md index 81a9232e34e36..d2ae4a39ceb15 100644 --- a/docs/design/coreclr/botr/readytorun-format.md +++ b/docs/design/coreclr/botr/readytorun-format.md @@ -799,7 +799,6 @@ enum ReadyToRunHelper READYTORUN_HELPER_VirtualFuncPtr = 0x68, READYTORUN_HELPER_IsInstanceOfException = 0x69, READYTORUN_HELPER_NewFrozenArray = 0x6A, - READYTORUN_HELPER_NewFrozenObject = 0x6B, // Long mul/div/shift ops READYTORUN_HELPER_LMul = 0xC0, diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 8334d11df9751..d4d1e4c6d4b3d 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -584,8 +584,6 @@ enum CorInfoHelpFunc CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE, // Convert from a TypeHandle (native structure pointer) to RuntimeTypeHandle at run-time CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL, // Convert from a TypeHandle (native structure pointer) to RuntimeTypeHandle at run-time, handle might point to a null type - CORINFO_HELP_ARE_TYPES_EQUIVALENT, // Check whether two TypeHandles (native structure pointers) are equivalent - CORINFO_HELP_VIRTUAL_FUNC_PTR, // look up a virtual method at run-time // Not a real helpers. Instead of taking handle arguments, these helpers point to a small stub that loads the handle argument and calls the static helper. diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index 36b58e63b2799..c11e6e726763e 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -253,8 +253,6 @@ JITHELPER(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE, JIT_GetRuntimeType, CORINFO_HELP_SIG_REG_ONLY) JITHELPER(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL, JIT_GetRuntimeType_MaybeNull, CORINFO_HELP_SIG_REG_ONLY) - JITHELPER(CORINFO_HELP_ARE_TYPES_EQUIVALENT, NULL, CORINFO_HELP_SIG_REG_ONLY) - JITHELPER(CORINFO_HELP_VIRTUAL_FUNC_PTR, JIT_VirtualFunctionPointer, CORINFO_HELP_SIG_4_STACK) JITHELPER(CORINFO_HELP_READYTORUN_NEW, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB) diff --git a/src/coreclr/inc/readytorun.h b/src/coreclr/inc/readytorun.h index a91a5718d0b0b..7294d3ada5a6f 100644 --- a/src/coreclr/inc/readytorun.h +++ b/src/coreclr/inc/readytorun.h @@ -337,7 +337,6 @@ enum ReadyToRunHelper READYTORUN_HELPER_VirtualFuncPtr = 0x68, READYTORUN_HELPER_IsInstanceOfException = 0x69, READYTORUN_HELPER_NewFrozenArray = 0x6A, - READYTORUN_HELPER_NewFrozenObject = 0x6B, // Long mul/div/shift ops READYTORUN_HELPER_LMul = 0xC0, diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index a78f234ac45f0..b0585bd66e9d7 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -13335,27 +13335,8 @@ GenTree* Compiler::gtCreateHandleCompare(genTreeOps oper, GenTree* op2, CorInfoInlineTypeCheck typeCheckInliningResult) { - // If we can compare pointers directly, just emit the binary operation - if (typeCheckInliningResult == CORINFO_INLINE_TYPECHECK_PASS) - { - return gtNewOperNode(oper, TYP_INT, op1, op2); - } - - assert(typeCheckInliningResult == CORINFO_INLINE_TYPECHECK_USE_HELPER); - - // Emit a call to a runtime helper - GenTree* ret = gtNewHelperCallNode(CORINFO_HELP_ARE_TYPES_EQUIVALENT, TYP_INT, op1, op2); - if (oper == GT_EQ) - { - ret = gtNewOperNode(GT_NE, TYP_INT, ret, gtNewIconNode(0, TYP_INT)); - } - else - { - assert(oper == GT_NE); - ret = gtNewOperNode(GT_EQ, TYP_INT, ret, gtNewIconNode(0, TYP_INT)); - } - - return ret; + assert(typeCheckInliningResult == CORINFO_INLINE_TYPECHECK_PASS); + return gtNewOperNode(oper, TYP_INT, op1, op2); } //------------------------------------------------------------------------ diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index db784abb8f06b..d60e98fab3c41 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -1387,7 +1387,6 @@ void HelperCallProperties::init() noThrow = true; // These return null for a failing cast break; - case CORINFO_HELP_ARE_TYPES_EQUIVALENT: case CORINFO_HELP_GETCURRENTMANAGEDTHREADID: isPure = true; noThrow = true; diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 8755533c24dee..03d544339af91 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -12309,10 +12309,6 @@ VNFunc Compiler::fgValueNumberJitHelperMethodVNFunc(CorInfoHelpFunc helpFunc) vnf = VNF_TypeHandleToRuntimeTypeHandle; break; - case CORINFO_HELP_ARE_TYPES_EQUIVALENT: - vnf = VNF_AreTypesEquivalent; - break; - case CORINFO_HELP_READYTORUN_ISINSTANCEOF: vnf = VNF_ReadyToRunIsInstanceOf; break; diff --git a/src/coreclr/jit/valuenumfuncs.h b/src/coreclr/jit/valuenumfuncs.h index 6551be8772a2a..df804121eb98a 100644 --- a/src/coreclr/jit/valuenumfuncs.h +++ b/src/coreclr/jit/valuenumfuncs.h @@ -41,8 +41,6 @@ ValueNumFuncDef(ReadyToRunIsInstanceOf, 2, false, false, false) // Args: 0 ValueNumFuncDef(TypeHandleToRuntimeType, 1, false, false, false) // Args: 0: TypeHandle to translate ValueNumFuncDef(TypeHandleToRuntimeTypeHandle, 1, false, false, false) // Args: 0: TypeHandle to translate -ValueNumFuncDef(AreTypesEquivalent, 2, false, false, false) // Args: 0: first TypeHandle, 1: second TypeHandle - ValueNumFuncDef(LdElemA, 3, false, false, false) // Args: 0: array value; 1: index value; 2: type handle of element. ValueNumFuncDef(ByrefExposedLoad, 3, false, false, false) // Args: 0: type handle/id, 1: pointer value; 2: ByrefExposed heap value diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs index 644a5566bd297..b7e48c6d9c743 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs @@ -257,7 +257,6 @@ public enum ReadyToRunHelper VirtualFuncPtr = 0x68, IsInstanceOfException = 0x69, NewFrozenArray = 0x6A, - NewFrozenObject = 0x6B, // Long mul/div/shift ops LMul = 0xC0, @@ -342,8 +341,6 @@ public enum ReadyToRunHelper GetRuntimeType, - AreTypesEquivalent, - CheckCastClass, CheckInstanceClass, CheckCastArray, diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs index 7c456180bbb2e..c9ffa6412b2d9 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs @@ -226,8 +226,6 @@ which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE, // Convert from a TypeHandle (native structure pointer) to RuntimeType at run-time CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL, // Convert from a TypeHandle (native structure pointer) to RuntimeTypeHandle at run-time, handle might point to a null type - CORINFO_HELP_ARE_TYPES_EQUIVALENT, // Check whether two TypeHandles (native structure pointers) are equivalent - CORINFO_HELP_VIRTUAL_FUNC_PTR, // look up a virtual method at run-time // Not a real helpers. Instead of taking handle arguments, these helpers point to a small stub that loads the handle argument and calls the static helper. diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs index 123166e3ec7fa..b126d06da8371 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs @@ -135,10 +135,6 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, methodDesc = context.GetHelperEntryPoint("LdTokenHelpers", "GetRuntimeFieldHandle"); break; - case ReadyToRunHelper.AreTypesEquivalent: - mangledName = "RhTypeCast_AreTypesEquivalent"; - break; - case ReadyToRunHelper.Lng2Dbl: mangledName = "RhpLng2Dbl"; break; diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index 8d0b4de86d843..b8a56bb708cb0 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -544,10 +544,6 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) id = ReadyToRunHelper.GetRuntimeTypeHandle; break; - case CorInfoHelpFunc.CORINFO_HELP_ARE_TYPES_EQUIVALENT: - id = ReadyToRunHelper.AreTypesEquivalent; - break; - case CorInfoHelpFunc.CORINFO_HELP_ISINSTANCEOF_EXCEPTION: id = ReadyToRunHelper.IsInstanceOfException; break; diff --git a/src/coreclr/vm/gchelpers.cpp b/src/coreclr/vm/gchelpers.cpp index 16fc51992c8e5..c411351471f81 100644 --- a/src/coreclr/vm/gchelpers.cpp +++ b/src/coreclr/vm/gchelpers.cpp @@ -518,12 +518,6 @@ OBJECTREF AllocateFrozenSzArray(MethodTable* pArrayMT, INT32 cElements) return AllocateSzArray(pArrayMT, cElements); } - if (pArrayMT->Collectible()) - { - // Ignore arrays of collectible types - return AllocateSzArray(pArrayMT, cElements); - } - // Disallow the creation of void[] (an array of System.Void) if (elemType == ELEMENT_TYPE_VOID) COMPlusThrow(kArgumentException); From c71cda7926e70fffc093f7d78f07d8a63de53731 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Apr 2023 19:29:21 +0200 Subject: [PATCH 12/20] Clean up --- src/coreclr/jit/compiler.h | 4 -- src/coreclr/jit/gentree.cpp | 38 +++++-------------- src/coreclr/jit/importer.cpp | 12 +++--- .../ReadyToRunCodegenCompilationBuilder.cs | 2 + src/coreclr/vm/gchelpers.cpp | 4 +- 5 files changed, 20 insertions(+), 40 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 86588d1c74f11..26e12c2c098ec 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -3018,10 +3018,6 @@ class Compiler GenTree* gtFoldBoxNullable(GenTree* tree); GenTree* gtFoldExprCompare(GenTree* tree); GenTree* gtFoldExprConditional(GenTree* tree); - GenTree* gtCreateHandleCompare(genTreeOps oper, - GenTree* op1, - GenTree* op2, - CorInfoInlineTypeCheck typeCheckInliningResult); GenTree* gtFoldExprCall(GenTreeCall* call); GenTree* gtFoldTypeCompare(GenTree* tree); GenTree* gtFoldTypeEqualityCall(bool isEq, GenTree* op1, GenTree* op2); diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index b0585bd66e9d7..607c8340fd489 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -2166,6 +2166,8 @@ GenTree* Compiler::getArrayLengthFromAllocation(GenTree* tree DEBUGARG(BasicBloc { if (opts.IsReadyToRun() && helper == CORINFO_HELP_NEWARR_1_FROZEN) { + // CORINFO_HELP_NEWARR_1_FROZEN is used in both JIT and R2R, + // for R2R take the same path as CORINFO_HELP_READYTORUN_NEWARR_1 FALLTHROUGH; } else @@ -13317,28 +13319,6 @@ GenTree* Compiler::gtFoldExprConditional(GenTree* tree) return replacement; } -//------------------------------------------------------------------------ -// gtCreateHandleCompare: generate a type handle comparison -// -// Arguments: -// oper -- comparison operation (equal/not equal) -// op1 -- first operand -// op2 -- second operand -// typeCheckInliningResult -- indicates how the comparison should happen -// -// Returns: -// Type comparison tree -// - -GenTree* Compiler::gtCreateHandleCompare(genTreeOps oper, - GenTree* op1, - GenTree* op2, - CorInfoInlineTypeCheck typeCheckInliningResult) -{ - assert(typeCheckInliningResult == CORINFO_INLINE_TYPECHECK_PASS); - return gtNewOperNode(oper, TYP_INT, op1, op2); -} - //------------------------------------------------------------------------ // gtFoldTypeCompare: see if a type comparison can be further simplified // @@ -13451,9 +13431,9 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree) inliningKind = info.compCompHnd->canInlineTypeCheck(cls2Hnd, CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN); } - assert(inliningKind == CORINFO_INLINE_TYPECHECK_PASS || inliningKind == CORINFO_INLINE_TYPECHECK_USE_HELPER); + assert(inliningKind == CORINFO_INLINE_TYPECHECK_PASS); - GenTree* compare = gtCreateHandleCompare(oper, op1ClassFromHandle, op2ClassFromHandle, inliningKind); + GenTree* compare = gtNewOperNode(oper, TYP_INT, op1ClassFromHandle, op2ClassFromHandle); // Drop any now-irrelevant flags compare->gtFlags |= tree->gtFlags & (GTF_RELOP_JMP_USED | GTF_DONT_CSE); @@ -13489,11 +13469,10 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree) arg2 = gtNewMethodTableLookup(arg2); - CorInfoInlineTypeCheck inliningKind = - info.compCompHnd->canInlineTypeCheck(nullptr, CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE); - assert(inliningKind == CORINFO_INLINE_TYPECHECK_PASS || inliningKind == CORINFO_INLINE_TYPECHECK_USE_HELPER); + assert(info.compCompHnd->canInlineTypeCheck(nullptr, CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE) == + CORINFO_INLINE_TYPECHECK_PASS); - GenTree* compare = gtCreateHandleCompare(oper, arg1, arg2, inliningKind); + GenTree* compare = gtNewOperNode(oper, TYP_INT, arg1, arg2); // Drop any now-irrelevant flags compare->gtFlags |= tree->gtFlags & (GTF_RELOP_JMP_USED | GTF_DONT_CSE); @@ -13591,7 +13570,8 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree) GenTree* const objMT = gtNewMethodTableLookup(objOp); // Compare the two method tables - GenTree* const compare = gtCreateHandleCompare(oper, objMT, knownMT, typeCheckInliningResult); + assert(typeCheckInliningResult == CORINFO_INLINE_TYPECHECK_PASS); + GenTree* const compare = gtNewOperNode(oper, TYP_INT, objMT, knownMT); // Drop any now irrelevant flags compare->gtFlags |= tree->gtFlags & (GTF_RELOP_JMP_USED | GTF_DONT_CSE); diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 0e401b5c3d831..423d53f0bd58c 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -9817,22 +9817,24 @@ void Compiler::impImportBlockCode(BasicBlock* block) // stsfld // ret // - // We replace default heap allocator for newarr with the one that prefers frozen segments. - // This is a very simple and conservative implementation targeting Array.Empty(), ideally - // we want to be able to use frozen allocators more broadly, but that analysis is not trivial. + // we emit a "frozen" allocator for newarr to, hopefully, allocate that array on a frozen segment. + // This is a very simple and conservative implementation targeting Array.Empty()'s shape + // Ideally, we want to be able to use frozen allocators more broadly, but such an analysis is + // not trivial. // if (((info.compFlags & FLG_CCTOR) == FLG_CCTOR) && // Does VM allow us to use frozen allocators? opts.jitFlags->IsSet(JitFlags::JIT_FLAG_FROZEN_ALLOC_ALLOWED)) { - // Check next two opcodes + // Check next two opcodes (have to be STSFLD and RET) const BYTE* nextOpcode1 = codeAddr + sizeof(mdToken); const BYTE* nextOpcode2 = nextOpcode1 + sizeof(mdToken) + 1; if (nextOpcode2 <= codeEndp && getU1LittleEndian(nextOpcode1) == CEE_STSFLD) { if (getU1LittleEndian(nextOpcode2) == CEE_RET) { - // Check that the field is "static readonly" + // Check that the field is "static readonly", we don't want to waste memory + // for potentially mutable fields. CORINFO_RESOLVED_TOKEN fldToken; impResolveToken(nextOpcode1 + 1, &fldToken, CORINFO_TOKENKIND_Field); CORINFO_FIELD_INFO fi; diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs index d0b2539ca1c83..573eacc1fcc4c 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs @@ -291,6 +291,8 @@ public override ICompilation ToCompilation() break; } + // Always allow frozen allocators for R2R (NativeAOT is able to preinitialize objects on + // frozen segments without JIT's help) corJitFlags.Add(CorJitFlag.CORJIT_FLAG_FROZEN_ALLOC_ALLOWED); if (!_isJitInitialized) diff --git a/src/coreclr/vm/gchelpers.cpp b/src/coreclr/vm/gchelpers.cpp index c411351471f81..47b1dc0410cb3 100644 --- a/src/coreclr/vm/gchelpers.cpp +++ b/src/coreclr/vm/gchelpers.cpp @@ -493,8 +493,8 @@ OBJECTREF AllocateSzArray(MethodTable* pArrayMT, INT32 cElements, GC_ALLOC_FLAGS return ObjectToOBJECTREF((Object*)orArray); } -// Same as AllocateSzArray but attempts to allocate the array on a frozen segment. -// It fallbacks to AllocateSzArray if it fails to allocate on a frozen segment. +// Same as AllocateSzArray but for frozen segments. +// Fallbacks to AllocateSzArray if it fails. OBJECTREF AllocateFrozenSzArray(MethodTable* pArrayMT, INT32 cElements) { CONTRACTL{ From 05f1f9af27134dce6d546d5dde611970bec0b9e4 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Apr 2023 22:01:49 +0200 Subject: [PATCH 13/20] Add allocator for non-array object (not used for now) --- docs/design/coreclr/botr/readytorun-format.md | 1 + src/coreclr/inc/corinfo.h | 1 + src/coreclr/inc/jithelpers.h | 1 + src/coreclr/inc/readytorun.h | 1 + src/coreclr/inc/readytorunhelpers.h | 1 + src/coreclr/jit/utils.cpp | 1 + src/coreclr/jit/valuenum.cpp | 4 ++ .../Internal/Runtime/ReadyToRunConstants.cs | 1 + .../Common/JitInterface/CorInfoHelpFunc.cs | 1 + .../JitInterface/CorInfoImpl.ReadyToRun.cs | 3 ++ .../ReadyToRunSignature.cs | 4 ++ src/coreclr/vm/gchelpers.cpp | 43 ++++++++++++++++--- src/coreclr/vm/gchelpers.h | 7 ++- src/coreclr/vm/jithelpers.cpp | 40 ++++++++++++++++- src/coreclr/vm/jitinterface.cpp | 7 ++- src/coreclr/vm/object.h | 2 +- 16 files changed, 105 insertions(+), 13 deletions(-) diff --git a/docs/design/coreclr/botr/readytorun-format.md b/docs/design/coreclr/botr/readytorun-format.md index d2ae4a39ceb15..81a9232e34e36 100644 --- a/docs/design/coreclr/botr/readytorun-format.md +++ b/docs/design/coreclr/botr/readytorun-format.md @@ -799,6 +799,7 @@ enum ReadyToRunHelper READYTORUN_HELPER_VirtualFuncPtr = 0x68, READYTORUN_HELPER_IsInstanceOfException = 0x69, READYTORUN_HELPER_NewFrozenArray = 0x6A, + READYTORUN_HELPER_NewFrozenObject = 0x6B, // Long mul/div/shift ops READYTORUN_HELPER_LMul = 0xC0, diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index d4d1e4c6d4b3d..6284ba48c1c05 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -404,6 +404,7 @@ enum CorInfoHelpFunc which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_NEWFAST, + CORINFO_HELP_NEWFAST_FROZEN, // allocator for objects on a frozen segment CORINFO_HELP_NEWSFAST, // allocator for small, non-finalizer, non-array object CORINFO_HELP_NEWSFAST_FINALIZE, // allocator for small, finalizable, non-array object CORINFO_HELP_NEWSFAST_ALIGN8, // allocator for small, non-finalizer, non-array object, 8 byte aligned diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index c11e6e726763e..60602af5832e1 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -70,6 +70,7 @@ // Allocating a new object JITHELPER(CORINFO_HELP_NEWFAST, JIT_New, CORINFO_HELP_SIG_REG_ONLY) + JITHELPER(CORINFO_HELP_NEWFAST_FROZEN, JIT_NewFrozen,CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_NEWSFAST, JIT_New, CORINFO_HELP_SIG_REG_ONLY) JITHELPER(CORINFO_HELP_NEWSFAST_FINALIZE, NULL, CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_NEWSFAST_ALIGN8, JIT_New, CORINFO_HELP_SIG_REG_ONLY) diff --git a/src/coreclr/inc/readytorun.h b/src/coreclr/inc/readytorun.h index 7294d3ada5a6f..a91a5718d0b0b 100644 --- a/src/coreclr/inc/readytorun.h +++ b/src/coreclr/inc/readytorun.h @@ -337,6 +337,7 @@ enum ReadyToRunHelper READYTORUN_HELPER_VirtualFuncPtr = 0x68, READYTORUN_HELPER_IsInstanceOfException = 0x69, READYTORUN_HELPER_NewFrozenArray = 0x6A, + READYTORUN_HELPER_NewFrozenObject = 0x6B, // Long mul/div/shift ops READYTORUN_HELPER_LMul = 0xC0, diff --git a/src/coreclr/inc/readytorunhelpers.h b/src/coreclr/inc/readytorunhelpers.h index f26feed650fdb..a13683ed630e2 100644 --- a/src/coreclr/inc/readytorunhelpers.h +++ b/src/coreclr/inc/readytorunhelpers.h @@ -56,6 +56,7 @@ HELPER(READYTORUN_HELPER_GenericNonGcTlsBase, CORINFO_HELP_GETGENERICS_NON HELPER(READYTORUN_HELPER_VirtualFuncPtr, CORINFO_HELP_VIRTUAL_FUNC_PTR, ) HELPER(READYTORUN_HELPER_IsInstanceOfException, CORINFO_HELP_ISINSTANCEOF_EXCEPTION, ) HELPER(READYTORUN_HELPER_NewFrozenArray, CORINFO_HELP_NEWARR_1_FROZEN, ) +HELPER(READYTORUN_HELPER_NewFrozenObject, CORINFO_HELP_NEWFAST_FROZEN, ) HELPER(READYTORUN_HELPER_LMul, CORINFO_HELP_LMUL, ) HELPER(READYTORUN_HELPER_LMulOfv, CORINFO_HELP_LMUL_OVF, ) diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index d60e98fab3c41..918bce4b8cfb7 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -1318,6 +1318,7 @@ void HelperCallProperties::init() case CORINFO_HELP_NEWSFAST_ALIGN8: case CORINFO_HELP_NEWSFAST_ALIGN8_VC: case CORINFO_HELP_NEWFAST: + case CORINFO_HELP_NEWFAST_FROZEN: case CORINFO_HELP_NEWSFAST_FINALIZE: case CORINFO_HELP_NEWSFAST_ALIGN8_FINALIZE: case CORINFO_HELP_READYTORUN_NEW: diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 03d544339af91..836dc1e5421ce 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -12187,6 +12187,10 @@ VNFunc Compiler::fgValueNumberJitHelperMethodVNFunc(CorInfoHelpFunc helpFunc) vnf = VNF_JitReadyToRunNewArr; break; + case CORINFO_HELP_NEWFAST_FROZEN: + vnf = opts.IsReadyToRun() ? VNF_JitReadyToRunNew : VNF_JitNew; + break; + case CORINFO_HELP_NEWARR_1_FROZEN: vnf = opts.IsReadyToRun() ? VNF_JitReadyToRunNewArr : VNF_JitNewArr; break; diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs index b7e48c6d9c743..70aded6b3ed46 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs @@ -257,6 +257,7 @@ public enum ReadyToRunHelper VirtualFuncPtr = 0x68, IsInstanceOfException = 0x69, NewFrozenArray = 0x6A, + NewFrozenObject = 0x6B, // Long mul/div/shift ops LMul = 0xC0, diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs index c9ffa6412b2d9..b395c14233c32 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs @@ -47,6 +47,7 @@ public enum CorInfoHelpFunc which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_NEWFAST, + CORINFO_HELP_NEWFAST_FROZEN, // allocator for objects on a frozen segment CORINFO_HELP_NEWSFAST, // allocator for small, non-finalizer, non-array object CORINFO_HELP_NEWSFAST_FINALIZE, // allocator for small, finalizable, non-array object CORINFO_HELP_NEWSFAST_ALIGN8, // allocator for small, non-finalizer, non-array object, 8 byte aligned diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index ce0f0dddfd83b..351e996466cd9 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -901,6 +901,9 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_FROZEN: id = ReadyToRunHelper.NewFrozenArray; break; + case CorInfoHelpFunc.CORINFO_HELP_NEWFAST_FROZEN: + id = ReadyToRunHelper.NewFrozenObject; + break; case CorInfoHelpFunc.CORINFO_HELP_VIRTUAL_FUNC_PTR: id = ReadyToRunHelper.VirtualFuncPtr; break; diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs index b47d772f01d73..f5bbd0bc3b1a3 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs @@ -1778,6 +1778,10 @@ private void ParseHelper(StringBuilder builder) builder.Append("NEW_FROZEN_ARRAY"); break; + case ReadyToRunHelper.NewFrozenObject: + builder.Append("NEW_FROZEN_OBJECT"); + break; + case ReadyToRunHelper.CheckCastAny: builder.Append("CHECK_CAST_ANY"); break; diff --git a/src/coreclr/vm/gchelpers.cpp b/src/coreclr/vm/gchelpers.cpp index 47b1dc0410cb3..e3c882f623b24 100644 --- a/src/coreclr/vm/gchelpers.cpp +++ b/src/coreclr/vm/gchelpers.cpp @@ -493,9 +493,7 @@ OBJECTREF AllocateSzArray(MethodTable* pArrayMT, INT32 cElements, GC_ALLOC_FLAGS return ObjectToOBJECTREF((Object*)orArray); } -// Same as AllocateSzArray but for frozen segments. -// Fallbacks to AllocateSzArray if it fails. -OBJECTREF AllocateFrozenSzArray(MethodTable* pArrayMT, INT32 cElements) +OBJECTREF TryAllocateFrozenSzArray(MethodTable* pArrayMT, INT32 cElements) { CONTRACTL{ THROWS; @@ -515,7 +513,7 @@ OBJECTREF AllocateFrozenSzArray(MethodTable* pArrayMT, INT32 cElements) if (pArrayMT->ContainsPointers() && cElements > 0) { // For arrays with GC pointers we can only work with empty arrays - return AllocateSzArray(pArrayMT, cElements); + return NULL; } // Disallow the creation of void[] (an array of System.Void) @@ -546,13 +544,13 @@ OBJECTREF AllocateFrozenSzArray(MethodTable* pArrayMT, INT32 cElements) // so we give up on arrays of value types requiring 8 byte alignment on 32bit platforms. if ((DATA_ALIGNMENT < sizeof(double)) && (elemType == ELEMENT_TYPE_R8)) { - return AllocateSzArray(pArrayMT, cElements); + return NULL; } #ifdef FEATURE_64BIT_ALIGNMENT MethodTable* pElementMT = pArrayMT->GetArrayElementTypeHandle().GetMethodTable(); if (pElementMT->RequiresAlign8() && pElementMT->IsValueType()) { - return AllocateSzArray(pArrayMT, cElements); + return NULL; } #endif @@ -562,7 +560,7 @@ OBJECTREF AllocateFrozenSzArray(MethodTable* pArrayMT, INT32 cElements) { // We failed to allocate on a frozen segment, fallback to AllocateSzArray // E.g. if the array is too big to fit on a frozen segment - return AllocateSzArray(pArrayMT, cElements); + return NULL; } orArray->m_NumComponents = cElements; @@ -1115,6 +1113,37 @@ OBJECTREF AllocateObject(MethodTable *pMT return UNCHECKED_OBJECTREF_TO_OBJECTREF(oref); } +OBJECTREF TryAllocateFrozenObject(MethodTable* pObjMT) +{ + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + PRECONDITION(CheckPointer(pObjMT)); + PRECONDITION(pObjMT->CheckInstanceActivated()); + } CONTRACTL_END; + + SetTypeHandleOnThreadForAlloc(TypeHandle(pObjMT)); + + if (pObjMT->ContainsPointers() || pObjMT->IsComObjectType()) + { + return NULL; + } + +#ifdef FEATURE_64BIT_ALIGNMENT + if (pObjMT->RequiresAlign8()) + { + // Custom alignment is not supported for frozen objects yet. + return NULL; + } +#endif // FEATURE_64BIT_ALIGNMENT + + FrozenObjectHeapManager* foh = SystemDomain::GetFrozenObjectHeapManager(); + Object* orObject = foh->TryAllocateObject(pObjMT, PtrAlign(pObjMT->GetBaseSize()), /*publish*/ true); + + return ObjectToOBJECTREF(orObject); +} + //======================================================================== // // WRITE BARRIER HELPERS diff --git a/src/coreclr/vm/gchelpers.h b/src/coreclr/vm/gchelpers.h index 967aec987aeb0..3528ef8bb47b4 100644 --- a/src/coreclr/vm/gchelpers.h +++ b/src/coreclr/vm/gchelpers.h @@ -23,8 +23,11 @@ OBJECTREF AllocateSzArray(MethodTable *pArrayMT, INT32 length, GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS); OBJECTREF AllocateSzArray(TypeHandle arrayType, INT32 length, GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS); -// Allocate single-dimensional array with a hint to prefer frozen segments -OBJECTREF AllocateFrozenSzArray(MethodTable* pArrayMT, INT32 length); +// Allocate single-dimensional array on a frozen segment +// Returns nullptr if it's not possible. +OBJECTREF TryAllocateFrozenSzArray(MethodTable* pArrayMT, INT32 length); +// Same for non-array objects +OBJECTREF TryAllocateFrozenObject(MethodTable* pObjMT); // The main Array allocation routine, can do multi-dimensional OBJECTREF AllocateArrayEx(MethodTable *pArrayMT, INT32 *pArgs, DWORD dwNumArgs, GC_ALLOC_FLAGS flags = GC_ALLOC_NO_FLAGS); diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index 31b5742f13b43..bd431b8af18a6 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -2404,6 +2404,37 @@ HCIMPL1(Object*, JIT_New, CORINFO_CLASS_HANDLE typeHnd_) } HCIMPLEND +/*************************************************************/ +HCIMPL1(Object*, JIT_NewFrozen, CORINFO_CLASS_HANDLE typeHnd_) +{ + FCALL_CONTRACT; + + OBJECTREF newobj = NULL; + HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame + + TypeHandle typeHnd(typeHnd_); + + _ASSERTE(!typeHnd.IsTypeDesc()); // heap objects must have method tables + MethodTable* pMT = typeHnd.AsMethodTable(); + _ASSERTE(pMT->IsRestored_NoLogging()); + +#ifdef _DEBUG + if (g_pConfig->FastGCStressLevel()) { + GetThread()->DisableStressHeap(); + } +#endif // _DEBUG + + newobj = TryAllocateFrozenObject(pMT); + if (newobj == NULL) + { + // Fallback to normal heap allocation. + newobj = AllocateObject(pMT); + } + + HELPER_METHOD_FRAME_END(); + return(OBJECTREFToObject(newobj)); +} +HCIMPLEND //======================================================================== @@ -2752,7 +2783,14 @@ HCIMPL2(Object*, JIT_NewArr1Frozen, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size) } #endif // _DEBUG - newArray = AllocateFrozenSzArray(pArrayMT, (INT32)size); + newArray = TryAllocateFrozenSzArray(pArrayMT, (INT32)size); + if (newArray == NULL) + { + // Fallback to default heap allocation + newArray = AllocateSzArray(pArrayMT, (INT32)size); + } + _ASSERTE(newArray != NULL); + HELPER_METHOD_FRAME_END(); return(OBJECTREFToObject(newArray)); diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 53a1219c2103e..8ba73a5a8db1e 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -6175,8 +6175,11 @@ bool CEEInfo::isObjectImmutable(CORINFO_OBJECT_HANDLE objHandle) // Empty arrays are always immutable isImmutable = true; } - // delegates and types with no instance fields are also immutable but we never allocate - // them on frozen segments (yet). + else if (type->IsDelegate() || type->GetNumInstanceFields() == 0) + { + // Delegates and types without fields are always immutable + isImmutable = true; + } EE_TO_JIT_TRANSITION(); diff --git a/src/coreclr/vm/object.h b/src/coreclr/vm/object.h index 5399b005cbdee..cca2b7e8ba849 100644 --- a/src/coreclr/vm/object.h +++ b/src/coreclr/vm/object.h @@ -522,7 +522,7 @@ class ArrayBase : public Object friend class CObjectHeader; friend class Object; friend OBJECTREF AllocateSzArray(MethodTable *pArrayMT, INT32 length, GC_ALLOC_FLAGS flags); - friend OBJECTREF AllocateFrozenSzArray(MethodTable* pArrayMT, INT32 length); + friend OBJECTREF TryAllocateFrozenSzArray(MethodTable* pArrayMT, INT32 length); friend OBJECTREF AllocateArrayEx(MethodTable *pArrayMT, INT32 *pArgs, DWORD dwNumArgs, GC_ALLOC_FLAGS flags); friend FCDECL2(Object*, JIT_NewArr1VC_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size); friend FCDECL2(Object*, JIT_NewArr1OBJ_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size); From 2547ffeca18dbb916cd02d823a00a285c58ab41e Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Apr 2023 23:28:59 +0200 Subject: [PATCH 14/20] Remove areTypesEquivalent --- src/coreclr/inc/corinfo.h | 6 - src/coreclr/inc/icorjitinfoimpl_generated.h | 4 - src/coreclr/jit/ICorJitInfo_names_generated.h | 1 - .../jit/ICorJitInfo_wrapper_generated.hpp | 10 - src/coreclr/jit/morph.cpp | 8 + .../tools/Common/JitInterface/CorInfoImpl.cs | 2 - .../JitInterface/CorInfoImpl_generated.cs | 226 ++++++++---------- .../ThunkGenerator/ThunkInput.txt | 1 - .../ILVerification/ILImporter.StackValue.cs | 3 +- .../aot/jitinterface/jitinterface_generated.h | 11 - .../tools/superpmi/superpmi-shared/lwmlist.h | 1 - .../superpmi-shared/methodcontext.cpp | 31 --- .../superpmi/superpmi-shared/methodcontext.h | 6 +- .../superpmi-shim-collector/icorjitinfo.cpp | 9 - .../icorjitinfo_generated.cpp | 8 - .../icorjitinfo_generated.cpp | 7 - .../tools/superpmi/superpmi/icorjitinfo.cpp | 7 - src/coreclr/vm/jitinterface.cpp | 23 -- 18 files changed, 116 insertions(+), 248 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 6284ba48c1c05..6e3900ab14606 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2619,12 +2619,6 @@ class ICorStaticInfo CORINFO_CLASS_HANDLE parent // base type ) = 0; - // TRUE if cls1 and cls2 are considered equivalent types. - virtual bool areTypesEquivalent( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2 - ) = 0; - // See if a cast from fromClass to toClass will succeed, fail, or needs // to be resolved at runtime. virtual TypeCompareState compareTypesForCast( diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index 18ea19b28df17..cf4c94498c33a 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -339,10 +339,6 @@ bool canCast( CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent) override; -bool areTypesEquivalent( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2) override; - TypeCompareState compareTypesForCast( CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) override; diff --git a/src/coreclr/jit/ICorJitInfo_names_generated.h b/src/coreclr/jit/ICorJitInfo_names_generated.h index e554312dedb64..cb5db87194525 100644 --- a/src/coreclr/jit/ICorJitInfo_names_generated.h +++ b/src/coreclr/jit/ICorJitInfo_names_generated.h @@ -84,7 +84,6 @@ DEF_CLR_API(getBuiltinClass) DEF_CLR_API(getTypeForPrimitiveValueClass) DEF_CLR_API(getTypeForPrimitiveNumericClass) DEF_CLR_API(canCast) -DEF_CLR_API(areTypesEquivalent) DEF_CLR_API(compareTypesForCast) DEF_CLR_API(compareTypesForEquality) DEF_CLR_API(mergeClasses) diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index 26aa42f752260..b819fc12fbce1 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -793,16 +793,6 @@ bool WrapICorJitInfo::canCast( return temp; } -bool WrapICorJitInfo::areTypesEquivalent( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2) -{ - API_ENTER(areTypesEquivalent); - bool temp = wrapHnd->areTypesEquivalent(cls1, cls2); - API_LEAVE(areTypesEquivalent); - return temp; -} - TypeCompareState WrapICorJitInfo::compareTypesForCast( CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 8cd03b6e0d69c..7dc6532f28ca5 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -7757,6 +7757,14 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call) #endif } + if (call->IsHelperCall() && strstr(info.compClassName, "MyClass")) + { + if (eeGetHelperNum(call->gtCallMethHnd) == CORINFO_HELP_NEWSFAST) + { + call->AsCall()->gtCallMethHnd = eeFindHelper(CORINFO_HELP_NEWFAST_FROZEN); + } + } + if (((call->gtCallMoreFlags & (GTF_CALL_M_SPECIAL_INTRINSIC | GTF_CALL_M_LDVIRTFTN_INTERFACE)) == 0) && (call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_VIRTUAL_FUNC_PTR) #ifdef FEATURE_READYTORUN diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 9ad3bd7156dd7..6d3806f298768 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -2571,8 +2571,6 @@ private CorInfoType getTypeForPrimitiveNumericClass(CORINFO_CLASS_STRUCT_* cls) private bool canCast(CORINFO_CLASS_STRUCT_* child, CORINFO_CLASS_STRUCT_* parent) { throw new NotImplementedException("canCast"); } - private bool areTypesEquivalent(CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUCT_* cls2) - { throw new NotImplementedException("areTypesEquivalent"); } private TypeCompareState compareTypesForCast(CORINFO_CLASS_STRUCT_* fromClass, CORINFO_CLASS_STRUCT_* toClass) { diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 55c7d70b6618a..3c7f632ef8e7b 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -1195,21 +1195,6 @@ private static byte _canCast(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLA } } - [UnmanagedCallersOnly] - private static byte _areTypesEquivalent(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUCT_* cls2) - { - var _this = GetThis(thisHandle); - try - { - return _this.areTypesEquivalent(cls1, cls2) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - [UnmanagedCallersOnly] private static TypeCompareState _compareTypesForCast(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* fromClass, CORINFO_CLASS_STRUCT_* toClass) { @@ -2745,7 +2730,7 @@ private static uint _getJitFlags(IntPtr thisHandle, IntPtr* ppException, CORJIT_ private static IntPtr GetUnmanagedCallbacks() { - void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 185); + void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 184); callbacks[0] = (delegate* unmanaged)&_isIntrinsic; callbacks[1] = (delegate* unmanaged)&_getMethodAttribs; @@ -2827,111 +2812,110 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[77] = (delegate* unmanaged)&_getTypeForPrimitiveValueClass; callbacks[78] = (delegate* unmanaged)&_getTypeForPrimitiveNumericClass; callbacks[79] = (delegate* unmanaged)&_canCast; - callbacks[80] = (delegate* unmanaged)&_areTypesEquivalent; - callbacks[81] = (delegate* unmanaged)&_compareTypesForCast; - callbacks[82] = (delegate* unmanaged)&_compareTypesForEquality; - callbacks[83] = (delegate* unmanaged)&_mergeClasses; - callbacks[84] = (delegate* unmanaged)&_isMoreSpecificType; - callbacks[85] = (delegate* unmanaged)&_isEnum; - callbacks[86] = (delegate* unmanaged)&_getParentType; - callbacks[87] = (delegate* unmanaged)&_getChildType; - callbacks[88] = (delegate* unmanaged)&_satisfiesClassConstraints; - callbacks[89] = (delegate* unmanaged)&_isSDArray; - callbacks[90] = (delegate* unmanaged)&_getArrayRank; - callbacks[91] = (delegate* unmanaged)&_getArrayIntrinsicID; - callbacks[92] = (delegate* unmanaged)&_getArrayInitializationData; - callbacks[93] = (delegate* unmanaged)&_canAccessClass; - callbacks[94] = (delegate* unmanaged)&_printFieldName; - callbacks[95] = (delegate* unmanaged)&_getFieldClass; - callbacks[96] = (delegate* unmanaged)&_getFieldType; - callbacks[97] = (delegate* unmanaged)&_getFieldOffset; - callbacks[98] = (delegate* unmanaged)&_getFieldInfo; - callbacks[99] = (delegate* unmanaged)&_getThreadLocalFieldInfo; - callbacks[100] = (delegate* unmanaged)&_getThreadLocalStaticBlocksInfo; - callbacks[101] = (delegate* unmanaged)&_isFieldStatic; - callbacks[102] = (delegate* unmanaged)&_getArrayOrStringLength; - callbacks[103] = (delegate* unmanaged)&_getBoundaries; - callbacks[104] = (delegate* unmanaged)&_setBoundaries; - callbacks[105] = (delegate* unmanaged)&_getVars; - callbacks[106] = (delegate* unmanaged)&_setVars; - callbacks[107] = (delegate* unmanaged)&_reportRichMappings; - callbacks[108] = (delegate* unmanaged)&_allocateArray; - callbacks[109] = (delegate* unmanaged)&_freeArray; - callbacks[110] = (delegate* unmanaged)&_getArgNext; - callbacks[111] = (delegate* unmanaged)&_getArgType; - callbacks[112] = (delegate* unmanaged)&_getExactClasses; - callbacks[113] = (delegate* unmanaged)&_getArgClass; - callbacks[114] = (delegate* unmanaged)&_getHFAType; - callbacks[115] = (delegate* unmanaged)&_GetErrorHRESULT; - callbacks[116] = (delegate* unmanaged)&_GetErrorMessage; - callbacks[117] = (delegate* unmanaged)&_FilterException; - callbacks[118] = (delegate* unmanaged)&_ThrowExceptionForJitResult; - callbacks[119] = (delegate* unmanaged)&_ThrowExceptionForHelper; - callbacks[120] = (delegate* unmanaged)&_runWithErrorTrap; - callbacks[121] = (delegate* unmanaged)&_runWithSPMIErrorTrap; - callbacks[122] = (delegate* unmanaged)&_getEEInfo; - callbacks[123] = (delegate* unmanaged)&_getJitTimeLogFilename; - callbacks[124] = (delegate* unmanaged)&_getMethodDefFromMethod; - callbacks[125] = (delegate* unmanaged)&_printMethodName; - callbacks[126] = (delegate* unmanaged)&_getMethodNameFromMetadata; - callbacks[127] = (delegate* unmanaged)&_getMethodHash; - callbacks[128] = (delegate* unmanaged)&_findNameOfToken; - callbacks[129] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; - callbacks[130] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; - callbacks[131] = (delegate* unmanaged)&_getRISCV64PassStructInRegisterFlags; - callbacks[132] = (delegate* unmanaged)&_getThreadTLSIndex; - callbacks[133] = (delegate* unmanaged)&_getInlinedCallFrameVptr; - callbacks[134] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; - callbacks[135] = (delegate* unmanaged)&_getHelperFtn; - callbacks[136] = (delegate* unmanaged)&_getFunctionEntryPoint; - callbacks[137] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; - callbacks[138] = (delegate* unmanaged)&_getMethodSync; - callbacks[139] = (delegate* unmanaged)&_getLazyStringLiteralHelper; - callbacks[140] = (delegate* unmanaged)&_embedModuleHandle; - callbacks[141] = (delegate* unmanaged)&_embedClassHandle; - callbacks[142] = (delegate* unmanaged)&_embedMethodHandle; - callbacks[143] = (delegate* unmanaged)&_embedFieldHandle; - callbacks[144] = (delegate* unmanaged)&_embedGenericHandle; - callbacks[145] = (delegate* unmanaged)&_getLocationOfThisType; - callbacks[146] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; - callbacks[147] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; - callbacks[148] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; - callbacks[149] = (delegate* unmanaged)&_getJustMyCodeHandle; - callbacks[150] = (delegate* unmanaged)&_GetProfilingHandle; - callbacks[151] = (delegate* unmanaged)&_getCallInfo; - callbacks[152] = (delegate* unmanaged)&_canAccessFamily; - callbacks[153] = (delegate* unmanaged)&_isRIDClassDomainID; - callbacks[154] = (delegate* unmanaged)&_getClassDomainID; - callbacks[155] = (delegate* unmanaged)&_getStaticFieldContent; - callbacks[156] = (delegate* unmanaged)&_getObjectContent; - callbacks[157] = (delegate* unmanaged)&_getStaticFieldCurrentClass; - callbacks[158] = (delegate* unmanaged)&_getVarArgsHandle; - callbacks[159] = (delegate* unmanaged)&_canGetVarArgsHandle; - callbacks[160] = (delegate* unmanaged)&_constructStringLiteral; - callbacks[161] = (delegate* unmanaged)&_emptyStringLiteral; - callbacks[162] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; - callbacks[163] = (delegate* unmanaged)&_GetDelegateCtor; - callbacks[164] = (delegate* unmanaged)&_MethodCompileComplete; - callbacks[165] = (delegate* unmanaged)&_getTailCallHelpers; - callbacks[166] = (delegate* unmanaged)&_convertPInvokeCalliToCall; - callbacks[167] = (delegate* unmanaged)&_notifyInstructionSetUsage; - callbacks[168] = (delegate* unmanaged)&_updateEntryPointForTailCall; - callbacks[169] = (delegate* unmanaged)&_allocMem; - callbacks[170] = (delegate* unmanaged)&_reserveUnwindInfo; - callbacks[171] = (delegate* unmanaged)&_allocUnwindInfo; - callbacks[172] = (delegate* unmanaged)&_allocGCInfo; - callbacks[173] = (delegate* unmanaged)&_setEHcount; - callbacks[174] = (delegate* unmanaged)&_setEHinfo; - callbacks[175] = (delegate* unmanaged)&_logMsg; - callbacks[176] = (delegate* unmanaged)&_doAssert; - callbacks[177] = (delegate* unmanaged)&_reportFatalError; - callbacks[178] = (delegate* unmanaged)&_getPgoInstrumentationResults; - callbacks[179] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; - callbacks[180] = (delegate* unmanaged)&_recordCallSite; - callbacks[181] = (delegate* unmanaged)&_recordRelocation; - callbacks[182] = (delegate* unmanaged)&_getRelocTypeHint; - callbacks[183] = (delegate* unmanaged)&_getExpectedTargetArchitecture; - callbacks[184] = (delegate* unmanaged)&_getJitFlags; + callbacks[80] = (delegate* unmanaged)&_compareTypesForCast; + callbacks[81] = (delegate* unmanaged)&_compareTypesForEquality; + callbacks[82] = (delegate* unmanaged)&_mergeClasses; + callbacks[83] = (delegate* unmanaged)&_isMoreSpecificType; + callbacks[84] = (delegate* unmanaged)&_isEnum; + callbacks[85] = (delegate* unmanaged)&_getParentType; + callbacks[86] = (delegate* unmanaged)&_getChildType; + callbacks[87] = (delegate* unmanaged)&_satisfiesClassConstraints; + callbacks[88] = (delegate* unmanaged)&_isSDArray; + callbacks[89] = (delegate* unmanaged)&_getArrayRank; + callbacks[90] = (delegate* unmanaged)&_getArrayIntrinsicID; + callbacks[91] = (delegate* unmanaged)&_getArrayInitializationData; + callbacks[92] = (delegate* unmanaged)&_canAccessClass; + callbacks[93] = (delegate* unmanaged)&_printFieldName; + callbacks[94] = (delegate* unmanaged)&_getFieldClass; + callbacks[95] = (delegate* unmanaged)&_getFieldType; + callbacks[96] = (delegate* unmanaged)&_getFieldOffset; + callbacks[97] = (delegate* unmanaged)&_getFieldInfo; + callbacks[98] = (delegate* unmanaged)&_getThreadLocalFieldInfo; + callbacks[99] = (delegate* unmanaged)&_getThreadLocalStaticBlocksInfo; + callbacks[100] = (delegate* unmanaged)&_isFieldStatic; + callbacks[101] = (delegate* unmanaged)&_getArrayOrStringLength; + callbacks[102] = (delegate* unmanaged)&_getBoundaries; + callbacks[103] = (delegate* unmanaged)&_setBoundaries; + callbacks[104] = (delegate* unmanaged)&_getVars; + callbacks[105] = (delegate* unmanaged)&_setVars; + callbacks[106] = (delegate* unmanaged)&_reportRichMappings; + callbacks[107] = (delegate* unmanaged)&_allocateArray; + callbacks[108] = (delegate* unmanaged)&_freeArray; + callbacks[109] = (delegate* unmanaged)&_getArgNext; + callbacks[110] = (delegate* unmanaged)&_getArgType; + callbacks[111] = (delegate* unmanaged)&_getExactClasses; + callbacks[112] = (delegate* unmanaged)&_getArgClass; + callbacks[113] = (delegate* unmanaged)&_getHFAType; + callbacks[114] = (delegate* unmanaged)&_GetErrorHRESULT; + callbacks[115] = (delegate* unmanaged)&_GetErrorMessage; + callbacks[116] = (delegate* unmanaged)&_FilterException; + callbacks[117] = (delegate* unmanaged)&_ThrowExceptionForJitResult; + callbacks[118] = (delegate* unmanaged)&_ThrowExceptionForHelper; + callbacks[119] = (delegate* unmanaged)&_runWithErrorTrap; + callbacks[120] = (delegate* unmanaged)&_runWithSPMIErrorTrap; + callbacks[121] = (delegate* unmanaged)&_getEEInfo; + callbacks[122] = (delegate* unmanaged)&_getJitTimeLogFilename; + callbacks[123] = (delegate* unmanaged)&_getMethodDefFromMethod; + callbacks[124] = (delegate* unmanaged)&_printMethodName; + callbacks[125] = (delegate* unmanaged)&_getMethodNameFromMetadata; + callbacks[126] = (delegate* unmanaged)&_getMethodHash; + callbacks[127] = (delegate* unmanaged)&_findNameOfToken; + callbacks[128] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; + callbacks[129] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; + callbacks[130] = (delegate* unmanaged)&_getRISCV64PassStructInRegisterFlags; + callbacks[131] = (delegate* unmanaged)&_getThreadTLSIndex; + callbacks[132] = (delegate* unmanaged)&_getInlinedCallFrameVptr; + callbacks[133] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; + callbacks[134] = (delegate* unmanaged)&_getHelperFtn; + callbacks[135] = (delegate* unmanaged)&_getFunctionEntryPoint; + callbacks[136] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; + callbacks[137] = (delegate* unmanaged)&_getMethodSync; + callbacks[138] = (delegate* unmanaged)&_getLazyStringLiteralHelper; + callbacks[139] = (delegate* unmanaged)&_embedModuleHandle; + callbacks[140] = (delegate* unmanaged)&_embedClassHandle; + callbacks[141] = (delegate* unmanaged)&_embedMethodHandle; + callbacks[142] = (delegate* unmanaged)&_embedFieldHandle; + callbacks[143] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[144] = (delegate* unmanaged)&_getLocationOfThisType; + callbacks[145] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; + callbacks[146] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; + callbacks[147] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; + callbacks[148] = (delegate* unmanaged)&_getJustMyCodeHandle; + callbacks[149] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[150] = (delegate* unmanaged)&_getCallInfo; + callbacks[151] = (delegate* unmanaged)&_canAccessFamily; + callbacks[152] = (delegate* unmanaged)&_isRIDClassDomainID; + callbacks[153] = (delegate* unmanaged)&_getClassDomainID; + callbacks[154] = (delegate* unmanaged)&_getStaticFieldContent; + callbacks[155] = (delegate* unmanaged)&_getObjectContent; + callbacks[156] = (delegate* unmanaged)&_getStaticFieldCurrentClass; + callbacks[157] = (delegate* unmanaged)&_getVarArgsHandle; + callbacks[158] = (delegate* unmanaged)&_canGetVarArgsHandle; + callbacks[159] = (delegate* unmanaged)&_constructStringLiteral; + callbacks[160] = (delegate* unmanaged)&_emptyStringLiteral; + callbacks[161] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; + callbacks[162] = (delegate* unmanaged)&_GetDelegateCtor; + callbacks[163] = (delegate* unmanaged)&_MethodCompileComplete; + callbacks[164] = (delegate* unmanaged)&_getTailCallHelpers; + callbacks[165] = (delegate* unmanaged)&_convertPInvokeCalliToCall; + callbacks[166] = (delegate* unmanaged)&_notifyInstructionSetUsage; + callbacks[167] = (delegate* unmanaged)&_updateEntryPointForTailCall; + callbacks[168] = (delegate* unmanaged)&_allocMem; + callbacks[169] = (delegate* unmanaged)&_reserveUnwindInfo; + callbacks[170] = (delegate* unmanaged)&_allocUnwindInfo; + callbacks[171] = (delegate* unmanaged)&_allocGCInfo; + callbacks[172] = (delegate* unmanaged)&_setEHcount; + callbacks[173] = (delegate* unmanaged)&_setEHinfo; + callbacks[174] = (delegate* unmanaged)&_logMsg; + callbacks[175] = (delegate* unmanaged)&_doAssert; + callbacks[176] = (delegate* unmanaged)&_reportFatalError; + callbacks[177] = (delegate* unmanaged)&_getPgoInstrumentationResults; + callbacks[178] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; + callbacks[179] = (delegate* unmanaged)&_recordCallSite; + callbacks[180] = (delegate* unmanaged)&_recordRelocation; + callbacks[181] = (delegate* unmanaged)&_getRelocTypeHint; + callbacks[182] = (delegate* unmanaged)&_getExpectedTargetArchitecture; + callbacks[183] = (delegate* unmanaged)&_getJitFlags; return (IntPtr)callbacks; } diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 870d86df9136d..b9f8aa66f259e 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -239,7 +239,6 @@ FUNCTIONS CorInfoType getTypeForPrimitiveValueClass(CORINFO_CLASS_HANDLE cls) CorInfoType getTypeForPrimitiveNumericClass(CORINFO_CLASS_HANDLE cls) bool canCast(CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent) - bool areTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) TypeCompareState compareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) TypeCompareState compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) CORINFO_CLASS_HANDLE mergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) diff --git a/src/coreclr/tools/ILVerification/ILImporter.StackValue.cs b/src/coreclr/tools/ILVerification/ILImporter.StackValue.cs index 09b1890d91ea4..718f725aaf909 100644 --- a/src/coreclr/tools/ILVerification/ILImporter.StackValue.cs +++ b/src/coreclr/tools/ILVerification/ILImporter.StackValue.cs @@ -611,7 +611,8 @@ bool IsAssignable(StackValue src, StackValue dst) return FALSE; // Structures are compatible if they are equivalent - return jitInfo->areTypesEquivalent(child.m_cls, parent.m_cls); + // return jitInfo->areTypesEquivalent(child.m_cls, parent.m_cls); + return child.m_cls == parent.m_cls; } else if (parent.IsByRef()) { diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index 038abebbeceac..62db21d2232e2 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -91,7 +91,6 @@ struct JitInterfaceCallbacks CorInfoType (* getTypeForPrimitiveValueClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); CorInfoType (* getTypeForPrimitiveNumericClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); bool (* canCast)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent); - bool (* areTypesEquivalent)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); TypeCompareState (* compareTypesForCast)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass); TypeCompareState (* compareTypesForEquality)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); CORINFO_CLASS_HANDLE (* mergeClasses)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); @@ -992,16 +991,6 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } - virtual bool areTypesEquivalent( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2) -{ - CorInfoExceptionClass* pException = nullptr; - bool temp = _callbacks->areTypesEquivalent(_thisHandle, &pException, cls1, cls2); - if (pException != nullptr) throw pException; - return temp; -} - virtual TypeCompareState compareTypesForCast( CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h index 0a26a5d05774f..19a0600b3f582 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -18,7 +18,6 @@ LWM(AllocPgoInstrumentationBySchema, DWORDLONG, Agnostic_AllocPgoInstrumentationBySchema) LWM(GetPgoInstrumentationResults, DWORDLONG, Agnostic_GetPgoInstrumentationResults) -LWM(AreTypesEquivalent, DLDL, DWORD) LWM(AsCorInfoType, DWORDLONG, DWORD) LWM(CanAccessClass, Agnostic_CanAccessClassIn, Agnostic_CanAccessClassOut) LWM(CanAccessFamily, DLDL, DWORD) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 71d56a94935a7..469ff6f6d56d9 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -6196,37 +6196,6 @@ CORINFO_FIELD_HANDLE MethodContext::repEmbedFieldHandle(CORINFO_FIELD_HANDLE han return (CORINFO_FIELD_HANDLE)value.B; } -void MethodContext::recAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool result) -{ - if (AreTypesEquivalent == nullptr) - AreTypesEquivalent = new LightWeightMap(); - - DLDL key; - ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.A = CastHandle(cls1); - key.B = CastHandle(cls2); - - DWORD value = result ? 1 : 0; - AreTypesEquivalent->Add(key, value); - DEBUG_REC(dmpAreTypesEquivalent(key, value)); -} -void MethodContext::dmpAreTypesEquivalent(DLDL key, DWORD value) -{ - printf("AreTypesEquivalent NYI"); -} -bool MethodContext::repAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) -{ - DLDL key; - ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.A = CastHandle(cls1); - key.B = CastHandle(cls2); - - DWORD value = LookupByKeyOrMiss(AreTypesEquivalent, key, ": key %016" PRIX64 " %016" PRIX64 "", key.A, key.B); - - DEBUG_REP(dmpAreTypesEquivalent(key, value)); - return value != 0; -} - void MethodContext::recCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass, TypeCompareState result) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index d8935bb4f806b..53b3b02f745ea 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -777,10 +777,6 @@ class MethodContext void dmpEmbedFieldHandle(DWORDLONG key, DLDL value); CORINFO_FIELD_HANDLE repEmbedFieldHandle(CORINFO_FIELD_HANDLE handle, void** ppIndirection); - void recAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool result); - void dmpAreTypesEquivalent(DLDL key, DWORD value); - bool repAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); - void recCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass, TypeCompareState result); void dmpCompareTypesForCast(DLDL key, DWORD value); TypeCompareState repCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass); @@ -986,7 +982,7 @@ class MethodContext enum mcPackets { - Packet_AreTypesEquivalent = 1, + //Packet_AreTypesEquivalent = 1, Packet_AsCorInfoType = 2, Packet_CanAccessClass = 3, Packet_CanAccessFamily = 4, diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 6adbb6ac6f624..96249dde36c0d 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -898,15 +898,6 @@ bool interceptor_ICJI::canCast(CORINFO_CLASS_HANDLE child, // subtype (extends p return temp; } -// TRUE if cls1 and cls2 are considered equivalent types. -bool interceptor_ICJI::areTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) -{ - mc->cr->AddCall("areTypesEquivalent"); - bool temp = original_ICorJitInfo->areTypesEquivalent(cls1, cls2); - mc->recAreTypesEquivalent(cls1, cls2, temp); - return temp; -} - // See if a cast from fromClass to toClass will succeed, fail, or needs // to be resolved at runtime. TypeCompareState interceptor_ICJI::compareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp index e4aa9e7e69af8..58dc80abec8e1 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -650,14 +650,6 @@ bool interceptor_ICJI::canCast( return original_ICorJitInfo->canCast(child, parent); } -bool interceptor_ICJI::areTypesEquivalent( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2) -{ - mcs->AddCall("areTypesEquivalent"); - return original_ICorJitInfo->areTypesEquivalent(cls1, cls2); -} - TypeCompareState interceptor_ICJI::compareTypesForCast( CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp index d832d82b4f3b5..a9dced511ddce 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -570,13 +570,6 @@ bool interceptor_ICJI::canCast( return original_ICorJitInfo->canCast(child, parent); } -bool interceptor_ICJI::areTypesEquivalent( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2) -{ - return original_ICorJitInfo->areTypesEquivalent(cls1, cls2); -} - TypeCompareState interceptor_ICJI::compareTypesForCast( CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 3b25e9ad9f076..9915b4699eeeb 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -759,13 +759,6 @@ bool MyICJI::canCast(CORINFO_CLASS_HANDLE child, // subtype (extends parent) return jitInstance->mc->repCanCast(child, parent); } -// TRUE if cls1 and cls2 are considered equivalent types. -bool MyICJI::areTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) -{ - jitInstance->mc->cr->AddCall("areTypesEquivalent"); - return jitInstance->mc->repAreTypesEquivalent(cls1, cls2); -} - // See if a cast from fromClass to toClass will succeed, fail, or needs // to be resolved at runtime. TypeCompareState MyICJI::compareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 8ba73a5a8db1e..62a4400c7d86c 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -4205,29 +4205,6 @@ bool CEEInfo::canCast( return result; } -/*********************************************************************/ -// TRUE if cls1 and cls2 are considered equivalent types. -bool CEEInfo::areTypesEquivalent( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_PREEMPTIVE; - } CONTRACTL_END; - - bool result = false; - - JIT_TO_EE_TRANSITION(); - - result = !!((TypeHandle)cls1).IsEquivalentTo((TypeHandle)cls2); - - EE_TO_JIT_TRANSITION(); - - return result; -} - /*********************************************************************/ // See if a cast from fromClass to toClass will succeed, fail, or needs // to be resolved at runtime. From ef76d7176268301e7c45c7b2c1fbdcfe4d4b6640 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 1 May 2023 15:15:07 +0200 Subject: [PATCH 15/20] clean up --- src/coreclr/jit/morph.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 7dc6532f28ca5..8cd03b6e0d69c 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -7757,14 +7757,6 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call) #endif } - if (call->IsHelperCall() && strstr(info.compClassName, "MyClass")) - { - if (eeGetHelperNum(call->gtCallMethHnd) == CORINFO_HELP_NEWSFAST) - { - call->AsCall()->gtCallMethHnd = eeFindHelper(CORINFO_HELP_NEWFAST_FROZEN); - } - } - if (((call->gtCallMoreFlags & (GTF_CALL_M_SPECIAL_INTRINSIC | GTF_CALL_M_LDVIRTFTN_INTERFACE)) == 0) && (call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_VIRTUAL_FUNC_PTR) #ifdef FEATURE_READYTORUN From 0735f681e9355c0cca62febb681ea98b36980a9a Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 1 May 2023 23:38:42 +0200 Subject: [PATCH 16/20] Address feedback --- docs/design/coreclr/botr/readytorun-format.md | 4 +-- src/coreclr/inc/corinfo.h | 4 +-- src/coreclr/inc/jithelpers.h | 4 +-- src/coreclr/inc/readytorun.h | 4 +-- src/coreclr/inc/readytorunhelpers.h | 4 +-- src/coreclr/jit/gentree.cpp | 32 +++---------------- src/coreclr/jit/importer.cpp | 2 +- src/coreclr/jit/importercalls.cpp | 4 +-- src/coreclr/jit/utils.cpp | 4 +-- src/coreclr/jit/valuenum.cpp | 4 +-- .../Internal/Runtime/ReadyToRunConstants.cs | 4 +-- .../Common/JitInterface/CorInfoHelpFunc.cs | 4 +-- .../ILVerification/ILImporter.StackValue.cs | 2 +- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 8 ++--- .../ReadyToRunSignature.cs | 8 ++--- src/coreclr/vm/jithelpers.cpp | 4 +-- 16 files changed, 36 insertions(+), 60 deletions(-) diff --git a/docs/design/coreclr/botr/readytorun-format.md b/docs/design/coreclr/botr/readytorun-format.md index 81a9232e34e36..d88cd2a3982be 100644 --- a/docs/design/coreclr/botr/readytorun-format.md +++ b/docs/design/coreclr/botr/readytorun-format.md @@ -798,8 +798,8 @@ enum ReadyToRunHelper READYTORUN_HELPER_GenericNonGcTlsBase = 0x67, READYTORUN_HELPER_VirtualFuncPtr = 0x68, READYTORUN_HELPER_IsInstanceOfException = 0x69, - READYTORUN_HELPER_NewFrozenArray = 0x6A, - READYTORUN_HELPER_NewFrozenObject = 0x6B, + READYTORUN_HELPER_NewMyabeFrozenArray = 0x6A, + READYTORUN_HELPER_NewMaybeFrozenObject = 0x6B, // Long mul/div/shift ops READYTORUN_HELPER_LMul = 0xC0, diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 6e3900ab14606..de14ddc073635 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -404,7 +404,7 @@ enum CorInfoHelpFunc which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_NEWFAST, - CORINFO_HELP_NEWFAST_FROZEN, // allocator for objects on a frozen segment + CORINFO_HELP_NEWFAST_MAYBEFROZEN,// allocator for objects that *might* allocate them on a frozen segment CORINFO_HELP_NEWSFAST, // allocator for small, non-finalizer, non-array object CORINFO_HELP_NEWSFAST_FINALIZE, // allocator for small, finalizable, non-array object CORINFO_HELP_NEWSFAST_ALIGN8, // allocator for small, non-finalizer, non-array object, 8 byte aligned @@ -413,7 +413,7 @@ enum CorInfoHelpFunc CORINFO_HELP_NEW_MDARR,// multi-dim array helper for arrays Rank != 1 (with or without lower bounds - dimensions passed in as unmanaged array) CORINFO_HELP_NEW_MDARR_RARE,// rare multi-dim array helper (Rank == 1) CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creation - CORINFO_HELP_NEWARR_1_FROZEN, // helper for any one dimensional array creation on a frozen segment + CORINFO_HELP_NEWARR_1_ MAYBEFROZEN,// allocator for arrays that *might* allocate them on a frozen segment CORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arrays CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays CORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array start diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index 60602af5832e1..1d498c3589347 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -70,7 +70,7 @@ // Allocating a new object JITHELPER(CORINFO_HELP_NEWFAST, JIT_New, CORINFO_HELP_SIG_REG_ONLY) - JITHELPER(CORINFO_HELP_NEWFAST_FROZEN, JIT_NewFrozen,CORINFO_HELP_SIG_REG_ONLY) + JITHELPER(CORINFO_HELP_NEWFAST_MAYBEFROZEN, JIT_NewMaybeFrozen,CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_NEWSFAST, JIT_New, CORINFO_HELP_SIG_REG_ONLY) JITHELPER(CORINFO_HELP_NEWSFAST_FINALIZE, NULL, CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_NEWSFAST_ALIGN8, JIT_New, CORINFO_HELP_SIG_REG_ONLY) @@ -79,7 +79,7 @@ JITHELPER(CORINFO_HELP_NEW_MDARR, JIT_NewMDArr,CORINFO_HELP_SIG_4_STACK) JITHELPER(CORINFO_HELP_NEW_MDARR_RARE, JIT_NewMDArr,CORINFO_HELP_SIG_4_STACK) JITHELPER(CORINFO_HELP_NEWARR_1_DIRECT, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY) - JITHELPER(CORINFO_HELP_NEWARR_1_FROZEN, JIT_NewArr1Frozen,CORINFO_HELP_SIG_REG_ONLY) + JITHELPER(CORINFO_HELP_NEWARR_1_MAYBEFROZEN, JIT_NewArr1MaybeFrozen,CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_OBJ, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_VC, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_ALIGN8, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY) diff --git a/src/coreclr/inc/readytorun.h b/src/coreclr/inc/readytorun.h index a91a5718d0b0b..842807dbd4770 100644 --- a/src/coreclr/inc/readytorun.h +++ b/src/coreclr/inc/readytorun.h @@ -336,8 +336,8 @@ enum ReadyToRunHelper READYTORUN_HELPER_GenericNonGcTlsBase = 0x67, READYTORUN_HELPER_VirtualFuncPtr = 0x68, READYTORUN_HELPER_IsInstanceOfException = 0x69, - READYTORUN_HELPER_NewFrozenArray = 0x6A, - READYTORUN_HELPER_NewFrozenObject = 0x6B, + READYTORUN_HELPER_NewMyabeFrozenArray = 0x6A, + READYTORUN_HELPER_NewMaybeFrozenObject = 0x6B, // Long mul/div/shift ops READYTORUN_HELPER_LMul = 0xC0, diff --git a/src/coreclr/inc/readytorunhelpers.h b/src/coreclr/inc/readytorunhelpers.h index a13683ed630e2..ac5dcf5d59d94 100644 --- a/src/coreclr/inc/readytorunhelpers.h +++ b/src/coreclr/inc/readytorunhelpers.h @@ -55,8 +55,8 @@ HELPER(READYTORUN_HELPER_GenericNonGcTlsBase, CORINFO_HELP_GETGENERICS_NON HELPER(READYTORUN_HELPER_VirtualFuncPtr, CORINFO_HELP_VIRTUAL_FUNC_PTR, ) HELPER(READYTORUN_HELPER_IsInstanceOfException, CORINFO_HELP_ISINSTANCEOF_EXCEPTION, ) -HELPER(READYTORUN_HELPER_NewFrozenArray, CORINFO_HELP_NEWARR_1_FROZEN, ) -HELPER(READYTORUN_HELPER_NewFrozenObject, CORINFO_HELP_NEWFAST_FROZEN, ) +HELPER(READYTORUN_HELPER_NewMyabeFrozenArray, CORINFO_HELP_NEWARR_1_MAYBEFROZEN, ) +HELPER(READYTORUN_HELPER_NewMaybeFrozenObject, CORINFO_HELP_NEWFAST_MAYBEFROZEN, ) HELPER(READYTORUN_HELPER_LMul, CORINFO_HELP_LMUL, ) HELPER(READYTORUN_HELPER_LMulOfv, CORINFO_HELP_LMUL_OVF, ) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index c414914db0032..2550514165eeb 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -2158,38 +2158,14 @@ GenTree* Compiler::getArrayLengthFromAllocation(GenTree* tree DEBUGARG(BasicBloc CorInfoHelpFunc helper = eeGetHelperNum(call->gtCallMethHnd); switch (helper) { - case CORINFO_HELP_NEWARR_1_FROZEN: + case CORINFO_HELP_NEWARR_1_MAYBEFROZEN: case CORINFO_HELP_NEWARR_1_DIRECT: case CORINFO_HELP_NEWARR_1_OBJ: case CORINFO_HELP_NEWARR_1_VC: case CORINFO_HELP_NEWARR_1_ALIGN8: { - if (opts.IsReadyToRun() && helper == CORINFO_HELP_NEWARR_1_FROZEN) - { - // CORINFO_HELP_NEWARR_1_FROZEN is used in both JIT and R2R, - // for R2R take the same path as CORINFO_HELP_READYTORUN_NEWARR_1 - FALLTHROUGH; - } - else - { - // This is an array allocation site. Grab the array length node. - arrayLength = call->gtArgs.GetArgByIndex(1)->GetNode(); - break; - } - } - - case CORINFO_HELP_READYTORUN_NEWARR_1: - { - // On arm when compiling on certain platforms for ready to - // run, a handle will be inserted before the length. To - // handle this case, we will grab the last argument as - // that's always the length. See - // CallArgs::AddFinalArgsAndDetermineABIInfo for where the - // handle is inserted. - for (CallArg& arg : call->gtArgs.Args()) - { - arrayLength = arg.GetNode(); - } + // This is an array allocation site. Grab the array length node. + arrayLength = call->gtArgs.GetUserArgByIndex(1)->GetNode(); break; } @@ -18350,7 +18326,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetHelperCallClassHandle(GenTreeCall* call, boo } case CORINFO_HELP_NEWARR_1_DIRECT: - case CORINFO_HELP_NEWARR_1_FROZEN: + case CORINFO_HELP_NEWARR_1_MAYBEFROZEN: case CORINFO_HELP_NEWARR_1_OBJ: case CORINFO_HELP_NEWARR_1_VC: case CORINFO_HELP_NEWARR_1_ALIGN8: diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index fda4f7bd8a8e7..519dc9f97f063 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -9773,7 +9773,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) op1 = impTokenToHandle(&resolvedToken, nullptr, true /*mustRestoreHandle*/); } #endif - op1 = gtNewHelperCallNode(CORINFO_HELP_NEWARR_1_FROZEN, TYP_REF, op1, op2); + op1 = gtNewHelperCallNode(CORINFO_HELP_NEWARR_1_MAYBEFROZEN, TYP_REF, op1, op2); isFrozenAllocator = true; } } diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 826d3022ceac5..90fb4829eedc5 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -1872,7 +1872,7 @@ GenTree* Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig) bool isMDArray = false; if (newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_DIRECT) && - newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_FROZEN) && + newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_MAYBEFROZEN) && newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_OBJ) && newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_VC) && newArrayCall->AsCall()->gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_ALIGN8) @@ -2044,7 +2044,7 @@ GenTree* Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig) #ifdef FEATURE_READYTORUN if (newArrayCall->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_READYTORUN_NEWARR_1) || - newArrayCall->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_FROZEN)) + newArrayCall->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_MAYBEFROZEN)) { // Array length is 1st argument for readytorun helper arrayLengthNode = newArrayCall->AsCall()->gtArgs.GetArgByIndex(0)->GetNode(); diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index 918bce4b8cfb7..3e5ad119411e2 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -1318,7 +1318,7 @@ void HelperCallProperties::init() case CORINFO_HELP_NEWSFAST_ALIGN8: case CORINFO_HELP_NEWSFAST_ALIGN8_VC: case CORINFO_HELP_NEWFAST: - case CORINFO_HELP_NEWFAST_FROZEN: + case CORINFO_HELP_NEWFAST_MAYBEFROZEN: case CORINFO_HELP_NEWSFAST_FINALIZE: case CORINFO_HELP_NEWSFAST_ALIGN8_FINALIZE: case CORINFO_HELP_READYTORUN_NEW: @@ -1336,7 +1336,7 @@ void HelperCallProperties::init() case CORINFO_HELP_NEW_MDARR: case CORINFO_HELP_NEW_MDARR_RARE: case CORINFO_HELP_NEWARR_1_DIRECT: - case CORINFO_HELP_NEWARR_1_FROZEN: + case CORINFO_HELP_NEWARR_1_MAYBEFROZEN: case CORINFO_HELP_NEWARR_1_OBJ: case CORINFO_HELP_READYTORUN_NEWARR_1: diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 836dc1e5421ce..692f2d660073b 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -12187,11 +12187,11 @@ VNFunc Compiler::fgValueNumberJitHelperMethodVNFunc(CorInfoHelpFunc helpFunc) vnf = VNF_JitReadyToRunNewArr; break; - case CORINFO_HELP_NEWFAST_FROZEN: + case CORINFO_HELP_NEWFAST_MAYBEFROZEN: vnf = opts.IsReadyToRun() ? VNF_JitReadyToRunNew : VNF_JitNew; break; - case CORINFO_HELP_NEWARR_1_FROZEN: + case CORINFO_HELP_NEWARR_1_MAYBEFROZEN: vnf = opts.IsReadyToRun() ? VNF_JitReadyToRunNewArr : VNF_JitNewArr; break; diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs index 70aded6b3ed46..3b53c87fa8b14 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs @@ -256,8 +256,8 @@ public enum ReadyToRunHelper GenericNonGcTlsBase = 0x67, VirtualFuncPtr = 0x68, IsInstanceOfException = 0x69, - NewFrozenArray = 0x6A, - NewFrozenObject = 0x6B, + NewMyabeFrozenArray = 0x6A, + NewMaybeFrozenObject = 0x6B, // Long mul/div/shift ops LMul = 0xC0, diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs index b395c14233c32..33c007adac65c 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs @@ -47,7 +47,7 @@ public enum CorInfoHelpFunc which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_NEWFAST, - CORINFO_HELP_NEWFAST_FROZEN, // allocator for objects on a frozen segment + CORINFO_HELP_NEWFAST_MAYBEFROZEN,// allocator for objects that *might* allocate them on a frozen segment CORINFO_HELP_NEWSFAST, // allocator for small, non-finalizer, non-array object CORINFO_HELP_NEWSFAST_FINALIZE, // allocator for small, finalizable, non-array object CORINFO_HELP_NEWSFAST_ALIGN8, // allocator for small, non-finalizer, non-array object, 8 byte aligned @@ -56,7 +56,7 @@ which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_NEW_MDARR, // multi-dim array helper for arrays Rank != 1 (with or without lower bounds - dimensions passed in as unmanaged array) CORINFO_HELP_NEW_MDARR_RARE, // rare multi-dim array helper (Rank == 1) CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creation - CORINFO_HELP_NEWARR_1_FROZEN, // helper for any one dimensional array creation on a frozen segment + CORINFO_HELP_NEWARR_1_MAYBEFROZEN,// allocator for arrays that *might* allocate them on a frozen segment CORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arrays CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays CORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array start diff --git a/src/coreclr/tools/ILVerification/ILImporter.StackValue.cs b/src/coreclr/tools/ILVerification/ILImporter.StackValue.cs index 718f725aaf909..18c9736aeb3f5 100644 --- a/src/coreclr/tools/ILVerification/ILImporter.StackValue.cs +++ b/src/coreclr/tools/ILVerification/ILImporter.StackValue.cs @@ -612,7 +612,7 @@ bool IsAssignable(StackValue src, StackValue dst) // Structures are compatible if they are equivalent // return jitInfo->areTypesEquivalent(child.m_cls, parent.m_cls); - return child.m_cls == parent.m_cls; + return child.m_cls == parent.m_cls; } else if (parent.IsByRef()) { diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 351e996466cd9..382a2d6abd0a1 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -898,11 +898,11 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_DIRECT: id = ReadyToRunHelper.NewArray; break; - case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_FROZEN: - id = ReadyToRunHelper.NewFrozenArray; + case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_MAYBEFROZEN: + id = ReadyToRunHelper.NewMyabeFrozenArray; break; - case CorInfoHelpFunc.CORINFO_HELP_NEWFAST_FROZEN: - id = ReadyToRunHelper.NewFrozenObject; + case CorInfoHelpFunc.CORINFO_HELP_NEWFAST_MAYBEFROZEN: + id = ReadyToRunHelper.NewMaybeFrozenObject; break; case CorInfoHelpFunc.CORINFO_HELP_VIRTUAL_FUNC_PTR: id = ReadyToRunHelper.VirtualFuncPtr; diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs index f5bbd0bc3b1a3..454c12b135e6a 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs @@ -1774,12 +1774,12 @@ private void ParseHelper(StringBuilder builder) builder.Append("NEW_ARRAY"); break; - case ReadyToRunHelper.NewFrozenArray: - builder.Append("NEW_FROZEN_ARRAY"); + case ReadyToRunHelper.NewMyabeFrozenArray: + builder.Append("NEW_MAYBEFROZEN_ARRAY"); break; - case ReadyToRunHelper.NewFrozenObject: - builder.Append("NEW_FROZEN_OBJECT"); + case ReadyToRunHelper.NewMaybeFrozenObject: + builder.Append("NEW_MAYBEFROZEN_OBJECT"); break; case ReadyToRunHelper.CheckCastAny: diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index bd431b8af18a6..084281763c010 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -2405,7 +2405,7 @@ HCIMPL1(Object*, JIT_New, CORINFO_CLASS_HANDLE typeHnd_) HCIMPLEND /*************************************************************/ -HCIMPL1(Object*, JIT_NewFrozen, CORINFO_CLASS_HANDLE typeHnd_) +HCIMPL1(Object*, JIT_NewMaybeFrozen, CORINFO_CLASS_HANDLE typeHnd_) { FCALL_CONTRACT; @@ -2752,7 +2752,7 @@ HCIMPLEND /*************************************************************/ -HCIMPL2(Object*, JIT_NewArr1Frozen, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size) +HCIMPL2(Object*, JIT_NewArr1MaybeFrozen, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size) { FCALL_CONTRACT; From dc227c92e6f0b6e2a18327e462c720a042838719 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 1 May 2023 23:41:17 +0200 Subject: [PATCH 17/20] clean up --- src/coreclr/inc/corinfo.h | 2 +- src/coreclr/inc/corjitflags.h | 2 +- src/coreclr/jit/jitee.h | 2 +- src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index de14ddc073635..e45fe79a9a50d 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -413,7 +413,7 @@ enum CorInfoHelpFunc CORINFO_HELP_NEW_MDARR,// multi-dim array helper for arrays Rank != 1 (with or without lower bounds - dimensions passed in as unmanaged array) CORINFO_HELP_NEW_MDARR_RARE,// rare multi-dim array helper (Rank == 1) CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creation - CORINFO_HELP_NEWARR_1_ MAYBEFROZEN,// allocator for arrays that *might* allocate them on a frozen segment + CORINFO_HELP_NEWARR_1_MAYBEFROZEN,// allocator for arrays that *might* allocate them on a frozen segment CORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arrays CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays CORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array start diff --git a/src/coreclr/inc/corjitflags.h b/src/coreclr/inc/corjitflags.h index d9fffdbb97a22..4d511aa6f7470 100644 --- a/src/coreclr/inc/corjitflags.h +++ b/src/coreclr/inc/corjitflags.h @@ -55,7 +55,7 @@ class CORJIT_FLAGS CORJIT_FLAG_OSR = 13, // Generate alternate method for On Stack Replacement CORJIT_FLAG_ALT_JIT = 14, // JIT should consider itself an ALT_JIT - CORJIT_FLAG_FROZEN_ALLOC_ALLOWED = 15, // JIT is allowed to use *_FROZEN allocators + CORJIT_FLAG_FROZEN_ALLOC_ALLOWED = 15, // JIT is allowed to use *_MAYBEFROZEN allocators CORJIT_FLAG_UNUSED9 = 16, CORJIT_FLAG_UNUSED10 = 17, diff --git a/src/coreclr/jit/jitee.h b/src/coreclr/jit/jitee.h index 6088afaf8fa85..b55719f56e825 100644 --- a/src/coreclr/jit/jitee.h +++ b/src/coreclr/jit/jitee.h @@ -40,7 +40,7 @@ class JitFlags JIT_FLAG_OSR = 13, // Generate alternate version for On Stack Replacement JIT_FLAG_ALT_JIT = 14, // JIT should consider itself an ALT_JIT - JIT_FLAG_FROZEN_ALLOC_ALLOWED = 15, // JIT is allowed to use *_FROZEN allocators + JIT_FLAG_FROZEN_ALLOC_ALLOWED = 15, // JIT is allowed to use *_MAYBEFROZEN allocators JIT_FLAG_UNUSED9 = 16, #if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index 671148bb05281..cedbbda36b704 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -1411,7 +1411,7 @@ public enum CorJitFlag : uint CORJIT_FLAG_UNUSED6 = 12, CORJIT_FLAG_OSR = 13, // Generate alternate version for On Stack Replacement CORJIT_FLAG_ALT_JIT = 14, // JIT should consider itself an ALT_JIT - CORJIT_FLAG_FROZEN_ALLOC_ALLOWED = 15, // JIT is allowed to use *_FROZEN allocators + CORJIT_FLAG_FROZEN_ALLOC_ALLOWED = 15, // JIT is allowed to use *_MAYBEFROZEN allocators CORJIT_FLAG_UNUSED10 = 17, CORJIT_FLAG_MAKEFINALCODE = 18, // Use the final code generator, i.e., not the interpreter. CORJIT_FLAG_READYTORUN = 19, // Use version-resilient code generation From 7a35c84d668d474e3f847a8c8b80b3af3024e5ac Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 1 May 2023 23:58:12 +0200 Subject: [PATCH 18/20] formatting --- src/coreclr/inc/corinfo.h | 4 ++-- src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index e45fe79a9a50d..93f6768028449 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -404,7 +404,7 @@ enum CorInfoHelpFunc which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_NEWFAST, - CORINFO_HELP_NEWFAST_MAYBEFROZEN,// allocator for objects that *might* allocate them on a frozen segment + CORINFO_HELP_NEWFAST_MAYBEFROZEN, // allocator for objects that *might* allocate them on a frozen segment CORINFO_HELP_NEWSFAST, // allocator for small, non-finalizer, non-array object CORINFO_HELP_NEWSFAST_FINALIZE, // allocator for small, finalizable, non-array object CORINFO_HELP_NEWSFAST_ALIGN8, // allocator for small, non-finalizer, non-array object, 8 byte aligned @@ -413,7 +413,7 @@ enum CorInfoHelpFunc CORINFO_HELP_NEW_MDARR,// multi-dim array helper for arrays Rank != 1 (with or without lower bounds - dimensions passed in as unmanaged array) CORINFO_HELP_NEW_MDARR_RARE,// rare multi-dim array helper (Rank == 1) CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creation - CORINFO_HELP_NEWARR_1_MAYBEFROZEN,// allocator for arrays that *might* allocate them on a frozen segment + CORINFO_HELP_NEWARR_1_MAYBEFROZEN, // allocator for arrays that *might* allocate them on a frozen segment CORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arrays CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays CORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array start diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs index 33c007adac65c..06bc0f6363a09 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs @@ -47,7 +47,7 @@ public enum CorInfoHelpFunc which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_NEWFAST, - CORINFO_HELP_NEWFAST_MAYBEFROZEN,// allocator for objects that *might* allocate them on a frozen segment + CORINFO_HELP_NEWFAST_MAYBEFROZEN, // allocator for objects that *might* allocate them on a frozen segment CORINFO_HELP_NEWSFAST, // allocator for small, non-finalizer, non-array object CORINFO_HELP_NEWSFAST_FINALIZE, // allocator for small, finalizable, non-array object CORINFO_HELP_NEWSFAST_ALIGN8, // allocator for small, non-finalizer, non-array object, 8 byte aligned @@ -56,7 +56,7 @@ which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_NEW_MDARR, // multi-dim array helper for arrays Rank != 1 (with or without lower bounds - dimensions passed in as unmanaged array) CORINFO_HELP_NEW_MDARR_RARE, // rare multi-dim array helper (Rank == 1) CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creation - CORINFO_HELP_NEWARR_1_MAYBEFROZEN,// allocator for arrays that *might* allocate them on a frozen segment + CORINFO_HELP_NEWARR_1_MAYBEFROZEN, // allocator for arrays that *might* allocate them on a frozen segment CORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arrays CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays CORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array start From 7c00b675fc9d74d9b05980d3647d8e60a061641b Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Tue, 2 May 2023 00:01:41 +0200 Subject: [PATCH 19/20] Update src/coreclr/jit/importer.cpp Co-authored-by: Jakob Botsch Nielsen --- src/coreclr/jit/importer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 519dc9f97f063..7ae295cb1871e 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -9753,7 +9753,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) // Check next two opcodes (have to be STSFLD and RET) const BYTE* nextOpcode1 = codeAddr + sizeof(mdToken); const BYTE* nextOpcode2 = nextOpcode1 + sizeof(mdToken) + 1; - if (nextOpcode2 <= codeEndp && getU1LittleEndian(nextOpcode1) == CEE_STSFLD) + if ((nextOpcode2 < codeEndp) && (getU1LittleEndian(nextOpcode1) == CEE_STSFLD)) { if (getU1LittleEndian(nextOpcode2) == CEE_RET) { From a1266cf38ac4f69d4c141c81036ed4d12e20517e Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 2 May 2023 16:03:56 +0200 Subject: [PATCH 20/20] fix typo --- docs/design/coreclr/botr/readytorun-format.md | 2 +- src/coreclr/inc/readytorun.h | 2 +- src/coreclr/inc/readytorunhelpers.h | 2 +- .../tools/Common/Internal/Runtime/ReadyToRunConstants.cs | 2 +- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 2 +- .../aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/design/coreclr/botr/readytorun-format.md b/docs/design/coreclr/botr/readytorun-format.md index d88cd2a3982be..2c63997332e48 100644 --- a/docs/design/coreclr/botr/readytorun-format.md +++ b/docs/design/coreclr/botr/readytorun-format.md @@ -798,7 +798,7 @@ enum ReadyToRunHelper READYTORUN_HELPER_GenericNonGcTlsBase = 0x67, READYTORUN_HELPER_VirtualFuncPtr = 0x68, READYTORUN_HELPER_IsInstanceOfException = 0x69, - READYTORUN_HELPER_NewMyabeFrozenArray = 0x6A, + READYTORUN_HELPER_NewMaybeFrozenArray = 0x6A, READYTORUN_HELPER_NewMaybeFrozenObject = 0x6B, // Long mul/div/shift ops diff --git a/src/coreclr/inc/readytorun.h b/src/coreclr/inc/readytorun.h index 842807dbd4770..e138058b3666a 100644 --- a/src/coreclr/inc/readytorun.h +++ b/src/coreclr/inc/readytorun.h @@ -336,7 +336,7 @@ enum ReadyToRunHelper READYTORUN_HELPER_GenericNonGcTlsBase = 0x67, READYTORUN_HELPER_VirtualFuncPtr = 0x68, READYTORUN_HELPER_IsInstanceOfException = 0x69, - READYTORUN_HELPER_NewMyabeFrozenArray = 0x6A, + READYTORUN_HELPER_NewMaybeFrozenArray = 0x6A, READYTORUN_HELPER_NewMaybeFrozenObject = 0x6B, // Long mul/div/shift ops diff --git a/src/coreclr/inc/readytorunhelpers.h b/src/coreclr/inc/readytorunhelpers.h index ac5dcf5d59d94..8691f9b9cb8c0 100644 --- a/src/coreclr/inc/readytorunhelpers.h +++ b/src/coreclr/inc/readytorunhelpers.h @@ -55,7 +55,7 @@ HELPER(READYTORUN_HELPER_GenericNonGcTlsBase, CORINFO_HELP_GETGENERICS_NON HELPER(READYTORUN_HELPER_VirtualFuncPtr, CORINFO_HELP_VIRTUAL_FUNC_PTR, ) HELPER(READYTORUN_HELPER_IsInstanceOfException, CORINFO_HELP_ISINSTANCEOF_EXCEPTION, ) -HELPER(READYTORUN_HELPER_NewMyabeFrozenArray, CORINFO_HELP_NEWARR_1_MAYBEFROZEN, ) +HELPER(READYTORUN_HELPER_NewMaybeFrozenArray, CORINFO_HELP_NEWARR_1_MAYBEFROZEN, ) HELPER(READYTORUN_HELPER_NewMaybeFrozenObject, CORINFO_HELP_NEWFAST_MAYBEFROZEN, ) HELPER(READYTORUN_HELPER_LMul, CORINFO_HELP_LMUL, ) diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs index 3b53c87fa8b14..f46904cab3e09 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs @@ -256,7 +256,7 @@ public enum ReadyToRunHelper GenericNonGcTlsBase = 0x67, VirtualFuncPtr = 0x68, IsInstanceOfException = 0x69, - NewMyabeFrozenArray = 0x6A, + NewMaybeFrozenArray = 0x6A, NewMaybeFrozenObject = 0x6B, // Long mul/div/shift ops diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 382a2d6abd0a1..f73c55cd0dc67 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -899,7 +899,7 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) id = ReadyToRunHelper.NewArray; break; case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_MAYBEFROZEN: - id = ReadyToRunHelper.NewMyabeFrozenArray; + id = ReadyToRunHelper.NewMaybeFrozenArray; break; case CorInfoHelpFunc.CORINFO_HELP_NEWFAST_MAYBEFROZEN: id = ReadyToRunHelper.NewMaybeFrozenObject; diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs index 454c12b135e6a..8d325f467d600 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs @@ -1774,7 +1774,7 @@ private void ParseHelper(StringBuilder builder) builder.Append("NEW_ARRAY"); break; - case ReadyToRunHelper.NewMyabeFrozenArray: + case ReadyToRunHelper.NewMaybeFrozenArray: builder.Append("NEW_MAYBEFROZEN_ARRAY"); break;