From 9d0e0e26cd66e691c7a441801df622a4c35fa85a Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Mon, 22 Jan 2024 18:02:29 -0800 Subject: [PATCH 1/4] Convert isExactType check to JIT/EE interface call The approximation of isExactType from class flags had false positives (correctness) and false negatives issues. Converting it to JIT/EE interface method fixes them both. Fixes #97134 --- src/coreclr/inc/corinfo.h | 11 +- src/coreclr/inc/icorjitinfoimpl_generated.h | 3 + src/coreclr/inc/jiteeversionguid.h | 10 +- src/coreclr/jit/ICorJitInfo_names_generated.h | 1 + .../jit/ICorJitInfo_wrapper_generated.hpp | 9 + src/coreclr/jit/importer.cpp | 22 +- .../tools/Common/JitInterface/CorInfoImpl.cs | 40 +++- .../JitInterface/CorInfoImpl_generated.cs | 200 ++++++++++-------- .../tools/Common/JitInterface/CorInfoTypes.cs | 6 +- .../ThunkGenerator/ThunkInput.txt | 3 +- .../aot/jitinterface/jitinterface_generated.h | 10 + .../tools/superpmi/superpmi-shared/lwmlist.h | 1 + .../superpmi-shared/methodcontext.cpp | 22 ++ .../superpmi/superpmi-shared/methodcontext.h | 5 + .../superpmi-shared/spmidumphelper.cpp | 3 - .../superpmi-shim-collector/icorjitinfo.cpp | 9 + .../icorjitinfo_generated.cpp | 7 + .../icorjitinfo_generated.cpp | 6 + .../tools/superpmi/superpmi/icorjitinfo.cpp | 7 + src/coreclr/vm/jitinterface.cpp | 71 +++++-- 20 files changed, 296 insertions(+), 150 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index e957885418ca7b..c5b888d8c53b7d 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -824,13 +824,13 @@ enum CorInfoFlag { // CORINFO_FLG_UNUSED = 0x00000001, // CORINFO_FLG_UNUSED = 0x00000002, - CORINFO_FLG_PROTECTED = 0x00000004, +// CORINFO_FLG_UNUSED = 0x00000004, CORINFO_FLG_STATIC = 0x00000008, CORINFO_FLG_FINAL = 0x00000010, CORINFO_FLG_SYNCH = 0x00000020, CORINFO_FLG_VIRTUAL = 0x00000040, // CORINFO_FLG_UNUSED = 0x00000080, - CORINFO_FLG_NATIVE = 0x00000100, +// CORINFO_FLG_UNUSED = 0x00000100, CORINFO_FLG_INTRINSIC_TYPE = 0x00000200, // This type is marked by [Intrinsic] CORINFO_FLG_ABSTRACT = 0x00000400, @@ -865,7 +865,7 @@ enum CorInfoFlag CORINFO_FLG_DELEGATE = 0x02000000, // is this a subclass of delegate or multicast delegate ? CORINFO_FLG_INDEXABLE_FIELDS = 0x04000000, // struct fields may be accessed via indexing (used for inline arrays) CORINFO_FLG_BYREF_LIKE = 0x08000000, // it is byref-like value type - CORINFO_FLG_VARIANCE = 0x10000000, // MethodTable::HasVariance (sealed does *not* mean uncast-able) +// CORINFO_FLG_UNUSED = 0x10000000, CORINFO_FLG_BEFOREFIELDINIT = 0x20000000, // Additional flexibility for when to run .cctor (see code:#ClassConstructionFlags) CORINFO_FLG_GENERIC_TYPE_VARIABLE = 0x40000000, // This is really a handle for a variable type CORINFO_FLG_UNSAFE_VALUECLASS = 0x80000000, // Unsafe (C++'s /GS) value type @@ -2734,6 +2734,11 @@ class ICorStaticInfo CORINFO_CLASS_HANDLE cls2 ) = 0; + // Return if a class handle can only describe values of exactly one type. + virtual bool isExactType( + CORINFO_CLASS_HANDLE cls + ) = 0; + // Returns TypeCompareState::Must if cls is known to be an enum. // For enums with known exact type returns the underlying // type in underlyingType when the provided pointer is diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index af9e1b9662ba50..c450b72a894dc3 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -342,6 +342,9 @@ bool isMoreSpecificType( CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) override; +bool isExactType( + CORINFO_CLASS_HANDLE cls) override; + TypeCompareState isEnum( CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType) override; diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 6262bcdf852760..40820c5ab0535b 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 = { /* d7bbeb5a-aa7d-43ec-b29e-6f24dd3bca9c */ - 0xd7bbeb5a, - 0xaa7d, - 0x43ec, - {0xb2, 0x9e, 0x6f, 0x24, 0xdd, 0x3b, 0xca, 0x9c} +constexpr GUID JITEEVersionIdentifier = { /* fcf238f0-8f23-4843-b09d-7761a30a41f8 */ + 0xfcf238f0, + 0x8f23, + 0x4843, + {0xb0, 0x9d, 0x77, 0x61, 0xa3, 0x0a, 0x41, 0xf8} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/ICorJitInfo_names_generated.h b/src/coreclr/jit/ICorJitInfo_names_generated.h index 6e2e675b293db0..fc5df83c938bdc 100644 --- a/src/coreclr/jit/ICorJitInfo_names_generated.h +++ b/src/coreclr/jit/ICorJitInfo_names_generated.h @@ -85,6 +85,7 @@ DEF_CLR_API(canCast) DEF_CLR_API(compareTypesForCast) DEF_CLR_API(compareTypesForEquality) DEF_CLR_API(isMoreSpecificType) +DEF_CLR_API(isExactType) DEF_CLR_API(isEnum) DEF_CLR_API(getParentType) DEF_CLR_API(getChildType) diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index a0ddadf7a8221a..70b59e41542ec0 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -802,6 +802,15 @@ bool WrapICorJitInfo::isMoreSpecificType( return temp; } +bool WrapICorJitInfo::isExactType( + CORINFO_CLASS_HANDLE cls) +{ + API_ENTER(isExactType); + bool temp = wrapHnd->isExactType(cls); + API_LEAVE(isExactType); + return temp; +} + TypeCompareState WrapICorJitInfo::isEnum( CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 701e0463367b89..fa2574f5181d0b 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -13597,29 +13597,9 @@ methodPointerInfo* Compiler::impAllocateMethodPointerInfo(const CORINFO_RESOLVED // true if class is final and not subject to special casting from // variance or similar. // -// Note: -// We are conservative on arrays of primitive types here. - bool Compiler::impIsClassExact(CORINFO_CLASS_HANDLE classHnd) { - DWORD flags = info.compCompHnd->getClassAttribs(classHnd); - DWORD flagsMask = CORINFO_FLG_FINAL | CORINFO_FLG_VARIANCE | CORINFO_FLG_ARRAY; - - if ((flags & flagsMask) == CORINFO_FLG_FINAL) - { - return true; - } - if ((flags & flagsMask) == (CORINFO_FLG_FINAL | CORINFO_FLG_ARRAY)) - { - CORINFO_CLASS_HANDLE arrayElementHandle = nullptr; - CorInfoType type = info.compCompHnd->getChildType(classHnd, &arrayElementHandle); - - if ((type == CORINFO_TYPE_CLASS) || (type == CORINFO_TYPE_VALUECLASS)) - { - return impIsClassExact(arrayElementHandle); - } - } - return false; + return info.compCompHnd->isExactType(classHnd); } //------------------------------------------------------------------------ diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index cadc58a7014516..4032ba35993c83 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1062,8 +1062,6 @@ private uint getMethodAttribsInternal(MethodDesc method) { CorInfoFlag result = 0; - // CORINFO_FLG_PROTECTED - verification only - if (method.Signature.IsStatic) result |= CorInfoFlag.CORINFO_FLG_STATIC; @@ -2061,9 +2059,6 @@ private uint getClassAttribsInternal(TypeDesc type) if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) result |= CorInfoFlag.CORINFO_FLG_SHAREDINST; - if (type.HasVariance) - result |= CorInfoFlag.CORINFO_FLG_VARIANCE; - if (type.IsDelegate) result |= CorInfoFlag.CORINFO_FLG_DELEGATE; @@ -2914,6 +2909,41 @@ private bool isMoreSpecificType(CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUC return merged == type1; } + private bool isExactType(CORINFO_CLASS_STRUCT_* cls) + { + TypeDesc type = HandleToObject(cls); + + while (type.IsArray) + { + ArrayType arrayType = (ArrayType)type; + + // Single dimensional array with non-zero bounds may be SZ array. + if (arrayType.IsMdArray && arrayType.Rank == 1) + return false; + + type = arrayType.ElementType; + + // Arrays of primitives are interchangeable with arrays of enums of the same underlying type. + if (type.IsPrimitive || type.IsEnum) + return false; + } + + // Use conservative answer for pointers and custom types. + if (!type.IsDefType) + return false; + + // Use conservative answer for equivalent and variant types. + if (type.HasTypeEquivalence || type.HasVariance) + return false; + + // Valuetypes are invariant. This assumes that introducing type equivalence to an existing type + // is not compatible change. + if (type.IsValueType) + return true; + + return _compilation.IsEffectivelySealed(type); + } + private TypeCompareState isEnum(CORINFO_CLASS_STRUCT_* cls, CORINFO_CLASS_STRUCT_** underlyingType) { Debug.Assert(cls != null); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 0db8ace5e1d482..95f387cfbe2169 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -1210,6 +1210,21 @@ private static byte _isMoreSpecificType(IntPtr thisHandle, IntPtr* ppException, } } + [UnmanagedCallersOnly] + private static byte _isExactType(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) + { + var _this = GetThis(thisHandle); + try + { + return _this.isExactType(cls) ? (byte)1 : (byte)0; + } + catch (Exception ex) + { + *ppException = _this.AllocException(ex); + return default; + } + } + [UnmanagedCallersOnly] private static TypeCompareState _isEnum(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls, CORINFO_CLASS_STRUCT_** underlyingType) { @@ -2551,7 +2566,7 @@ private static uint _getJitFlags(IntPtr thisHandle, IntPtr* ppException, CORJIT_ private static IntPtr GetUnmanagedCallbacks() { - void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 172); + void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 173); callbacks[0] = (delegate* unmanaged)&_isIntrinsic; callbacks[1] = (delegate* unmanaged)&_notifyMethodInfoUsage; @@ -2634,97 +2649,98 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[78] = (delegate* unmanaged)&_compareTypesForCast; callbacks[79] = (delegate* unmanaged)&_compareTypesForEquality; callbacks[80] = (delegate* unmanaged)&_isMoreSpecificType; - callbacks[81] = (delegate* unmanaged)&_isEnum; - callbacks[82] = (delegate* unmanaged)&_getParentType; - callbacks[83] = (delegate* unmanaged)&_getChildType; - callbacks[84] = (delegate* unmanaged)&_isSDArray; - callbacks[85] = (delegate* unmanaged)&_getArrayRank; - callbacks[86] = (delegate* unmanaged)&_getArrayIntrinsicID; - callbacks[87] = (delegate* unmanaged)&_getArrayInitializationData; - callbacks[88] = (delegate* unmanaged)&_canAccessClass; - callbacks[89] = (delegate* unmanaged)&_printFieldName; - callbacks[90] = (delegate* unmanaged)&_getFieldClass; - callbacks[91] = (delegate* unmanaged)&_getFieldType; - callbacks[92] = (delegate* unmanaged)&_getFieldOffset; - callbacks[93] = (delegate* unmanaged)&_getFieldInfo; - callbacks[94] = (delegate* unmanaged)&_getThreadLocalFieldInfo; - callbacks[95] = (delegate* unmanaged)&_getThreadLocalStaticBlocksInfo; - callbacks[96] = (delegate* unmanaged)&_getThreadLocalStaticInfo_NativeAOT; - callbacks[97] = (delegate* unmanaged)&_isFieldStatic; - callbacks[98] = (delegate* unmanaged)&_getArrayOrStringLength; - callbacks[99] = (delegate* unmanaged)&_getBoundaries; - callbacks[100] = (delegate* unmanaged)&_setBoundaries; - callbacks[101] = (delegate* unmanaged)&_getVars; - callbacks[102] = (delegate* unmanaged)&_setVars; - callbacks[103] = (delegate* unmanaged)&_reportRichMappings; - callbacks[104] = (delegate* unmanaged)&_allocateArray; - callbacks[105] = (delegate* unmanaged)&_freeArray; - callbacks[106] = (delegate* unmanaged)&_getArgNext; - callbacks[107] = (delegate* unmanaged)&_getArgType; - callbacks[108] = (delegate* unmanaged)&_getExactClasses; - callbacks[109] = (delegate* unmanaged)&_getArgClass; - callbacks[110] = (delegate* unmanaged)&_getHFAType; - callbacks[111] = (delegate* unmanaged)&_runWithErrorTrap; - callbacks[112] = (delegate* unmanaged)&_runWithSPMIErrorTrap; - callbacks[113] = (delegate* unmanaged)&_getEEInfo; - callbacks[114] = (delegate* unmanaged)&_getJitTimeLogFilename; - callbacks[115] = (delegate* unmanaged)&_getMethodDefFromMethod; - callbacks[116] = (delegate* unmanaged)&_printMethodName; - callbacks[117] = (delegate* unmanaged)&_getMethodNameFromMetadata; - callbacks[118] = (delegate* unmanaged)&_getMethodHash; - callbacks[119] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; - callbacks[120] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; - callbacks[121] = (delegate* unmanaged)&_getRISCV64PassStructInRegisterFlags; - callbacks[122] = (delegate* unmanaged)&_getThreadTLSIndex; - callbacks[123] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; - callbacks[124] = (delegate* unmanaged)&_getHelperFtn; - callbacks[125] = (delegate* unmanaged)&_getFunctionEntryPoint; - callbacks[126] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; - callbacks[127] = (delegate* unmanaged)&_getMethodSync; - callbacks[128] = (delegate* unmanaged)&_getLazyStringLiteralHelper; - callbacks[129] = (delegate* unmanaged)&_embedModuleHandle; - callbacks[130] = (delegate* unmanaged)&_embedClassHandle; - callbacks[131] = (delegate* unmanaged)&_embedMethodHandle; - callbacks[132] = (delegate* unmanaged)&_embedFieldHandle; - callbacks[133] = (delegate* unmanaged)&_embedGenericHandle; - callbacks[134] = (delegate* unmanaged)&_getLocationOfThisType; - callbacks[135] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; - callbacks[136] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; - callbacks[137] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; - callbacks[138] = (delegate* unmanaged)&_getJustMyCodeHandle; - callbacks[139] = (delegate* unmanaged)&_GetProfilingHandle; - callbacks[140] = (delegate* unmanaged)&_getCallInfo; - callbacks[141] = (delegate* unmanaged)&_getClassDomainID; - callbacks[142] = (delegate* unmanaged)&_getStaticFieldContent; - callbacks[143] = (delegate* unmanaged)&_getObjectContent; - callbacks[144] = (delegate* unmanaged)&_getStaticFieldCurrentClass; - callbacks[145] = (delegate* unmanaged)&_getVarArgsHandle; - callbacks[146] = (delegate* unmanaged)&_canGetVarArgsHandle; - callbacks[147] = (delegate* unmanaged)&_constructStringLiteral; - callbacks[148] = (delegate* unmanaged)&_emptyStringLiteral; - callbacks[149] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; - callbacks[150] = (delegate* unmanaged)&_GetDelegateCtor; - callbacks[151] = (delegate* unmanaged)&_MethodCompileComplete; - callbacks[152] = (delegate* unmanaged)&_getTailCallHelpers; - callbacks[153] = (delegate* unmanaged)&_convertPInvokeCalliToCall; - callbacks[154] = (delegate* unmanaged)&_notifyInstructionSetUsage; - callbacks[155] = (delegate* unmanaged)&_updateEntryPointForTailCall; - callbacks[156] = (delegate* unmanaged)&_allocMem; - callbacks[157] = (delegate* unmanaged)&_reserveUnwindInfo; - callbacks[158] = (delegate* unmanaged)&_allocUnwindInfo; - callbacks[159] = (delegate* unmanaged)&_allocGCInfo; - callbacks[160] = (delegate* unmanaged)&_setEHcount; - callbacks[161] = (delegate* unmanaged)&_setEHinfo; - callbacks[162] = (delegate* unmanaged)&_logMsg; - callbacks[163] = (delegate* unmanaged)&_doAssert; - callbacks[164] = (delegate* unmanaged)&_reportFatalError; - callbacks[165] = (delegate* unmanaged)&_getPgoInstrumentationResults; - callbacks[166] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; - callbacks[167] = (delegate* unmanaged)&_recordCallSite; - callbacks[168] = (delegate* unmanaged)&_recordRelocation; - callbacks[169] = (delegate* unmanaged)&_getRelocTypeHint; - callbacks[170] = (delegate* unmanaged)&_getExpectedTargetArchitecture; - callbacks[171] = (delegate* unmanaged)&_getJitFlags; + callbacks[81] = (delegate* unmanaged)&_isExactType; + callbacks[82] = (delegate* unmanaged)&_isEnum; + callbacks[83] = (delegate* unmanaged)&_getParentType; + callbacks[84] = (delegate* unmanaged)&_getChildType; + callbacks[85] = (delegate* unmanaged)&_isSDArray; + callbacks[86] = (delegate* unmanaged)&_getArrayRank; + callbacks[87] = (delegate* unmanaged)&_getArrayIntrinsicID; + callbacks[88] = (delegate* unmanaged)&_getArrayInitializationData; + callbacks[89] = (delegate* unmanaged)&_canAccessClass; + callbacks[90] = (delegate* unmanaged)&_printFieldName; + callbacks[91] = (delegate* unmanaged)&_getFieldClass; + callbacks[92] = (delegate* unmanaged)&_getFieldType; + callbacks[93] = (delegate* unmanaged)&_getFieldOffset; + callbacks[94] = (delegate* unmanaged)&_getFieldInfo; + callbacks[95] = (delegate* unmanaged)&_getThreadLocalFieldInfo; + callbacks[96] = (delegate* unmanaged)&_getThreadLocalStaticBlocksInfo; + callbacks[97] = (delegate* unmanaged)&_getThreadLocalStaticInfo_NativeAOT; + callbacks[98] = (delegate* unmanaged)&_isFieldStatic; + callbacks[99] = (delegate* unmanaged)&_getArrayOrStringLength; + callbacks[100] = (delegate* unmanaged)&_getBoundaries; + callbacks[101] = (delegate* unmanaged)&_setBoundaries; + callbacks[102] = (delegate* unmanaged)&_getVars; + callbacks[103] = (delegate* unmanaged)&_setVars; + callbacks[104] = (delegate* unmanaged)&_reportRichMappings; + callbacks[105] = (delegate* unmanaged)&_allocateArray; + callbacks[106] = (delegate* unmanaged)&_freeArray; + callbacks[107] = (delegate* unmanaged)&_getArgNext; + callbacks[108] = (delegate* unmanaged)&_getArgType; + callbacks[109] = (delegate* unmanaged)&_getExactClasses; + callbacks[110] = (delegate* unmanaged)&_getArgClass; + callbacks[111] = (delegate* unmanaged)&_getHFAType; + callbacks[112] = (delegate* unmanaged)&_runWithErrorTrap; + callbacks[113] = (delegate* unmanaged)&_runWithSPMIErrorTrap; + callbacks[114] = (delegate* unmanaged)&_getEEInfo; + callbacks[115] = (delegate* unmanaged)&_getJitTimeLogFilename; + callbacks[116] = (delegate* unmanaged)&_getMethodDefFromMethod; + callbacks[117] = (delegate* unmanaged)&_printMethodName; + callbacks[118] = (delegate* unmanaged)&_getMethodNameFromMetadata; + callbacks[119] = (delegate* unmanaged)&_getMethodHash; + callbacks[120] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; + callbacks[121] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; + callbacks[122] = (delegate* unmanaged)&_getRISCV64PassStructInRegisterFlags; + callbacks[123] = (delegate* unmanaged)&_getThreadTLSIndex; + callbacks[124] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; + callbacks[125] = (delegate* unmanaged)&_getHelperFtn; + callbacks[126] = (delegate* unmanaged)&_getFunctionEntryPoint; + callbacks[127] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; + callbacks[128] = (delegate* unmanaged)&_getMethodSync; + callbacks[129] = (delegate* unmanaged)&_getLazyStringLiteralHelper; + callbacks[130] = (delegate* unmanaged)&_embedModuleHandle; + callbacks[131] = (delegate* unmanaged)&_embedClassHandle; + callbacks[132] = (delegate* unmanaged)&_embedMethodHandle; + callbacks[133] = (delegate* unmanaged)&_embedFieldHandle; + callbacks[134] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[135] = (delegate* unmanaged)&_getLocationOfThisType; + callbacks[136] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; + callbacks[137] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; + callbacks[138] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; + callbacks[139] = (delegate* unmanaged)&_getJustMyCodeHandle; + callbacks[140] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[141] = (delegate* unmanaged)&_getCallInfo; + callbacks[142] = (delegate* unmanaged)&_getClassDomainID; + callbacks[143] = (delegate* unmanaged)&_getStaticFieldContent; + callbacks[144] = (delegate* unmanaged)&_getObjectContent; + callbacks[145] = (delegate* unmanaged)&_getStaticFieldCurrentClass; + callbacks[146] = (delegate* unmanaged)&_getVarArgsHandle; + callbacks[147] = (delegate* unmanaged)&_canGetVarArgsHandle; + callbacks[148] = (delegate* unmanaged)&_constructStringLiteral; + callbacks[149] = (delegate* unmanaged)&_emptyStringLiteral; + callbacks[150] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; + callbacks[151] = (delegate* unmanaged)&_GetDelegateCtor; + callbacks[152] = (delegate* unmanaged)&_MethodCompileComplete; + callbacks[153] = (delegate* unmanaged)&_getTailCallHelpers; + callbacks[154] = (delegate* unmanaged)&_convertPInvokeCalliToCall; + callbacks[155] = (delegate* unmanaged)&_notifyInstructionSetUsage; + callbacks[156] = (delegate* unmanaged)&_updateEntryPointForTailCall; + callbacks[157] = (delegate* unmanaged)&_allocMem; + callbacks[158] = (delegate* unmanaged)&_reserveUnwindInfo; + callbacks[159] = (delegate* unmanaged)&_allocUnwindInfo; + callbacks[160] = (delegate* unmanaged)&_allocGCInfo; + callbacks[161] = (delegate* unmanaged)&_setEHcount; + callbacks[162] = (delegate* unmanaged)&_setEHinfo; + callbacks[163] = (delegate* unmanaged)&_logMsg; + callbacks[164] = (delegate* unmanaged)&_doAssert; + callbacks[165] = (delegate* unmanaged)&_reportFatalError; + callbacks[166] = (delegate* unmanaged)&_getPgoInstrumentationResults; + callbacks[167] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; + callbacks[168] = (delegate* unmanaged)&_recordCallSite; + callbacks[169] = (delegate* unmanaged)&_recordRelocation; + callbacks[170] = (delegate* unmanaged)&_getRelocTypeHint; + callbacks[171] = (delegate* unmanaged)&_getExpectedTargetArchitecture; + callbacks[172] = (delegate* unmanaged)&_getJitFlags; return (IntPtr)callbacks; } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index 394a7a4bbac91b..24fefb249bc56a 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -564,13 +564,13 @@ public enum CorInfoFlag : uint { // CORINFO_FLG_UNUSED = 0x00000001, // CORINFO_FLG_UNUSED = 0x00000002, - CORINFO_FLG_PROTECTED = 0x00000004, + // CORINFO_FLG_UNUSED = 0x00000004, CORINFO_FLG_STATIC = 0x00000008, CORINFO_FLG_FINAL = 0x00000010, CORINFO_FLG_SYNCH = 0x00000020, CORINFO_FLG_VIRTUAL = 0x00000040, // CORINFO_FLG_UNUSED = 0x00000080, - CORINFO_FLG_NATIVE = 0x00000100, + // CORINFO_FLG_UNUSED = 0x00000100, CORINFO_FLG_INTRINSIC_TYPE = 0x00000200, // This type is marked by [Intrinsic] CORINFO_FLG_ABSTRACT = 0x00000400, @@ -603,7 +603,7 @@ public enum CorInfoFlag : uint CORINFO_FLG_DELEGATE = 0x02000000, // is this a subclass of delegate or multicast delegate ? CORINFO_FLG_INDEXABLE_FIELDS = 0x04000000, // struct fields may be accessed via indexing (used for inline arrays) CORINFO_FLG_BYREF_LIKE = 0x08000000, // it is byref-like value type - CORINFO_FLG_VARIANCE = 0x10000000, // MethodTable::HasVariance (sealed does *not* mean uncast-able) + // CORINFO_FLG_UNUSED = 0x10000000, CORINFO_FLG_BEFOREFIELDINIT = 0x20000000, // Additional flexibility for when to run .cctor (see code:#ClassConstructionFlags) CORINFO_FLG_GENERIC_TYPE_VARIABLE = 0x40000000, // This is really a handle for a variable type CORINFO_FLG_UNSAFE_VALUECLASS = 0x80000000, // Unsafe (C++'s /GS) value type diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 1fb0f057d915ba..f6182050ba950b 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -242,7 +242,8 @@ FUNCTIONS bool canCast(CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent) TypeCompareState compareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) TypeCompareState compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) - bool isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) + bool isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) + bool isExactType(CORINFO_CLASS_HANDLE cls) TypeCompareState isEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType) CORINFO_CLASS_HANDLE getParentType(CORINFO_CLASS_HANDLE cls) CorInfoType getChildType(CORINFO_CLASS_HANDLE clsHnd, CORINFO_CLASS_HANDLE* clsRet) diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index 995f312eafd07e..9109c6afb51789 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -92,6 +92,7 @@ struct JitInterfaceCallbacks 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); bool (* isMoreSpecificType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); + bool (* isExactType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); TypeCompareState (* isEnum)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType); CORINFO_CLASS_HANDLE (* getParentType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); CorInfoType (* getChildType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE clsHnd, CORINFO_CLASS_HANDLE* clsRet); @@ -988,6 +989,15 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } + virtual bool isExactType( + CORINFO_CLASS_HANDLE cls) +{ + CorInfoExceptionClass* pException = nullptr; + bool temp = _callbacks->isExactType(_thisHandle, &pException, cls); + if (pException != nullptr) throw pException; + return temp; +} + virtual TypeCompareState isEnum( CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h index 7cdb9d5ebede61..cabbc5f1938df6 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -157,6 +157,7 @@ LWM(PrintFieldName, DWORDLONG, Agnostic_PrintResult) LWM(PrintMethodName, DWORDLONG, Agnostic_PrintResult) LWM(IsValueClass, DWORDLONG, DWORD) LWM(IsMoreSpecificType, DLDL, DWORD) +LWM(IsExactType, DWORDLONG, DWORD) LWM(IsEnum, DWORDLONG, DLD) LWM(PInvokeMarshalingRequired, MethodOrSigInfoValue, DWORD) LWM(ResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, ResolveTokenValue) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index efb7b7e97461ae..33fe1a1bf208c6 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -5915,6 +5915,28 @@ bool MethodContext::repIsMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLA return value != 0; } +void MethodContext::recIsExactType(CORINFO_CLASS_HANDLE cls, bool result) +{ + if (IsExactType == nullptr) + IsExactType = new LightWeightMap(); + + DWORDLONG key = CastHandle(cls); + DWORD value = result ? 1 : 0; + IsExactType->Add(key, value); + DEBUG_REC(dmpIsExactType(key, value)); +} +void MethodContext::dmpIsExactType(DWORDLONG key, DWORD value) +{ + printf("IsExactType key cls-%016" PRIX64 ", value res-%u", key, value); +} +bool MethodContext::repIsExactType(CORINFO_CLASS_HANDLE cls) +{ + DWORDLONG key = CastHandle(cls); + DWORD value = LookupByKeyOrMiss(IsExactType, key, ": key %016" PRIX64 "", key); + DEBUG_REP(dmpIsExactType(key, value)); + return value != 0; +} + void MethodContext::recIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE underlyingType, TypeCompareState result) { if (IsEnum == nullptr) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index ccf42bc0feb0b2..885710187412d3 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -719,6 +719,10 @@ class MethodContext void dmpIsMoreSpecificType(DLDL key, DWORD value); bool repIsMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); + void recIsExactType(CORINFO_CLASS_HANDLE cls, bool result); + void dmpIsExactType(DWORDLONG key, DWORD value); + bool repIsExactType(CORINFO_CLASS_HANDLE cls); + void recIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE underlyingType, TypeCompareState result); void dmpIsEnum(DWORDLONG key, DLD value); TypeCompareState repIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType); @@ -1148,6 +1152,7 @@ enum mcPackets Packet_GetTypeLayout = 212, Packet_HaveSameMethodDefinition = 213, Packet_NotifyMethodInfoUsage = 214, + Packet_IsExactType = 215, }; void SetDebugDumpVariables(); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/spmidumphelper.cpp b/src/coreclr/tools/superpmi/superpmi-shared/spmidumphelper.cpp index 083b80c03286c0..725f52cbcc74ca 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/spmidumphelper.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/spmidumphelper.cpp @@ -158,12 +158,10 @@ std::string SpmiDumpHelper::DumpCorInfoFlag(CorInfoFlag flags) #define AddFlag(__name)\ if (flags & __name) { s += std::string(" ") + std::string(#__name); flags = (CorInfoFlag)((DWORD)flags & ~(DWORD)__name); } - AddFlag(CORINFO_FLG_PROTECTED); AddFlag(CORINFO_FLG_STATIC); AddFlag(CORINFO_FLG_FINAL); AddFlag(CORINFO_FLG_SYNCH); AddFlag(CORINFO_FLG_VIRTUAL); - AddFlag(CORINFO_FLG_NATIVE); AddFlag(CORINFO_FLG_INTRINSIC_TYPE); AddFlag(CORINFO_FLG_ABSTRACT); AddFlag(CORINFO_FLG_EnC); @@ -186,7 +184,6 @@ std::string SpmiDumpHelper::DumpCorInfoFlag(CorInfoFlag flags) AddFlag(CORINFO_FLG_CONTAINS_GC_PTR); AddFlag(CORINFO_FLG_DELEGATE); AddFlag(CORINFO_FLG_BYREF_LIKE); - AddFlag(CORINFO_FLG_VARIANCE); AddFlag(CORINFO_FLG_BEFOREFIELDINIT); AddFlag(CORINFO_FLG_GENERIC_TYPE_VARIABLE); AddFlag(CORINFO_FLG_UNSAFE_VALUECLASS); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 067adc0e8808f3..4730e457cdd098 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -914,6 +914,15 @@ bool interceptor_ICJI::isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLA return temp; } +// Return if a class handle can only describe values of exactly one type. +bool interceptor_ICJI::isExactType(CORINFO_CLASS_HANDLE cls) +{ + mc->cr->AddCall("isExactType"); + bool temp = original_ICorJitInfo->isExactType(cls); + mc->recIsExactType(cls, temp); + return temp; +} + // Returns TypeCompareState::Must if cls is known to be an enum. // For enums with known exact type returns the underlying // type in underlyingType when the provided pointer is 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 9fcc2a17f8a452..5330a0bcca01d3 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -657,6 +657,13 @@ bool interceptor_ICJI::isMoreSpecificType( return original_ICorJitInfo->isMoreSpecificType(cls1, cls2); } +bool interceptor_ICJI::isExactType( + CORINFO_CLASS_HANDLE cls) +{ + mcs->AddCall("isExactType"); + return original_ICorJitInfo->isExactType(cls); +} + TypeCompareState interceptor_ICJI::isEnum( CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType) 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 394746a7a200a1..fab31aeae54ff5 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -576,6 +576,12 @@ bool interceptor_ICJI::isMoreSpecificType( return original_ICorJitInfo->isMoreSpecificType(cls1, cls2); } +bool interceptor_ICJI::isExactType( + CORINFO_CLASS_HANDLE cls) +{ + return original_ICorJitInfo->isExactType(cls); +} + TypeCompareState interceptor_ICJI::isEnum( CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType) diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 89c7f4e6273779..ea83c769655831 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -764,6 +764,13 @@ bool MyICJI::isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE return jitInstance->mc->repIsMoreSpecificType(cls1, cls2); } +// Return if a class handle can only describe values of exactly one type. +bool MyICJI::isExactType(CORINFO_CLASS_HANDLE cls) +{ + jitInstance->mc->cr->AddCall("isExactType"); + return jitInstance->mc->repIsExactType(cls); +} + // Returns TypeCompareState::Must if cls is known to be an enum. // For enums with known exact type returns the underlying // type in underlyingType when the provided pointer is diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index c6b6af6fc6e1a2..a731372f8309bf 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -3914,9 +3914,6 @@ uint32_t CEEInfo::getClassAttribsInternal (CORINFO_CLASS_HANDLE clsHnd) if (VMClsHnd.IsCanonicalSubtype()) ret |= CORINFO_FLG_SHAREDINST; - if (pMT->HasVariance()) - ret |= CORINFO_FLG_VARIANCE; - if (pMT->ContainsPointers() || pMT == g_TypedReferenceMT) ret |= CORINFO_FLG_CONTAINS_GC_PTR; @@ -4544,18 +4541,9 @@ TypeCompareState CEEInfo::compareTypesForEquality( /*********************************************************************/ -static BOOL isMoreSpecificTypeHelper( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2) +static BOOL isMoreSpecificTypeHelper(TypeHandle hnd1, TypeHandle hnd2) { - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_PREEMPTIVE; - } CONTRACTL_END; - - TypeHandle hnd1 = TypeHandle(cls1); - TypeHandle hnd2 = TypeHandle(cls2); + STANDARD_VM_CONTRACT; // We can't really reason about equivalent types. Just // assume the new type is not more specific. @@ -4599,7 +4587,58 @@ bool CEEInfo::isMoreSpecificType( JIT_TO_EE_TRANSITION(); - result = isMoreSpecificTypeHelper(cls1, cls2); + result = isMoreSpecificTypeHelper(TypeHandle(cls1), TypeHandle(cls2)); + + EE_TO_JIT_TRANSITION(); + return result; +} + +static bool isExactTypeHelper(TypeHandle th) +{ + STANDARD_VM_CONTRACT; + + while (th.IsArray()) + { + MethodTable* pMT = th.AsMethodTable(); + + // Single dimensional array with non-zero bounds may be SZ array. + if (pMT->IsMultiDimArray() && pMT->GetRank() == 1) + return false; + + th = pMT->GetArrayElementTypeHandle(); + + // Arrays of primitives are interchangeable with arrays of enums of the same underlying type. + if (CorTypeInfo::IsPrimitiveType(th.GetVerifierCorElementType())) + return false; + } + + // Use conservative answer for pointers. + if (th.IsTypeDesc()) + return false; + + MethodTable* pMT = th.AsMethodTable(); + + // Use conservative answer for equivalent and variant types. + if (pMT->HasTypeEquivalence() || pMT->HasVariance()) + return false; + + return pMT->IsSealed(); +} + +// Return if a class handle can only describe values of exactly one type. +bool CEEInfo::isExactType(CORINFO_CLASS_HANDLE cls) +{ + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } CONTRACTL_END; + + bool result = false; + + JIT_TO_EE_TRANSITION(); + + result = isExactTypeHelper(TypeHandle(cls)); EE_TO_JIT_TRANSITION(); return result; @@ -6614,8 +6653,6 @@ DWORD CEEInfo::getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftn) DWORD attribs = pMD->GetAttrs(); - if (IsMdFamily(attribs)) - result |= CORINFO_FLG_PROTECTED; if (IsMdStatic(attribs)) result |= CORINFO_FLG_STATIC; if (pMD->IsSynchronized()) From 96ff42352638f40be151e819d152a4f2b1ab125c Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Tue, 23 Jan 2024 14:45:59 -0800 Subject: [PATCH 2/4] Add test --- .../baseservices/typeequivalence/contracts/Types.cs | 6 ++++++ src/tests/baseservices/typeequivalence/impl/Impls.cs | 5 +++++ src/tests/baseservices/typeequivalence/simple/Simple.cs | 9 +++++++++ 3 files changed, 20 insertions(+) diff --git a/src/tests/baseservices/typeequivalence/contracts/Types.cs b/src/tests/baseservices/typeequivalence/contracts/Types.cs index a9fc0270a1bdd0..539e83318fc506 100644 --- a/src/tests/baseservices/typeequivalence/contracts/Types.cs +++ b/src/tests/baseservices/typeequivalence/contracts/Types.cs @@ -61,6 +61,12 @@ public interface ISparseType int MultiplyBy20(int a); } + [Guid("BD752276-52DF-4CD1-8C62-49D202F15C8D")] + public struct TestValueType + { + public int Field; + } + // // Below types are used in type punning tests and shouldn't be used anywhere else. // diff --git a/src/tests/baseservices/typeequivalence/impl/Impls.cs b/src/tests/baseservices/typeequivalence/impl/Impls.cs index dd0ce12eec9baa..f3472ed1076300 100644 --- a/src/tests/baseservices/typeequivalence/impl/Impls.cs +++ b/src/tests/baseservices/typeequivalence/impl/Impls.cs @@ -130,3 +130,8 @@ public static int GetField_3(OnlyLoadOnce_3 s) return s.Field; } } + +public static class TestsExactTypeOptimizationsHelper +{ + public static TestValueType[] s_arrayInstance; +} diff --git a/src/tests/baseservices/typeequivalence/simple/Simple.cs b/src/tests/baseservices/typeequivalence/simple/Simple.cs index a5bc9a0984780a..afe4ba62777680 100644 --- a/src/tests/baseservices/typeequivalence/simple/Simple.cs +++ b/src/tests/baseservices/typeequivalence/simple/Simple.cs @@ -7,6 +7,7 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Threading; using Xunit; using TypeEquivalenceTypes; @@ -285,6 +286,13 @@ private static void TestCastsOptimizations() EquivalentValueType inst = (EquivalentValueType)otherEquivalentValueTypeInstance; } + private static void TestsExactTypeOptimizations() + { + TestsExactTypeOptimizationsHelper.s_arrayInstance = new TestValueType[1]; + Thread.Yield(); + Assert.True(typeof(TestValueType[]) == TestsExactTypeOptimizationsHelper.s_arrayInstance.GetType()); + } + [Fact] public static int TestEntryPoint() { @@ -305,6 +313,7 @@ public static int TestEntryPoint() TestTypeEquivalenceWithTypePunning(); TestLoadingValueTypesWithMethod(); TestCastsOptimizations(); + TestsExactTypeOptimizations(); } catch (Exception e) { From a6bce5b49526d00a36eaa9b667c10fa3ecc2aef5 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Tue, 23 Jan 2024 15:23:44 -0800 Subject: [PATCH 3/4] FB --- src/coreclr/inc/corinfo.h | 2 +- src/coreclr/jit/compiler.h | 1 - src/coreclr/jit/gentree.cpp | 4 +-- src/coreclr/jit/importer.cpp | 26 ++++--------------- .../superpmi-shim-collector/icorjitinfo.cpp | 2 +- .../tools/superpmi/superpmi/icorjitinfo.cpp | 2 +- src/coreclr/vm/jitinterface.cpp | 2 +- 7 files changed, 11 insertions(+), 28 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index c5b888d8c53b7d..465ba3a403ee8e 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2734,7 +2734,7 @@ class ICorStaticInfo CORINFO_CLASS_HANDLE cls2 ) = 0; - // Return if a class handle can only describe values of exactly one type. + // Returns true if a class handle can only describe values of exactly one type. virtual bool isExactType( CORINFO_CLASS_HANDLE cls ) = 0; diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 3ce1dc0dd51860..b8f482f27ae05e 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -4907,7 +4907,6 @@ class Compiler bool impIsImplicitTailCallCandidate( OPCODE curOpcode, const BYTE* codeAddrOfNextOpcode, const BYTE* codeEnd, int prefixFlags, bool isRecursive); - bool impIsClassExact(CORINFO_CLASS_HANDLE classHnd); bool impCanSkipCovariantStoreCheck(GenTree* value, GenTree* array); methodPointerInfo* impAllocateMethodPointerInfo(const CORINFO_RESOLVED_TOKEN& token, mdToken tokenConstrained); diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index ac88ed8abae8b9..d62a85bd9b59a6 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -14034,7 +14034,7 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree) // if both classes are "final" (e.g. System.String[]) we can replace the comparison // with `true/false` + null check. - if ((objCls != NO_CLASS_HANDLE) && (pIsExact || impIsClassExact(objCls))) + if ((objCls != NO_CLASS_HANDLE) && (pIsExact || info.compCompHnd->isExactType(objCls))) { TypeCompareState tcs = info.compCompHnd->compareTypesForEquality(objCls, clsHnd); if (tcs != TypeCompareState::May) @@ -18585,7 +18585,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b } else { - *pIsExact = impIsClassExact(objClass); + *pIsExact = info.compCompHnd->isExactType(objClass); } } diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index fa2574f5181d0b..9c63d5482a122f 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -5344,7 +5344,7 @@ GenTree* Compiler::impOptimizeCastClassOrIsInst(GenTree* op1, CORINFO_RESOLVED_T // See if we can sharpen exactness by looking for final classes if (!isExact) { - isExact = impIsClassExact(fromClass); + isExact = info.compCompHnd->isExactType(fromClass); } // Cast to exact type will fail. Handle case where we have @@ -5411,7 +5411,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree( // Optimistically assume the jit should expand this as an inline test bool shouldExpandInline = true; - bool isClassExact = impIsClassExact(pResolvedToken->hClass); + bool isClassExact = info.compCompHnd->isExactType(pResolvedToken->hClass); // ECMA-335 III.4.3: If typeTok is a nullable type, Nullable, it is interpreted as "boxed" T // We can convert constant-ish tokens of nullable to its underlying type. @@ -5481,7 +5481,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree( if (this->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && ((helper == CORINFO_HELP_ISINSTANCEOFINTERFACE) || (helper == CORINFO_HELP_CHKCASTINTERFACE)) && (info.compCompHnd->getExactClasses(pResolvedToken->hClass, 1, &actualImplCls) == 1) && - (actualImplCls != NO_CLASS_HANDLE) && impIsClassExact(actualImplCls)) + (actualImplCls != NO_CLASS_HANDLE) && info.compCompHnd->isExactType(actualImplCls)) { // if an interface has a single implementation on NativeAOT where we won't load new types, // we can assume that our object is always of that implementation's type, e.g.: @@ -6834,7 +6834,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) } if (opts.OptimizationEnabled() && (gtGetArrayElementClassHandle(impStackTop(1).val) == ldelemClsHnd) && - impIsClassExact(ldelemClsHnd)) + info.compCompHnd->isExactType(ldelemClsHnd)) { JITDUMP("\nldelema of T[] with T exact: skipping covariant check\n"); goto ARR_LD; @@ -13586,22 +13586,6 @@ methodPointerInfo* Compiler::impAllocateMethodPointerInfo(const CORINFO_RESOLVED return memory; } -//------------------------------------------------------------------------ -// impIsClassExact: check if a class handle can only describe values -// of exactly one class. -// -// Arguments: -// classHnd - handle for class in question -// -// Returns: -// true if class is final and not subject to special casting from -// variance or similar. -// -bool Compiler::impIsClassExact(CORINFO_CLASS_HANDLE classHnd) -{ - return info.compCompHnd->isExactType(classHnd); -} - //------------------------------------------------------------------------ // impCanSkipCovariantStoreCheck: see if storing a ref type value to an array // can skip the array store covariance check. @@ -13685,7 +13669,7 @@ bool Compiler::impCanSkipCovariantStoreCheck(GenTree* value, GenTree* array) return true; } - const bool arrayTypeIsSealed = impIsClassExact(arrayElementHandle); + const bool arrayTypeIsSealed = info.compCompHnd->isExactType(arrayElementHandle); if ((!arrayIsExact && !arrayTypeIsSealed) || (arrayElementHandle == NO_CLASS_HANDLE)) { diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 4730e457cdd098..996752e6e243c1 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -914,7 +914,7 @@ bool interceptor_ICJI::isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLA return temp; } -// Return if a class handle can only describe values of exactly one type. +// Returns true if a class handle can only describe values of exactly one type. bool interceptor_ICJI::isExactType(CORINFO_CLASS_HANDLE cls) { mc->cr->AddCall("isExactType"); diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index ea83c769655831..16e02586a00cc3 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -764,7 +764,7 @@ bool MyICJI::isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE return jitInstance->mc->repIsMoreSpecificType(cls1, cls2); } -// Return if a class handle can only describe values of exactly one type. +// Returns true if a class handle can only describe values of exactly one type. bool MyICJI::isExactType(CORINFO_CLASS_HANDLE cls) { jitInstance->mc->cr->AddCall("isExactType"); diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index a731372f8309bf..c39bc5630e5fb2 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -4625,7 +4625,7 @@ static bool isExactTypeHelper(TypeHandle th) return pMT->IsSealed(); } -// Return if a class handle can only describe values of exactly one type. +// Returns true if a class handle can only describe values of exactly one type. bool CEEInfo::isExactType(CORINFO_CLASS_HANDLE cls) { CONTRACTL { From 95a47fd5625ab76121ef552a2e6b4a5db1fd19b0 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Tue, 23 Jan 2024 17:07:13 -0800 Subject: [PATCH 4/4] Delete canInlineTypeCheck JIT/EE interface method All implementations return the same constant. Unlikely to be needed again. --- src/coreclr/inc/corinfo.h | 18 -- src/coreclr/inc/icorjitinfoimpl_generated.h | 4 - src/coreclr/inc/jiteeversionguid.h | 10 +- src/coreclr/jit/ICorJitInfo_names_generated.h | 1 - .../jit/ICorJitInfo_wrapper_generated.hpp | 10 - src/coreclr/jit/gentree.cpp | 29 -- .../tools/Common/JitInterface/CorInfoImpl.cs | 9 - .../JitInterface/CorInfoImpl_generated.cs | 282 +++++++++--------- .../ThunkGenerator/ThunkInput.txt | 1 - .../aot/jitinterface/jitinterface_generated.h | 11 - .../tools/superpmi/superpmi-shared/lwmlist.h | 1 - .../superpmi-shared/methodcontext.cpp | 35 --- .../superpmi/superpmi-shared/methodcontext.h | 8 +- .../superpmi-shim-collector/icorjitinfo.cpp | 12 - .../icorjitinfo_generated.cpp | 8 - .../icorjitinfo_generated.cpp | 7 - .../tools/superpmi/superpmi/icorjitinfo.cpp | 9 - src/coreclr/vm/jitinterface.cpp | 12 - 18 files changed, 139 insertions(+), 328 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 465ba3a403ee8e..347b832e309cb7 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -980,19 +980,6 @@ enum CorInfoInline INLINE_NEVER = -2, // This method should never be inlined, regardless of context }; -enum CorInfoInlineTypeCheck -{ - CORINFO_INLINE_TYPECHECK_NONE = 0x00000000, // It's not okay to compare type's vtable with a native type handle - CORINFO_INLINE_TYPECHECK_PASS = 0x00000001, // It's okay to compare type's vtable with a native type handle - CORINFO_INLINE_TYPECHECK_USE_HELPER = 0x00000002, // Use a specialized helper to compare type's vtable with native type handle -}; - -enum CorInfoInlineTypeCheckSource -{ - CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE = 0x00000000, // Type handle comes from the vtable - CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN = 0x00000001, // Type handle comes from an ldtoken -}; - // If you add more values here, keep it in sync with TailCallTypeMap in ..\vm\ClrEtwAll.man // and the string enum in CEEInfo::reportTailCallDecision in ..\vm\JITInterface.cpp enum CorInfoTailCall @@ -2400,11 +2387,6 @@ class ICorStaticInfo // Quick check whether the type is a value class. Returns the same value as getClassAttribs(cls) & CORINFO_FLG_VALUECLASS, except faster. virtual bool isValueClass(CORINFO_CLASS_HANDLE cls) = 0; - // Decides how the JIT should do the optimization to inline the check for - // GetTypeFromHandle(handle) == obj.GetType() (for CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE) - // GetTypeFromHandle(X) == GetTypeFromHandle(Y) (for CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN) - virtual CorInfoInlineTypeCheck canInlineTypeCheck(CORINFO_CLASS_HANDLE cls, CorInfoInlineTypeCheckSource source) = 0; - // return flags (a bitfield of CorInfoFlags values) virtual uint32_t getClassAttribs ( CORINFO_CLASS_HANDLE cls diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index c450b72a894dc3..8dd993f5b47829 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -189,10 +189,6 @@ size_t printClassName( bool isValueClass( CORINFO_CLASS_HANDLE cls) override; -CorInfoInlineTypeCheck canInlineTypeCheck( - CORINFO_CLASS_HANDLE cls, - CorInfoInlineTypeCheckSource source) override; - uint32_t getClassAttribs( CORINFO_CLASS_HANDLE cls) override; diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 40820c5ab0535b..5a65c21188ac87 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 = { /* fcf238f0-8f23-4843-b09d-7761a30a41f8 */ - 0xfcf238f0, - 0x8f23, - 0x4843, - {0xb0, 0x9d, 0x77, 0x61, 0xa3, 0x0a, 0x41, 0xf8} +constexpr GUID JITEEVersionIdentifier = { /* cb73cac8-302a-48ba-9e65-55c21d4209ac */ + 0xcb73cac8, + 0x302a, + 0x48ba, + {0x9e, 0x65, 0x55, 0xc2, 0x1d, 0x42, 0x09, 0xac} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/ICorJitInfo_names_generated.h b/src/coreclr/jit/ICorJitInfo_names_generated.h index fc5df83c938bdc..5fe1f716d474b8 100644 --- a/src/coreclr/jit/ICorJitInfo_names_generated.h +++ b/src/coreclr/jit/ICorJitInfo_names_generated.h @@ -44,7 +44,6 @@ DEF_CLR_API(getClassNameFromMetadata) DEF_CLR_API(getTypeInstantiationArgument) DEF_CLR_API(printClassName) DEF_CLR_API(isValueClass) -DEF_CLR_API(canInlineTypeCheck) DEF_CLR_API(getClassAttribs) DEF_CLR_API(getClassModule) DEF_CLR_API(getModuleAssembly) diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index 70b59e41542ec0..cae9b5d7b39e59 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -406,16 +406,6 @@ bool WrapICorJitInfo::isValueClass( return temp; } -CorInfoInlineTypeCheck WrapICorJitInfo::canInlineTypeCheck( - CORINFO_CLASS_HANDLE cls, - CorInfoInlineTypeCheckSource source) -{ - API_ENTER(canInlineTypeCheck); - CorInfoInlineTypeCheck temp = wrapHnd->canInlineTypeCheck(cls, source); - API_LEAVE(canInlineTypeCheck); - return temp; -} - uint32_t WrapICorJitInfo::getClassAttribs( CORINFO_CLASS_HANDLE cls) { diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index d62a85bd9b59a6..d4e464a38c722b 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -13912,22 +13912,6 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree) (cls2Hnd == NO_CLASS_HANDLE) ? " cls2" : ""); } - // We can't answer the equality comparison definitively at jit - // time, but can still simplify the comparison. - // - // Find out how we can compare the two handles. - // NOTE: We're potentially passing NO_CLASS_HANDLE, but the runtime knows what to do with it here. - CorInfoInlineTypeCheck inliningKind = - info.compCompHnd->canInlineTypeCheck(cls1Hnd, CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN); - - // If the first type needs helper, check the other type: it might be okay with a simple compare. - if (inliningKind == CORINFO_INLINE_TYPECHECK_USE_HELPER) - { - inliningKind = info.compCompHnd->canInlineTypeCheck(cls2Hnd, CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN); - } - - assert(inliningKind == CORINFO_INLINE_TYPECHECK_PASS); - GenTree* compare = gtNewOperNode(oper, TYP_INT, op1ClassFromHandle, op2ClassFromHandle); // Drop any now-irrelevant flags @@ -13964,9 +13948,6 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree) arg2 = gtNewMethodTableLookup(arg2); - assert(info.compCompHnd->canInlineTypeCheck(nullptr, CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE) == - CORINFO_INLINE_TYPECHECK_PASS); - GenTree* compare = gtNewOperNode(oper, TYP_INT, arg1, arg2); // Drop any now-irrelevant flags @@ -13999,15 +13980,6 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree) return tree; } - // Ask the VM if this type can be equality tested by a simple method - // table comparison. - CorInfoInlineTypeCheck typeCheckInliningResult = - info.compCompHnd->canInlineTypeCheck(clsHnd, CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE); - if (typeCheckInliningResult == CORINFO_INLINE_TYPECHECK_NONE) - { - return tree; - } - // We're good to go. JITDUMP("Optimizing compare of obj.GetType()" " and type-from-handle to compare method table pointer\n"); @@ -14065,7 +14037,6 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree) GenTree* const objMT = gtNewMethodTableLookup(objOp); // Compare the two method tables - assert(typeCheckInliningResult == CORINFO_INLINE_TYPECHECK_PASS); GenTree* const compare = gtNewOperNode(oper, TYP_INT, objMT, knownMT); // Drop any now irrelevant flags diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 4032ba35993c83..d26463264e9ebc 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -2008,15 +2008,6 @@ private bool isValueClass(CORINFO_CLASS_STRUCT_* cls) return HandleToObject(cls).IsValueType; } -#pragma warning disable CA1822 // Mark members as static - private CorInfoInlineTypeCheck canInlineTypeCheck(CORINFO_CLASS_STRUCT_* cls, CorInfoInlineTypeCheckSource source) -#pragma warning restore CA1822 // Mark members as static - { - // TODO: when we support multiple modules at runtime, this will need to do more work - // NOTE: cls can be null - return CorInfoInlineTypeCheck.CORINFO_INLINE_TYPECHECK_PASS; - } - private uint getClassAttribs(CORINFO_CLASS_STRUCT_* cls) { TypeDesc type = HandleToObject(cls); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 95f387cfbe2169..13844628bb8639 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -598,21 +598,6 @@ private static byte _isValueClass(IntPtr thisHandle, IntPtr* ppException, CORINF } } - [UnmanagedCallersOnly] - private static CorInfoInlineTypeCheck _canInlineTypeCheck(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls, CorInfoInlineTypeCheckSource source) - { - var _this = GetThis(thisHandle); - try - { - return _this.canInlineTypeCheck(cls, source); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - [UnmanagedCallersOnly] private static uint _getClassAttribs(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) { @@ -2566,7 +2551,7 @@ private static uint _getJitFlags(IntPtr thisHandle, IntPtr* ppException, CORJIT_ private static IntPtr GetUnmanagedCallbacks() { - void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 173); + void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 172); callbacks[0] = (delegate* unmanaged)&_isIntrinsic; callbacks[1] = (delegate* unmanaged)&_notifyMethodInfoUsage; @@ -2608,139 +2593,138 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[37] = (delegate* unmanaged)&_getTypeInstantiationArgument; callbacks[38] = (delegate* unmanaged)&_printClassName; callbacks[39] = (delegate* unmanaged)&_isValueClass; - callbacks[40] = (delegate* unmanaged)&_canInlineTypeCheck; - callbacks[41] = (delegate* unmanaged)&_getClassAttribs; - callbacks[42] = (delegate* unmanaged)&_getClassModule; - callbacks[43] = (delegate* unmanaged)&_getModuleAssembly; - callbacks[44] = (delegate* unmanaged)&_getAssemblyName; - callbacks[45] = (delegate* unmanaged)&_LongLifetimeMalloc; - callbacks[46] = (delegate* unmanaged)&_LongLifetimeFree; - callbacks[47] = (delegate* unmanaged)&_getClassModuleIdForStatics; - callbacks[48] = (delegate* unmanaged)&_getIsClassInitedFlagAddress; - callbacks[49] = (delegate* unmanaged)&_getStaticBaseAddress; - callbacks[50] = (delegate* unmanaged)&_getClassSize; - callbacks[51] = (delegate* unmanaged)&_getHeapClassSize; - callbacks[52] = (delegate* unmanaged)&_canAllocateOnStack; - callbacks[53] = (delegate* unmanaged)&_getClassAlignmentRequirement; - callbacks[54] = (delegate* unmanaged)&_getClassGClayout; - callbacks[55] = (delegate* unmanaged)&_getClassNumInstanceFields; - callbacks[56] = (delegate* unmanaged)&_getFieldInClass; - callbacks[57] = (delegate* unmanaged)&_getTypeLayout; - callbacks[58] = (delegate* unmanaged)&_checkMethodModifier; - callbacks[59] = (delegate* unmanaged)&_getNewHelper; - callbacks[60] = (delegate* unmanaged)&_getNewArrHelper; - callbacks[61] = (delegate* unmanaged)&_getCastingHelper; - callbacks[62] = (delegate* unmanaged)&_getSharedCCtorHelper; - callbacks[63] = (delegate* unmanaged)&_getTypeForBox; - callbacks[64] = (delegate* unmanaged)&_getBoxHelper; - callbacks[65] = (delegate* unmanaged)&_getUnBoxHelper; - callbacks[66] = (delegate* unmanaged)&_getRuntimeTypePointer; - callbacks[67] = (delegate* unmanaged)&_isObjectImmutable; - callbacks[68] = (delegate* unmanaged)&_getStringChar; - callbacks[69] = (delegate* unmanaged)&_getObjectType; - callbacks[70] = (delegate* unmanaged)&_getReadyToRunHelper; - callbacks[71] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper; - callbacks[72] = (delegate* unmanaged)&_initClass; - callbacks[73] = (delegate* unmanaged)&_classMustBeLoadedBeforeCodeIsRun; - callbacks[74] = (delegate* unmanaged)&_getBuiltinClass; - callbacks[75] = (delegate* unmanaged)&_getTypeForPrimitiveValueClass; - callbacks[76] = (delegate* unmanaged)&_getTypeForPrimitiveNumericClass; - callbacks[77] = (delegate* unmanaged)&_canCast; - callbacks[78] = (delegate* unmanaged)&_compareTypesForCast; - callbacks[79] = (delegate* unmanaged)&_compareTypesForEquality; - callbacks[80] = (delegate* unmanaged)&_isMoreSpecificType; - callbacks[81] = (delegate* unmanaged)&_isExactType; - callbacks[82] = (delegate* unmanaged)&_isEnum; - callbacks[83] = (delegate* unmanaged)&_getParentType; - callbacks[84] = (delegate* unmanaged)&_getChildType; - callbacks[85] = (delegate* unmanaged)&_isSDArray; - callbacks[86] = (delegate* unmanaged)&_getArrayRank; - callbacks[87] = (delegate* unmanaged)&_getArrayIntrinsicID; - callbacks[88] = (delegate* unmanaged)&_getArrayInitializationData; - callbacks[89] = (delegate* unmanaged)&_canAccessClass; - callbacks[90] = (delegate* unmanaged)&_printFieldName; - callbacks[91] = (delegate* unmanaged)&_getFieldClass; - callbacks[92] = (delegate* unmanaged)&_getFieldType; - callbacks[93] = (delegate* unmanaged)&_getFieldOffset; - callbacks[94] = (delegate* unmanaged)&_getFieldInfo; - callbacks[95] = (delegate* unmanaged)&_getThreadLocalFieldInfo; - callbacks[96] = (delegate* unmanaged)&_getThreadLocalStaticBlocksInfo; - callbacks[97] = (delegate* unmanaged)&_getThreadLocalStaticInfo_NativeAOT; - callbacks[98] = (delegate* unmanaged)&_isFieldStatic; - callbacks[99] = (delegate* unmanaged)&_getArrayOrStringLength; - callbacks[100] = (delegate* unmanaged)&_getBoundaries; - callbacks[101] = (delegate* unmanaged)&_setBoundaries; - callbacks[102] = (delegate* unmanaged)&_getVars; - callbacks[103] = (delegate* unmanaged)&_setVars; - callbacks[104] = (delegate* unmanaged)&_reportRichMappings; - callbacks[105] = (delegate* unmanaged)&_allocateArray; - callbacks[106] = (delegate* unmanaged)&_freeArray; - callbacks[107] = (delegate* unmanaged)&_getArgNext; - callbacks[108] = (delegate* unmanaged)&_getArgType; - callbacks[109] = (delegate* unmanaged)&_getExactClasses; - callbacks[110] = (delegate* unmanaged)&_getArgClass; - callbacks[111] = (delegate* unmanaged)&_getHFAType; - callbacks[112] = (delegate* unmanaged)&_runWithErrorTrap; - callbacks[113] = (delegate* unmanaged)&_runWithSPMIErrorTrap; - callbacks[114] = (delegate* unmanaged)&_getEEInfo; - callbacks[115] = (delegate* unmanaged)&_getJitTimeLogFilename; - callbacks[116] = (delegate* unmanaged)&_getMethodDefFromMethod; - callbacks[117] = (delegate* unmanaged)&_printMethodName; - callbacks[118] = (delegate* unmanaged)&_getMethodNameFromMetadata; - callbacks[119] = (delegate* unmanaged)&_getMethodHash; - callbacks[120] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; - callbacks[121] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; - callbacks[122] = (delegate* unmanaged)&_getRISCV64PassStructInRegisterFlags; - callbacks[123] = (delegate* unmanaged)&_getThreadTLSIndex; - callbacks[124] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; - callbacks[125] = (delegate* unmanaged)&_getHelperFtn; - callbacks[126] = (delegate* unmanaged)&_getFunctionEntryPoint; - callbacks[127] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; - callbacks[128] = (delegate* unmanaged)&_getMethodSync; - callbacks[129] = (delegate* unmanaged)&_getLazyStringLiteralHelper; - callbacks[130] = (delegate* unmanaged)&_embedModuleHandle; - callbacks[131] = (delegate* unmanaged)&_embedClassHandle; - callbacks[132] = (delegate* unmanaged)&_embedMethodHandle; - callbacks[133] = (delegate* unmanaged)&_embedFieldHandle; - callbacks[134] = (delegate* unmanaged)&_embedGenericHandle; - callbacks[135] = (delegate* unmanaged)&_getLocationOfThisType; - callbacks[136] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; - callbacks[137] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; - callbacks[138] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; - callbacks[139] = (delegate* unmanaged)&_getJustMyCodeHandle; - callbacks[140] = (delegate* unmanaged)&_GetProfilingHandle; - callbacks[141] = (delegate* unmanaged)&_getCallInfo; - callbacks[142] = (delegate* unmanaged)&_getClassDomainID; - callbacks[143] = (delegate* unmanaged)&_getStaticFieldContent; - callbacks[144] = (delegate* unmanaged)&_getObjectContent; - callbacks[145] = (delegate* unmanaged)&_getStaticFieldCurrentClass; - callbacks[146] = (delegate* unmanaged)&_getVarArgsHandle; - callbacks[147] = (delegate* unmanaged)&_canGetVarArgsHandle; - callbacks[148] = (delegate* unmanaged)&_constructStringLiteral; - callbacks[149] = (delegate* unmanaged)&_emptyStringLiteral; - callbacks[150] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; - callbacks[151] = (delegate* unmanaged)&_GetDelegateCtor; - callbacks[152] = (delegate* unmanaged)&_MethodCompileComplete; - callbacks[153] = (delegate* unmanaged)&_getTailCallHelpers; - callbacks[154] = (delegate* unmanaged)&_convertPInvokeCalliToCall; - callbacks[155] = (delegate* unmanaged)&_notifyInstructionSetUsage; - callbacks[156] = (delegate* unmanaged)&_updateEntryPointForTailCall; - callbacks[157] = (delegate* unmanaged)&_allocMem; - callbacks[158] = (delegate* unmanaged)&_reserveUnwindInfo; - callbacks[159] = (delegate* unmanaged)&_allocUnwindInfo; - callbacks[160] = (delegate* unmanaged)&_allocGCInfo; - callbacks[161] = (delegate* unmanaged)&_setEHcount; - callbacks[162] = (delegate* unmanaged)&_setEHinfo; - callbacks[163] = (delegate* unmanaged)&_logMsg; - callbacks[164] = (delegate* unmanaged)&_doAssert; - callbacks[165] = (delegate* unmanaged)&_reportFatalError; - callbacks[166] = (delegate* unmanaged)&_getPgoInstrumentationResults; - callbacks[167] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; - callbacks[168] = (delegate* unmanaged)&_recordCallSite; - callbacks[169] = (delegate* unmanaged)&_recordRelocation; - callbacks[170] = (delegate* unmanaged)&_getRelocTypeHint; - callbacks[171] = (delegate* unmanaged)&_getExpectedTargetArchitecture; - callbacks[172] = (delegate* unmanaged)&_getJitFlags; + callbacks[40] = (delegate* unmanaged)&_getClassAttribs; + callbacks[41] = (delegate* unmanaged)&_getClassModule; + callbacks[42] = (delegate* unmanaged)&_getModuleAssembly; + callbacks[43] = (delegate* unmanaged)&_getAssemblyName; + callbacks[44] = (delegate* unmanaged)&_LongLifetimeMalloc; + callbacks[45] = (delegate* unmanaged)&_LongLifetimeFree; + callbacks[46] = (delegate* unmanaged)&_getClassModuleIdForStatics; + callbacks[47] = (delegate* unmanaged)&_getIsClassInitedFlagAddress; + callbacks[48] = (delegate* unmanaged)&_getStaticBaseAddress; + callbacks[49] = (delegate* unmanaged)&_getClassSize; + callbacks[50] = (delegate* unmanaged)&_getHeapClassSize; + callbacks[51] = (delegate* unmanaged)&_canAllocateOnStack; + callbacks[52] = (delegate* unmanaged)&_getClassAlignmentRequirement; + callbacks[53] = (delegate* unmanaged)&_getClassGClayout; + callbacks[54] = (delegate* unmanaged)&_getClassNumInstanceFields; + callbacks[55] = (delegate* unmanaged)&_getFieldInClass; + callbacks[56] = (delegate* unmanaged)&_getTypeLayout; + callbacks[57] = (delegate* unmanaged)&_checkMethodModifier; + callbacks[58] = (delegate* unmanaged)&_getNewHelper; + callbacks[59] = (delegate* unmanaged)&_getNewArrHelper; + callbacks[60] = (delegate* unmanaged)&_getCastingHelper; + callbacks[61] = (delegate* unmanaged)&_getSharedCCtorHelper; + callbacks[62] = (delegate* unmanaged)&_getTypeForBox; + callbacks[63] = (delegate* unmanaged)&_getBoxHelper; + callbacks[64] = (delegate* unmanaged)&_getUnBoxHelper; + callbacks[65] = (delegate* unmanaged)&_getRuntimeTypePointer; + callbacks[66] = (delegate* unmanaged)&_isObjectImmutable; + callbacks[67] = (delegate* unmanaged)&_getStringChar; + callbacks[68] = (delegate* unmanaged)&_getObjectType; + callbacks[69] = (delegate* unmanaged)&_getReadyToRunHelper; + callbacks[70] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper; + callbacks[71] = (delegate* unmanaged)&_initClass; + callbacks[72] = (delegate* unmanaged)&_classMustBeLoadedBeforeCodeIsRun; + callbacks[73] = (delegate* unmanaged)&_getBuiltinClass; + callbacks[74] = (delegate* unmanaged)&_getTypeForPrimitiveValueClass; + callbacks[75] = (delegate* unmanaged)&_getTypeForPrimitiveNumericClass; + callbacks[76] = (delegate* unmanaged)&_canCast; + callbacks[77] = (delegate* unmanaged)&_compareTypesForCast; + callbacks[78] = (delegate* unmanaged)&_compareTypesForEquality; + callbacks[79] = (delegate* unmanaged)&_isMoreSpecificType; + callbacks[80] = (delegate* unmanaged)&_isExactType; + callbacks[81] = (delegate* unmanaged)&_isEnum; + callbacks[82] = (delegate* unmanaged)&_getParentType; + callbacks[83] = (delegate* unmanaged)&_getChildType; + callbacks[84] = (delegate* unmanaged)&_isSDArray; + callbacks[85] = (delegate* unmanaged)&_getArrayRank; + callbacks[86] = (delegate* unmanaged)&_getArrayIntrinsicID; + callbacks[87] = (delegate* unmanaged)&_getArrayInitializationData; + callbacks[88] = (delegate* unmanaged)&_canAccessClass; + callbacks[89] = (delegate* unmanaged)&_printFieldName; + callbacks[90] = (delegate* unmanaged)&_getFieldClass; + callbacks[91] = (delegate* unmanaged)&_getFieldType; + callbacks[92] = (delegate* unmanaged)&_getFieldOffset; + callbacks[93] = (delegate* unmanaged)&_getFieldInfo; + callbacks[94] = (delegate* unmanaged)&_getThreadLocalFieldInfo; + callbacks[95] = (delegate* unmanaged)&_getThreadLocalStaticBlocksInfo; + callbacks[96] = (delegate* unmanaged)&_getThreadLocalStaticInfo_NativeAOT; + callbacks[97] = (delegate* unmanaged)&_isFieldStatic; + callbacks[98] = (delegate* unmanaged)&_getArrayOrStringLength; + callbacks[99] = (delegate* unmanaged)&_getBoundaries; + callbacks[100] = (delegate* unmanaged)&_setBoundaries; + callbacks[101] = (delegate* unmanaged)&_getVars; + callbacks[102] = (delegate* unmanaged)&_setVars; + callbacks[103] = (delegate* unmanaged)&_reportRichMappings; + callbacks[104] = (delegate* unmanaged)&_allocateArray; + callbacks[105] = (delegate* unmanaged)&_freeArray; + callbacks[106] = (delegate* unmanaged)&_getArgNext; + callbacks[107] = (delegate* unmanaged)&_getArgType; + callbacks[108] = (delegate* unmanaged)&_getExactClasses; + callbacks[109] = (delegate* unmanaged)&_getArgClass; + callbacks[110] = (delegate* unmanaged)&_getHFAType; + callbacks[111] = (delegate* unmanaged)&_runWithErrorTrap; + callbacks[112] = (delegate* unmanaged)&_runWithSPMIErrorTrap; + callbacks[113] = (delegate* unmanaged)&_getEEInfo; + callbacks[114] = (delegate* unmanaged)&_getJitTimeLogFilename; + callbacks[115] = (delegate* unmanaged)&_getMethodDefFromMethod; + callbacks[116] = (delegate* unmanaged)&_printMethodName; + callbacks[117] = (delegate* unmanaged)&_getMethodNameFromMetadata; + callbacks[118] = (delegate* unmanaged)&_getMethodHash; + callbacks[119] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; + callbacks[120] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; + callbacks[121] = (delegate* unmanaged)&_getRISCV64PassStructInRegisterFlags; + callbacks[122] = (delegate* unmanaged)&_getThreadTLSIndex; + callbacks[123] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; + callbacks[124] = (delegate* unmanaged)&_getHelperFtn; + callbacks[125] = (delegate* unmanaged)&_getFunctionEntryPoint; + callbacks[126] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; + callbacks[127] = (delegate* unmanaged)&_getMethodSync; + callbacks[128] = (delegate* unmanaged)&_getLazyStringLiteralHelper; + callbacks[129] = (delegate* unmanaged)&_embedModuleHandle; + callbacks[130] = (delegate* unmanaged)&_embedClassHandle; + callbacks[131] = (delegate* unmanaged)&_embedMethodHandle; + callbacks[132] = (delegate* unmanaged)&_embedFieldHandle; + callbacks[133] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[134] = (delegate* unmanaged)&_getLocationOfThisType; + callbacks[135] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; + callbacks[136] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; + callbacks[137] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; + callbacks[138] = (delegate* unmanaged)&_getJustMyCodeHandle; + callbacks[139] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[140] = (delegate* unmanaged)&_getCallInfo; + callbacks[141] = (delegate* unmanaged)&_getClassDomainID; + callbacks[142] = (delegate* unmanaged)&_getStaticFieldContent; + callbacks[143] = (delegate* unmanaged)&_getObjectContent; + callbacks[144] = (delegate* unmanaged)&_getStaticFieldCurrentClass; + callbacks[145] = (delegate* unmanaged)&_getVarArgsHandle; + callbacks[146] = (delegate* unmanaged)&_canGetVarArgsHandle; + callbacks[147] = (delegate* unmanaged)&_constructStringLiteral; + callbacks[148] = (delegate* unmanaged)&_emptyStringLiteral; + callbacks[149] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; + callbacks[150] = (delegate* unmanaged)&_GetDelegateCtor; + callbacks[151] = (delegate* unmanaged)&_MethodCompileComplete; + callbacks[152] = (delegate* unmanaged)&_getTailCallHelpers; + callbacks[153] = (delegate* unmanaged)&_convertPInvokeCalliToCall; + callbacks[154] = (delegate* unmanaged)&_notifyInstructionSetUsage; + callbacks[155] = (delegate* unmanaged)&_updateEntryPointForTailCall; + callbacks[156] = (delegate* unmanaged)&_allocMem; + callbacks[157] = (delegate* unmanaged)&_reserveUnwindInfo; + callbacks[158] = (delegate* unmanaged)&_allocUnwindInfo; + callbacks[159] = (delegate* unmanaged)&_allocGCInfo; + callbacks[160] = (delegate* unmanaged)&_setEHcount; + callbacks[161] = (delegate* unmanaged)&_setEHinfo; + callbacks[162] = (delegate* unmanaged)&_logMsg; + callbacks[163] = (delegate* unmanaged)&_doAssert; + callbacks[164] = (delegate* unmanaged)&_reportFatalError; + callbacks[165] = (delegate* unmanaged)&_getPgoInstrumentationResults; + callbacks[166] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; + callbacks[167] = (delegate* unmanaged)&_recordCallSite; + callbacks[168] = (delegate* unmanaged)&_recordRelocation; + callbacks[169] = (delegate* unmanaged)&_getRelocTypeHint; + callbacks[170] = (delegate* unmanaged)&_getExpectedTargetArchitecture; + callbacks[171] = (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 f6182050ba950b..3407e4e3a87c9a 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -202,7 +202,6 @@ FUNCTIONS CORINFO_CLASS_HANDLE getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index) size_t printClassName(CORINFO_CLASS_HANDLE cls, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) bool isValueClass(CORINFO_CLASS_HANDLE cls) - CorInfoInlineTypeCheck canInlineTypeCheck(CORINFO_CLASS_HANDLE cls, CorInfoInlineTypeCheckSource source) uint32_t getClassAttribs(CORINFO_CLASS_HANDLE cls) CORINFO_MODULE_HANDLE getClassModule(CORINFO_CLASS_HANDLE cls) CORINFO_ASSEMBLY_HANDLE getModuleAssembly(CORINFO_MODULE_HANDLE mod) diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index 9109c6afb51789..5d659488b29257 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -51,7 +51,6 @@ struct JitInterfaceCallbacks CORINFO_CLASS_HANDLE (* getTypeInstantiationArgument)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls, unsigned index); size_t (* printClassName)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize); bool (* isValueClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); - CorInfoInlineTypeCheck (* canInlineTypeCheck)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls, CorInfoInlineTypeCheckSource source); uint32_t (* getClassAttribs)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); CORINFO_MODULE_HANDLE (* getClassModule)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); CORINFO_ASSEMBLY_HANDLE (* getModuleAssembly)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE mod); @@ -593,16 +592,6 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } - virtual CorInfoInlineTypeCheck canInlineTypeCheck( - CORINFO_CLASS_HANDLE cls, - CorInfoInlineTypeCheckSource source) -{ - CorInfoExceptionClass* pException = nullptr; - CorInfoInlineTypeCheck temp = _callbacks->canInlineTypeCheck(_thisHandle, &pException, cls, source); - if (pException != nullptr) throw pException; - return temp; -} - virtual uint32_t getClassAttribs( CORINFO_CLASS_HANDLE cls) { diff --git a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h index cabbc5f1938df6..a44faac3cee24e 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -24,7 +24,6 @@ LWM(CanCast, DLDL, DWORD) LWM(CanGetCookieForPInvokeCalliSig, CanGetCookieForPInvokeCalliSigValue, DWORD) LWM(CanGetVarArgsHandle, CanGetVarArgsHandleValue, DWORD) LWM(CanInline, DLDL, Agnostic_CanInline) -LWM(CanInlineTypeCheck, DLD, DWORD) LWM(CanTailCall, Agnostic_CanTailCall, DWORD) LWM(CheckMethodModifier, Agnostic_CheckMethodModifier, DWORD) LWM(CompareTypesForCast, DLDL, DWORD) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 33fe1a1bf208c6..7770e1e2696fc4 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -4998,41 +4998,6 @@ CorInfoType MethodContext::repGetFieldType(CORINFO_FIELD_HANDLE field, return (CorInfoType)value.B; } -void MethodContext::recCanInlineTypeCheck(CORINFO_CLASS_HANDLE cls, - CorInfoInlineTypeCheckSource source, - CorInfoInlineTypeCheck result) -{ - if (CanInlineTypeCheck == nullptr) - CanInlineTypeCheck = new LightWeightMap(); - - DLD key; - ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.A = CastHandle(cls); - key.B = (DWORD)source; - - DWORD value = (DWORD)result; - CanInlineTypeCheck->Add(key, value); - DEBUG_REC(dmpCanInlineTypeCheck(key, value)); -} -void MethodContext::dmpCanInlineTypeCheck(DLD key, DWORD value) -{ - printf("CanInlineTypeCheck key cls-%016" PRIX64 " src-%08X, value res-%u", key.A, key.B, value); -} -CorInfoInlineTypeCheck MethodContext::repCanInlineTypeCheck(CORINFO_CLASS_HANDLE cls, - CorInfoInlineTypeCheckSource source) -{ - DLD key; - ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.A = CastHandle(cls); - key.B = (DWORD)source; - - DWORD value = LookupByKeyOrMiss(CanInlineTypeCheck, key, ": key %016" PRIX64 "", key.A); - - DEBUG_REP(dmpCanInlineTypeCheck(key, value)); - CorInfoInlineTypeCheck result = (CorInfoInlineTypeCheck)value; - return result; -} - void MethodContext::recSatisfiesMethodConstraints(CORINFO_CLASS_HANDLE parent, CORINFO_METHOD_HANDLE method, bool result) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 885710187412d3..3344552ca06058 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -627,12 +627,6 @@ class MethodContext CORINFO_CLASS_HANDLE* structType, CORINFO_CLASS_HANDLE memberParent); - void recCanInlineTypeCheck(CORINFO_CLASS_HANDLE cls, - CorInfoInlineTypeCheckSource source, - CorInfoInlineTypeCheck result); - void dmpCanInlineTypeCheck(DLD key, DWORD value); - CorInfoInlineTypeCheck repCanInlineTypeCheck(CORINFO_CLASS_HANDLE cls, CorInfoInlineTypeCheckSource source); - void recSatisfiesMethodConstraints(CORINFO_CLASS_HANDLE parent, CORINFO_METHOD_HANDLE method, bool result); void dmpSatisfiesMethodConstraints(DLDL key, DWORD value); bool repSatisfiesMethodConstraints(CORINFO_CLASS_HANDLE parent, CORINFO_METHOD_HANDLE method); @@ -1110,7 +1104,7 @@ enum mcPackets Packet_GetHeapClassSize = 170, Packet_CanAllocateOnStack = 171, Packet_GetStaticFieldCurrentClass = 172, - Packet_CanInlineTypeCheck = 173, + // Packet_CanInlineTypeCheck = 173, Packet_IsMoreSpecificType = 174, Packet_GetStringLiteral = 175, PacketCR_SetPatchpointInfo = 176, diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 996752e6e243c1..47c50535e450f1 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -478,18 +478,6 @@ bool interceptor_ICJI::isValueClass(CORINFO_CLASS_HANDLE cls) return temp; } -// Decides how the JIT should do the optimization to inline the check for -// GetTypeFromHandle(handle) == obj.GetType() (for CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE) -// GetTypeFromHandle(X) == GetTypeFromHandle(Y) (for CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN) -CorInfoInlineTypeCheck interceptor_ICJI::canInlineTypeCheck(CORINFO_CLASS_HANDLE cls, - CorInfoInlineTypeCheckSource source) -{ - mc->cr->AddCall("canInlineTypeCheck"); - CorInfoInlineTypeCheck temp = original_ICorJitInfo->canInlineTypeCheck(cls, source); - mc->recCanInlineTypeCheck(cls, source, temp); - return temp; -} - // return flags (defined above, CORINFO_FLG_PUBLIC ...) uint32_t interceptor_ICJI::getClassAttribs(CORINFO_CLASS_HANDLE cls) { 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 5330a0bcca01d3..0f69dfae4a08c6 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -340,14 +340,6 @@ bool interceptor_ICJI::isValueClass( return original_ICorJitInfo->isValueClass(cls); } -CorInfoInlineTypeCheck interceptor_ICJI::canInlineTypeCheck( - CORINFO_CLASS_HANDLE cls, - CorInfoInlineTypeCheckSource source) -{ - mcs->AddCall("canInlineTypeCheck"); - return original_ICorJitInfo->canInlineTypeCheck(cls, source); -} - uint32_t interceptor_ICJI::getClassAttribs( CORINFO_CLASS_HANDLE cls) { 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 fab31aeae54ff5..02bef7b549aca0 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -300,13 +300,6 @@ bool interceptor_ICJI::isValueClass( return original_ICorJitInfo->isValueClass(cls); } -CorInfoInlineTypeCheck interceptor_ICJI::canInlineTypeCheck( - CORINFO_CLASS_HANDLE cls, - CorInfoInlineTypeCheckSource source) -{ - return original_ICorJitInfo->canInlineTypeCheck(cls, source); -} - uint32_t interceptor_ICJI::getClassAttribs( CORINFO_CLASS_HANDLE cls) { diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 16e02586a00cc3..15c17173abdda4 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -409,15 +409,6 @@ bool MyICJI::isValueClass(CORINFO_CLASS_HANDLE cls) return jitInstance->mc->repIsValueClass(cls); } -// Decides how the JIT should do the optimization to inline the check for -// GetTypeFromHandle(handle) == obj.GetType() (for CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE) -// GetTypeFromHandle(X) == GetTypeFromHandle(Y) (for CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN) -CorInfoInlineTypeCheck MyICJI::canInlineTypeCheck(CORINFO_CLASS_HANDLE cls, CorInfoInlineTypeCheckSource source) -{ - jitInstance->mc->cr->AddCall("canInlineTypeCheck"); - return jitInstance->mc->repCanInlineTypeCheck(cls, source); -} - // return flags (defined above, CORINFO_FLG_PUBLIC ...) uint32_t MyICJI::getClassAttribs(CORINFO_CLASS_HANDLE cls) { diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index c39bc5630e5fb2..cac5999056265c 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -3813,18 +3813,6 @@ bool CEEInfo::isValueClass(CORINFO_CLASS_HANDLE clsHnd) return ret; } -/*********************************************************************/ -// Decides how the JIT should do the optimization to inline the check for -// GetTypeFromHandle(handle) == obj.GetType() -// GetTypeFromHandle(X) == GetTypeFromHandle(Y) -// -// This will enable to use directly the typehandle instead of going through getClassByHandle -CorInfoInlineTypeCheck CEEInfo::canInlineTypeCheck(CORINFO_CLASS_HANDLE clsHnd, CorInfoInlineTypeCheckSource source) -{ - LIMITED_METHOD_CONTRACT; - return CORINFO_INLINE_TYPECHECK_PASS; -} - /*********************************************************************/ uint32_t CEEInfo::getClassAttribs (CORINFO_CLASS_HANDLE clsHnd) {