diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 4598496ac66845..9d44d64a4cf07a 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2134,6 +2134,21 @@ class ICorStaticInfo CORINFO_METHOD_HANDLE meth1Hnd, CORINFO_METHOD_HANDLE meth2Hnd) = 0; + //------------------------------------------------------------------------------ + // getTypeDefinition: Get the (unconstructed) type definition from a given type handle. + // + // Arguments: + // type - The input type handle + // + // Return Value: + // The type handle for the (unconstructed) type definition from type. + // + // Remarks: + // This is equivalent of Type.GetGenericTypeDefinition(). Given a generic type handle, it will + // return the original type definition (eg. for Foo it will return Foo<>). This method + // should only be called when the input type is in fact a generic type. + virtual CORINFO_CLASS_HANDLE getTypeDefinition(CORINFO_CLASS_HANDLE type) = 0; + // Decides if you have any limitations for inlining. If everything's OK, it will return // INLINE_PASS. // diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index 46c0c817bad07d..208c4f6e8ffc67 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -48,6 +48,9 @@ bool haveSameMethodDefinition( CORINFO_METHOD_HANDLE meth1Hnd, CORINFO_METHOD_HANDLE meth2Hnd) override; +CORINFO_CLASS_HANDLE getTypeDefinition( + CORINFO_CLASS_HANDLE type) override; + CorInfoInline canInline( CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd) override; diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 11675936acfa37..1ad50ce6381044 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 = { /* 86eab154-5d93-4fad-bc07-e94fd9268b70 */ - 0x86eab154, - 0x5d93, - 0x4fad, - {0xbc, 0x07, 0xe9, 0x4f, 0xd9, 0x26, 0x8b, 0x70} +constexpr GUID JITEEVersionIdentifier = { /* dbcd6414-2c05-4414-9086-6417cffb94d1 */ + 0xdbcd6414, + 0x2c05, + 0x4414, + {0x90, 0x86, 0x64, 0x17, 0xcf, 0xfb, 0x94, 0xd1} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/ICorJitInfo_names_generated.h b/src/coreclr/jit/ICorJitInfo_names_generated.h index 3908d4bcdc4be2..2d1cd51b691ad1 100644 --- a/src/coreclr/jit/ICorJitInfo_names_generated.h +++ b/src/coreclr/jit/ICorJitInfo_names_generated.h @@ -11,6 +11,7 @@ DEF_CLR_API(setMethodAttribs) DEF_CLR_API(getMethodSig) DEF_CLR_API(getMethodInfo) DEF_CLR_API(haveSameMethodDefinition) +DEF_CLR_API(getTypeDefinition) DEF_CLR_API(canInline) DEF_CLR_API(beginInlining) DEF_CLR_API(reportInliningDecision) diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index 1205512fabff0f..e0dbf98d9c97e0 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -79,6 +79,15 @@ bool WrapICorJitInfo::haveSameMethodDefinition( return temp; } +CORINFO_CLASS_HANDLE WrapICorJitInfo::getTypeDefinition( + CORINFO_CLASS_HANDLE type) +{ + API_ENTER(getTypeDefinition); + CORINFO_CLASS_HANDLE temp = wrapHnd->getTypeDefinition(type); + API_LEAVE(getTypeDefinition); + return temp; +} + CorInfoInline WrapICorJitInfo::canInline( CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index beeef98d8d0a12..a4780f0a1c01c3 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -4429,6 +4429,7 @@ class Compiler void impImportLeave(BasicBlock* block); void impResetLeaveBlock(BasicBlock* block, unsigned jmpAddr); GenTree* impTypeIsAssignable(GenTree* typeTo, GenTree* typeFrom); + GenTree* impGetGenericTypeDefinition(GenTree* type); // Mirrors StringComparison.cs enum StringComparison diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp index 9d9c44776b436a..e664c722e06f92 100644 --- a/src/coreclr/jit/fgbasic.cpp +++ b/src/coreclr/jit/fgbasic.cpp @@ -1345,6 +1345,7 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed case NI_System_Type_get_IsPrimitive: case NI_System_Type_get_IsByRefLike: case NI_System_Type_GetTypeFromHandle: + case NI_System_Type_GetGenericTypeDefinition: case NI_System_String_get_Length: case NI_System_Buffers_Binary_BinaryPrimitives_ReverseEndianness: #if defined(FEATURE_HW_INTRINSICS) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index e50773eefd4a53..ae0d54d36ef034 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -2486,6 +2486,33 @@ GenTree* Compiler::impTypeIsAssignable(GenTree* typeTo, GenTree* typeFrom) return nullptr; } + +GenTree* Compiler::impGetGenericTypeDefinition(GenTree* type) +{ + // This intrinsic requires the first arg to be some `typeof()` expression, + // ie. it applies to cases such as `typeof(...).GetGenericTypeDefinition()`. + CORINFO_CLASS_HANDLE hClassType = NO_CLASS_HANDLE; + if (gtIsTypeof(type, &hClassType)) + { + // Check that the 'typeof()' expression is being used on a type that is in fact generic. + // If that is not the case, we don't expand the intrinsic. This will end up using + // the usual Type.GetGenericTypeDefinition() at runtime, which will throw in this case. + if (info.compCompHnd->getTypeInstantiationArgument(hClassType, 0) != NO_CLASS_HANDLE) + { + CORINFO_CLASS_HANDLE hClassResult = info.compCompHnd->getTypeDefinition(hClassType); + + GenTree* retNode = gtNewIconEmbClsHndNode(hClassResult); + + // Drop the typeof(T) node + impPopStack(); + + return retNode; + } + } + + return nullptr; +} + /***************************************************************************** * 'logMsg' is true if a log message needs to be logged. false if the caller has * already logged it (presumably in a more detailed fashion than done here) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index ae17103edaeb46..3d0a450e601e39 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -2874,6 +2874,9 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, case NI_System_Type_op_Equality: case NI_System_Type_op_Inequality: + // This allows folding "typeof(...).GetGenericTypeDefinition() == typeof(...)" + case NI_System_Type_GetGenericTypeDefinition: + // These may lead to early dead code elimination case NI_System_Type_get_IsValueType: case NI_System_Type_get_IsPrimitive: @@ -3391,6 +3394,14 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, break; } + case NI_System_Type_GetGenericTypeDefinition: + { + GenTree* type = impStackTop(0).val; + + retNode = impGetGenericTypeDefinition(type); + break; + } + case NI_System_Type_op_Equality: case NI_System_Type_op_Inequality: { @@ -9250,6 +9261,10 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) { result = NI_System_Type_GetTypeFromHandle; } + else if (strcmp(methodName, "GetGenericTypeDefinition") == 0) + { + result = NI_System_Type_GetGenericTypeDefinition; + } else if (strcmp(methodName, "IsAssignableFrom") == 0) { result = NI_System_Type_IsAssignableFrom; diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h index 9fa128c38f74ee..26be97070495aa 100644 --- a/src/coreclr/jit/namedintrinsiclist.h +++ b/src/coreclr/jit/namedintrinsiclist.h @@ -84,6 +84,7 @@ enum NamedIntrinsic : unsigned short NI_System_Type_op_Equality, NI_System_Type_op_Inequality, NI_System_Type_GetTypeFromHandle, + NI_System_Type_GetGenericTypeDefinition, NI_System_Array_Clone, NI_System_Array_GetLength, NI_System_Array_GetLowerBound, diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index f3593694bc5e2c..3d7629fc966d4a 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1253,6 +1253,11 @@ private bool haveSameMethodDefinition(CORINFO_METHOD_STRUCT_* methHnd1, CORINFO_ return meth1.GetTypicalMethodDefinition() == meth2.GetTypicalMethodDefinition(); } + private CORINFO_CLASS_STRUCT_* getTypeDefinition(CORINFO_CLASS_STRUCT_* type) + { + return ObjectToHandle(HandleToObject(type).GetTypeDefinition()); + } + private CorInfoInline canInline(CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUCT_* calleeHnd) { MethodDesc callerMethod = HandleToObject(callerHnd); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 7789862f5074a1..6af3da32791a53 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -115,6 +115,21 @@ private static byte _haveSameMethodDefinition(IntPtr thisHandle, IntPtr* ppExcep } } + [UnmanagedCallersOnly] + private static CORINFO_CLASS_STRUCT_* _getTypeDefinition(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* type) + { + var _this = GetThis(thisHandle); + try + { + return _this.getTypeDefinition(type); + } + catch (Exception ex) + { + *ppException = _this.AllocException(ex); + return default; + } + } + [UnmanagedCallersOnly] private static CorInfoInline _canInline(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUCT_* calleeHnd) { @@ -2565,7 +2580,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) * 174); callbacks[0] = (delegate* unmanaged)&_isIntrinsic; callbacks[1] = (delegate* unmanaged)&_notifyMethodInfoUsage; @@ -2574,172 +2589,173 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[4] = (delegate* unmanaged)&_getMethodSig; callbacks[5] = (delegate* unmanaged)&_getMethodInfo; callbacks[6] = (delegate* unmanaged)&_haveSameMethodDefinition; - callbacks[7] = (delegate* unmanaged)&_canInline; - callbacks[8] = (delegate* unmanaged)&_beginInlining; - callbacks[9] = (delegate* unmanaged)&_reportInliningDecision; - callbacks[10] = (delegate* unmanaged)&_canTailCall; - callbacks[11] = (delegate* unmanaged)&_reportTailCallDecision; - callbacks[12] = (delegate* unmanaged)&_getEHinfo; - callbacks[13] = (delegate* unmanaged)&_getMethodClass; - callbacks[14] = (delegate* unmanaged)&_getMethodVTableOffset; - callbacks[15] = (delegate* unmanaged)&_resolveVirtualMethod; - callbacks[16] = (delegate* unmanaged)&_getUnboxedEntry; - callbacks[17] = (delegate* unmanaged)&_getDefaultComparerClass; - callbacks[18] = (delegate* unmanaged)&_getDefaultEqualityComparerClass; - callbacks[19] = (delegate* unmanaged)&_expandRawHandleIntrinsic; - callbacks[20] = (delegate* unmanaged)&_isIntrinsicType; - callbacks[21] = (delegate* unmanaged)&_getUnmanagedCallConv; - callbacks[22] = (delegate* unmanaged)&_pInvokeMarshalingRequired; - callbacks[23] = (delegate* unmanaged)&_satisfiesMethodConstraints; - callbacks[24] = (delegate* unmanaged)&_methodMustBeLoadedBeforeCodeIsRun; - callbacks[25] = (delegate* unmanaged)&_mapMethodDeclToMethodImpl; - callbacks[26] = (delegate* unmanaged)&_getGSCookie; - callbacks[27] = (delegate* unmanaged)&_setPatchpointInfo; - callbacks[28] = (delegate* unmanaged)&_getOSRInfo; - callbacks[29] = (delegate* unmanaged)&_resolveToken; - callbacks[30] = (delegate* unmanaged)&_findSig; - callbacks[31] = (delegate* unmanaged)&_findCallSiteSig; - callbacks[32] = (delegate* unmanaged)&_getTokenTypeAsHandle; - callbacks[33] = (delegate* unmanaged)&_getStringLiteral; - callbacks[34] = (delegate* unmanaged)&_printObjectDescription; - callbacks[35] = (delegate* unmanaged)&_asCorInfoType; - callbacks[36] = (delegate* unmanaged)&_getClassNameFromMetadata; - callbacks[37] = (delegate* unmanaged)&_getTypeInstantiationArgument; - callbacks[38] = (delegate* unmanaged)&_printClassName; - callbacks[39] = (delegate* unmanaged)&_isValueClass; - 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)&_reportMetadata; - 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[7] = (delegate* unmanaged)&_getTypeDefinition; + callbacks[8] = (delegate* unmanaged)&_canInline; + callbacks[9] = (delegate* unmanaged)&_beginInlining; + callbacks[10] = (delegate* unmanaged)&_reportInliningDecision; + callbacks[11] = (delegate* unmanaged)&_canTailCall; + callbacks[12] = (delegate* unmanaged)&_reportTailCallDecision; + callbacks[13] = (delegate* unmanaged)&_getEHinfo; + callbacks[14] = (delegate* unmanaged)&_getMethodClass; + callbacks[15] = (delegate* unmanaged)&_getMethodVTableOffset; + callbacks[16] = (delegate* unmanaged)&_resolveVirtualMethod; + callbacks[17] = (delegate* unmanaged)&_getUnboxedEntry; + callbacks[18] = (delegate* unmanaged)&_getDefaultComparerClass; + callbacks[19] = (delegate* unmanaged)&_getDefaultEqualityComparerClass; + callbacks[20] = (delegate* unmanaged)&_expandRawHandleIntrinsic; + callbacks[21] = (delegate* unmanaged)&_isIntrinsicType; + callbacks[22] = (delegate* unmanaged)&_getUnmanagedCallConv; + callbacks[23] = (delegate* unmanaged)&_pInvokeMarshalingRequired; + callbacks[24] = (delegate* unmanaged)&_satisfiesMethodConstraints; + callbacks[25] = (delegate* unmanaged)&_methodMustBeLoadedBeforeCodeIsRun; + callbacks[26] = (delegate* unmanaged)&_mapMethodDeclToMethodImpl; + callbacks[27] = (delegate* unmanaged)&_getGSCookie; + callbacks[28] = (delegate* unmanaged)&_setPatchpointInfo; + callbacks[29] = (delegate* unmanaged)&_getOSRInfo; + callbacks[30] = (delegate* unmanaged)&_resolveToken; + callbacks[31] = (delegate* unmanaged)&_findSig; + callbacks[32] = (delegate* unmanaged)&_findCallSiteSig; + callbacks[33] = (delegate* unmanaged)&_getTokenTypeAsHandle; + callbacks[34] = (delegate* unmanaged)&_getStringLiteral; + callbacks[35] = (delegate* unmanaged)&_printObjectDescription; + callbacks[36] = (delegate* unmanaged)&_asCorInfoType; + callbacks[37] = (delegate* unmanaged)&_getClassNameFromMetadata; + callbacks[38] = (delegate* unmanaged)&_getTypeInstantiationArgument; + callbacks[39] = (delegate* unmanaged)&_printClassName; + callbacks[40] = (delegate* unmanaged)&_isValueClass; + 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)&_reportMetadata; + callbacks[106] = (delegate* unmanaged)&_allocateArray; + callbacks[107] = (delegate* unmanaged)&_freeArray; + callbacks[108] = (delegate* unmanaged)&_getArgNext; + callbacks[109] = (delegate* unmanaged)&_getArgType; + callbacks[110] = (delegate* unmanaged)&_getExactClasses; + callbacks[111] = (delegate* unmanaged)&_getArgClass; + callbacks[112] = (delegate* unmanaged)&_getHFAType; + callbacks[113] = (delegate* unmanaged)&_runWithErrorTrap; + callbacks[114] = (delegate* unmanaged)&_runWithSPMIErrorTrap; + callbacks[115] = (delegate* unmanaged)&_getEEInfo; + callbacks[116] = (delegate* unmanaged)&_getJitTimeLogFilename; + callbacks[117] = (delegate* unmanaged)&_getMethodDefFromMethod; + callbacks[118] = (delegate* unmanaged)&_printMethodName; + callbacks[119] = (delegate* unmanaged)&_getMethodNameFromMetadata; + callbacks[120] = (delegate* unmanaged)&_getMethodHash; + callbacks[121] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; + callbacks[122] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; + callbacks[123] = (delegate* unmanaged)&_getRISCV64PassStructInRegisterFlags; + callbacks[124] = (delegate* unmanaged)&_getThreadTLSIndex; + callbacks[125] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; + callbacks[126] = (delegate* unmanaged)&_getHelperFtn; + callbacks[127] = (delegate* unmanaged)&_getFunctionEntryPoint; + callbacks[128] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; + callbacks[129] = (delegate* unmanaged)&_getMethodSync; + callbacks[130] = (delegate* unmanaged)&_getLazyStringLiteralHelper; + callbacks[131] = (delegate* unmanaged)&_embedModuleHandle; + callbacks[132] = (delegate* unmanaged)&_embedClassHandle; + callbacks[133] = (delegate* unmanaged)&_embedMethodHandle; + callbacks[134] = (delegate* unmanaged)&_embedFieldHandle; + callbacks[135] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[136] = (delegate* unmanaged)&_getLocationOfThisType; + callbacks[137] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; + callbacks[138] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; + callbacks[139] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; + callbacks[140] = (delegate* unmanaged)&_getJustMyCodeHandle; + callbacks[141] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[142] = (delegate* unmanaged)&_getCallInfo; + callbacks[143] = (delegate* unmanaged)&_getClassDomainID; + callbacks[144] = (delegate* unmanaged)&_getStaticFieldContent; + callbacks[145] = (delegate* unmanaged)&_getObjectContent; + callbacks[146] = (delegate* unmanaged)&_getStaticFieldCurrentClass; + callbacks[147] = (delegate* unmanaged)&_getVarArgsHandle; + callbacks[148] = (delegate* unmanaged)&_canGetVarArgsHandle; + callbacks[149] = (delegate* unmanaged)&_constructStringLiteral; + callbacks[150] = (delegate* unmanaged)&_emptyStringLiteral; + callbacks[151] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; + callbacks[152] = (delegate* unmanaged)&_GetDelegateCtor; + callbacks[153] = (delegate* unmanaged)&_MethodCompileComplete; + callbacks[154] = (delegate* unmanaged)&_getTailCallHelpers; + callbacks[155] = (delegate* unmanaged)&_convertPInvokeCalliToCall; + callbacks[156] = (delegate* unmanaged)&_notifyInstructionSetUsage; + callbacks[157] = (delegate* unmanaged)&_updateEntryPointForTailCall; + callbacks[158] = (delegate* unmanaged)&_allocMem; + callbacks[159] = (delegate* unmanaged)&_reserveUnwindInfo; + callbacks[160] = (delegate* unmanaged)&_allocUnwindInfo; + callbacks[161] = (delegate* unmanaged)&_allocGCInfo; + callbacks[162] = (delegate* unmanaged)&_setEHcount; + callbacks[163] = (delegate* unmanaged)&_setEHinfo; + callbacks[164] = (delegate* unmanaged)&_logMsg; + callbacks[165] = (delegate* unmanaged)&_doAssert; + callbacks[166] = (delegate* unmanaged)&_reportFatalError; + callbacks[167] = (delegate* unmanaged)&_getPgoInstrumentationResults; + callbacks[168] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; + callbacks[169] = (delegate* unmanaged)&_recordCallSite; + callbacks[170] = (delegate* unmanaged)&_recordRelocation; + callbacks[171] = (delegate* unmanaged)&_getRelocTypeHint; + callbacks[172] = (delegate* unmanaged)&_getExpectedTargetArchitecture; + callbacks[173] = (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 fda65c03b9ab17..3461d7256f03ae 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -169,6 +169,7 @@ FUNCTIONS void getMethodSig( CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO *sig, CORINFO_CLASS_HANDLE memberParent ); bool getMethodInfo(CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_INFO* info, CORINFO_CONTEXT_HANDLE context); bool haveSameMethodDefinition(CORINFO_METHOD_HANDLE meth1Hnd, CORINFO_METHOD_HANDLE meth2Hnd); + CORINFO_CLASS_HANDLE getTypeDefinition(CORINFO_CLASS_HANDLE type); CorInfoInline canInline( CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd); void beginInlining(CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd); void reportInliningDecision(CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd, CorInfoInline inlineResult, const char * reason); diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index 3723b57aa4d8e2..34df4a3a6d21b4 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -18,6 +18,7 @@ struct JitInterfaceCallbacks void (* getMethodSig)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO* sig, CORINFO_CLASS_HANDLE memberParent); bool (* getMethodInfo)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_INFO* info, CORINFO_CONTEXT_HANDLE context); bool (* haveSameMethodDefinition)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE meth1Hnd, CORINFO_METHOD_HANDLE meth2Hnd); + CORINFO_CLASS_HANDLE (* getTypeDefinition)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE type); CorInfoInline (* canInline)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd); void (* beginInlining)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd); void (* reportInliningDecision)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd, CorInfoInline inlineResult, const char* reason); @@ -266,6 +267,15 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } + virtual CORINFO_CLASS_HANDLE getTypeDefinition( + CORINFO_CLASS_HANDLE type) +{ + CorInfoExceptionClass* pException = nullptr; + CORINFO_CLASS_HANDLE temp = _callbacks->getTypeDefinition(_thisHandle, &pException, type); + if (pException != nullptr) throw pException; + return temp; +} + virtual CorInfoInline canInline( CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h index a44faac3cee24e..6bfa3b3186cae1 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -109,6 +109,7 @@ LWM(GetMethodDefFromMethod, DWORDLONG, DWORD) LWM(GetMethodHash, DWORDLONG, DWORD) LWM(GetMethodInfo, DLDL, Agnostic_GetMethodInfo) LWM(HaveSameMethodDefinition, DLDL, DWORD) +LWM(GetTypeDefinition, DWORDLONG, DWORDLONG) LWM(GetMethodNameFromMetadata, Agnostic_CORINFO_METHODNAME_TOKENin, Agnostic_CORINFO_METHODNAME_TOKENout) LWM(GetMethodSig, DLDL, Agnostic_CORINFO_SIG_INFO) LWM(GetMethodSync, DWORDLONG, DLDL) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index c72b8b1eec1f6c..dc1190fe3a0889 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -3059,6 +3059,29 @@ bool MethodContext::repHaveSameMethodDefinition(CORINFO_METHOD_HANDLE methHnd1, return value != 0; } +void MethodContext::recGetTypeDefinition(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result) +{ + if (GetTypeDefinition == nullptr) + GetTypeDefinition = new LightWeightMap(); + + DWORDLONG key = CastHandle(cls); + DWORDLONG value = CastHandle(result); + GetTypeDefinition->Add(key, value); + DEBUG_REC(dmpGetTypeDefinition(key, value)); +} +void MethodContext::dmpGetTypeDefinition(DWORDLONG key, DWORDLONG value) +{ + printf("GetTypeDefinition key cls-%016" PRIX64 ", value cls-%016" PRIX64 "", key, value); +} +CORINFO_CLASS_HANDLE MethodContext::repGetTypeDefinition(CORINFO_CLASS_HANDLE cls) +{ + DWORDLONG key = CastHandle(cls); + DWORDLONG value = LookupByKeyOrMiss(GetTypeDefinition, key, ": key %016" PRIX64 "", key); + DEBUG_REP(dmpGetTypeDefinition(key, value)); + CORINFO_CLASS_HANDLE result = (CORINFO_CLASS_HANDLE)value; + return result; +} + void MethodContext::recGetNewHelper(CORINFO_CLASS_HANDLE classHandle, bool hasSideEffects, CorInfoHelpFunc result, diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 74128026015006..2d3b30e6e03e75 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -414,6 +414,10 @@ class MethodContext void dmpHaveSameMethodDefinition(const DLDL& key, DWORD value); bool repHaveSameMethodDefinition(CORINFO_METHOD_HANDLE methHnd1, CORINFO_METHOD_HANDLE methHnd2); + void recGetTypeDefinition(CORINFO_CLASS_HANDLE type, CORINFO_CLASS_HANDLE result); + void dmpGetTypeDefinition(DWORDLONG key, DWORDLONG value); + CORINFO_CLASS_HANDLE repGetTypeDefinition(CORINFO_CLASS_HANDLE type); + void recGetNewHelper(CORINFO_CLASS_HANDLE classHandle, bool hasSideEffects, CorInfoHelpFunc result, @@ -1154,6 +1158,7 @@ enum mcPackets Packet_HaveSameMethodDefinition = 213, Packet_NotifyMethodInfoUsage = 214, Packet_IsExactType = 215, + Packet_GetTypeDefinition = 216, }; void SetDebugDumpVariables(); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 0cbcfb2df1b0b1..d80cffd789570a 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -107,6 +107,15 @@ bool interceptor_ICJI::haveSameMethodDefinition( return result; } +CORINFO_CLASS_HANDLE interceptor_ICJI::getTypeDefinition( + CORINFO_CLASS_HANDLE type) +{ + CORINFO_CLASS_HANDLE result = original_ICorJitInfo->getTypeDefinition(type); + mc->recGetTypeDefinition(type, result); + + return result; +} + // Decides if you have any limitations for inlining. If everything's OK, it will return // INLINE_PASS. // 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 d3fe993b94765b..170af2d60e0ad5 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -67,6 +67,13 @@ bool interceptor_ICJI::haveSameMethodDefinition( return original_ICorJitInfo->haveSameMethodDefinition(meth1Hnd, meth2Hnd); } +CORINFO_CLASS_HANDLE interceptor_ICJI::getTypeDefinition( + CORINFO_CLASS_HANDLE type) +{ + mcs->AddCall("getTypeDefinition"); + return original_ICorJitInfo->getTypeDefinition(type); +} + CorInfoInline interceptor_ICJI::canInline( CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd) 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 f3cdc4ff8ce636..285e6827edaf1e 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -60,6 +60,12 @@ bool interceptor_ICJI::haveSameMethodDefinition( return original_ICorJitInfo->haveSameMethodDefinition(meth1Hnd, meth2Hnd); } +CORINFO_CLASS_HANDLE interceptor_ICJI::getTypeDefinition( + CORINFO_CLASS_HANDLE type) +{ + return original_ICorJitInfo->getTypeDefinition(type); +} + CorInfoInline interceptor_ICJI::canInline( CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd) diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 2c0b79bab4fcd9..d0165f92f19dc6 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -96,6 +96,14 @@ bool MyICJI::haveSameMethodDefinition( return value; } +CORINFO_CLASS_HANDLE MyICJI::getTypeDefinition( + CORINFO_CLASS_HANDLE type) +{ + jitInstance->mc->cr->AddCall("getTypeDefinition"); + CORINFO_CLASS_HANDLE value = jitInstance->mc->repGetTypeDefinition(type); + return value; +} + // Decides if you have any limitations for inlining. If everything's OK, it will return // INLINE_PASS. // diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 5e6b0cbeeafdd1..73024ca54fef43 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -7936,6 +7936,37 @@ bool CEEInfo::haveSameMethodDefinition( return result; } +CORINFO_CLASS_HANDLE CEEInfo::getTypeDefinition(CORINFO_CLASS_HANDLE type) +{ + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } CONTRACTL_END; + + CORINFO_CLASS_HANDLE result = NULL; + + JIT_TO_EE_TRANSITION(); + + TypeHandle constructedHandle(type); + + _ASSERTE(constructedHandle.HasInstantiation()); + + TypeHandle definitionHandle = ClassLoader::LoadTypeDefThrowing( + constructedHandle.GetModule(), + constructedHandle.GetMethodTable()->GetCl(), + ClassLoader::ThrowIfNotFound, + ClassLoader::PermitUninstDefOrRef); + + result = CORINFO_CLASS_HANDLE(definitionHandle.AsPtr()); + + EE_TO_JIT_TRANSITION(); + + _ASSERTE(result != NULL); + + return result; +} + /************************************************************* * Check if the caller and calle are in the same assembly * i.e. do not inline across assemblies diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index 17e4636296c177..287c2efdd5e412 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -74,6 +74,7 @@ public bool IsInterface public virtual int GetArrayRank() => throw new NotSupportedException(SR.NotSupported_SubclassOverride); + [Intrinsic] public virtual Type GetGenericTypeDefinition() => throw new NotSupportedException(SR.NotSupported_SubclassOverride); public virtual Type[] GenericTypeArguments => (IsGenericType && !IsGenericTypeDefinition) ? GetGenericArguments() : EmptyTypes; public virtual Type[] GetGenericArguments() => throw new NotSupportedException(SR.NotSupported_SubclassOverride); diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs index 218f17e3d17932..c0a3f6eb0069f2 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs @@ -133,6 +133,7 @@ public static int TestEntryPoint() GetEnumUnderlyingType.TestGetEnumUnderlyingType(); IsPrimitiveTests(); + GetGenericTypeDefinitionTests(); return 100 + _errors; } @@ -186,6 +187,30 @@ private static void IsPrimitiveTests() IsFalse(typeof(Dictionary<,>).IsPrimitive); } + private static void GetGenericTypeDefinitionTests() + { + AreEqual(typeof(GenericEnumClass).GetGenericTypeDefinition(), typeof(GenericEnumClass<>)); + AreEqual(typeof(GenericEnumClass<>).GetGenericTypeDefinition(), typeof(GenericEnumClass<>)); + AreEqual(typeof(IGenericInterface).GetGenericTypeDefinition(), typeof(IGenericInterface<>)); + AreEqual(typeof(IGenericInterface<>).GetGenericTypeDefinition(), typeof(IGenericInterface<>)); + AreEqual(typeof(GenericStruct).GetGenericTypeDefinition(), typeof(GenericStruct<>)); + AreEqual(typeof(GenericStruct<>).GetGenericTypeDefinition(), typeof(GenericStruct<>)); + AreEqual(typeof(SimpleEnum?).GetGenericTypeDefinition(), typeof(Nullable<>)); + AreEqual(typeof(int?).GetGenericTypeDefinition(), typeof(Nullable<>)); + AreEqual(typeof(IntPtr?).GetGenericTypeDefinition(), typeof(Nullable<>)); + AreEqual(typeof(Nullable<>).GetGenericTypeDefinition(), typeof(Nullable<>)); + AreEqual(typeof(KeyValuePair).GetGenericTypeDefinition(), typeof(KeyValuePair<,>)); + AreEqual(typeof(KeyValuePair<,>).GetGenericTypeDefinition(), typeof(KeyValuePair<,>)); + AreEqual(typeof(Dictionary).GetGenericTypeDefinition(), typeof(Dictionary<,>)); + AreEqual(typeof(Dictionary<,>).GetGenericTypeDefinition(), typeof(Dictionary<,>)); + AreEqual(typeof(List).GetGenericTypeDefinition(), typeof(List<>)); + AreEqual(typeof(List<>).GetGenericTypeDefinition(), typeof(List<>)); + AreEqual(typeof(Action<>).GetGenericTypeDefinition(), typeof(Action<>)); + AreEqual(typeof(Action).GetGenericTypeDefinition(), typeof(Action<>)); + AreEqual(typeof(Func).GetGenericTypeDefinition(), typeof(Func<,>)); + AreEqual(typeof(Func<,>).GetGenericTypeDefinition(), typeof(Func<,>)); + } + private static int _varInt = 42; private static int? _varNullableInt = 42; private static decimal _varDecimal = 42M; @@ -239,6 +264,16 @@ static void IsFalse(bool expression, [CallerLineNumber] int line = 0, [CallerFil } } + [MethodImpl(MethodImplOptions.NoInlining)] + static void AreEqual(Type left, Type right, [CallerLineNumber] int line = 0, [CallerFilePath] string file = "") + { + if (left != right) + { + Console.WriteLine($"{file}:L{line} test failed (expected: '{left}' to be equal to '{right}')."); + _errors++; + } + } + static void ThrowsNRE(Action action, [CallerLineNumber] int line = 0, [CallerFilePath] string file = "") { try