From 168f8339b7faed89f57e84eb8e13e0fd884af005 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 8 Jun 2023 09:44:20 +0800 Subject: [PATCH 01/13] Import isinst Nullable as underlying type --- src/coreclr/jit/importer.cpp | 22 ++++++++++++++++------ src/coreclr/vm/jitinterface.cpp | 3 ++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index b0127eb4f0c703..b5223fc929f6ba 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -5422,9 +5422,19 @@ GenTree* Compiler::impCastClassOrIsInstToTree( { assert(op1->TypeGet() == TYP_REF); + // Import isinst Nullable as isinst V + CORINFO_CLASS_HANDLE hClass = info.compCompHnd->getTypeForBox(pResolvedToken->hClass); + + if (hClass != pResolvedToken->hClass) + { + // Convert nullable to underlying type + assert(op2->OperIsConst()); + op2 = gtNewIconEmbClsHndNode(hClass); + } + // Optimistically assume the jit should expand this as an inline test bool shouldExpandInline = true; - bool isClassExact = impIsClassExact(pResolvedToken->hClass); + bool isClassExact = impIsClassExact(hClass); // Profitability check. // @@ -5472,7 +5482,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree( CORINFO_CLASS_HANDLE actualImplCls = NO_CLASS_HANDLE; if (this->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && ((helper == CORINFO_HELP_ISINSTANCEOFINTERFACE) || (helper == CORINFO_HELP_CHKCASTINTERFACE)) && - (info.compCompHnd->getExactClasses(pResolvedToken->hClass, 1, &actualImplCls) == 1) && + (info.compCompHnd->getExactClasses(hClass, 1, &actualImplCls) == 1) && (actualImplCls != NO_CLASS_HANDLE) && impIsClassExact(actualImplCls)) { // if an interface has a single implementation on NativeAOT where we won't load new types, @@ -5490,7 +5500,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree( exactCls = actualImplCls; JITDUMP("'%s' interface has a single implementation - '%s', using that to inline isinst/castclass.", - eeGetClassName(pResolvedToken->hClass), eeGetClassName(actualImplCls)); + eeGetClassName(hClass), eeGetClassName(actualImplCls)); } else if (isCastClass) { @@ -5500,7 +5510,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree( // For ChkCastAny we ignore cases where the class is known to be abstract or is an interface. if (helper == CORINFO_HELP_CHKCASTANY) { - const bool isAbstract = (info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & + const bool isAbstract = (info.compCompHnd->getClassAttribs(hClass) & (CORINFO_FLG_INTERFACE | CORINFO_FLG_ABSTRACT)) != 0; canExpandInline = !isAbstract; } @@ -5543,7 +5553,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree( if ((likelyCls != NO_CLASS_HANDLE) && (likelyClass.likelihood > (UINT32)JitConfig.JitGuardedDevirtualizationChainLikelihood())) { - if ((info.compCompHnd->compareTypesForCast(likelyCls, pResolvedToken->hClass) == + if ((info.compCompHnd->compareTypesForCast(likelyCls, hClass) == TypeCompareState::Must)) { bool isAbstract = (info.compCompHnd->getClassAttribs(likelyCls) & @@ -5710,7 +5720,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree( assert(lclDsc->lvSingleDef == 0); lclDsc->lvSingleDef = 1; JITDUMP("Marked V%02u as a single def temp\n", tmp); - lvaSetClass(tmp, pResolvedToken->hClass); + lvaSetClass(tmp, hClass); return gtNewLclvNode(tmp, TYP_REF); } diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 15365a90216a84..517e72a25d3070 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -5990,9 +5990,10 @@ CorInfoHelpFunc CEEInfo::getCastingHelperStatic(TypeHandle clsHnd, bool fThrowin helper = CORINFO_HELP_ISINSTANCEOFARRAY; } else - if (!clsHnd.IsTypeDesc() && !Nullable::IsNullableType(clsHnd)) + if (!clsHnd.IsTypeDesc() && !(Nullable::IsNullableType(clsHnd) && fThrowing)) { // If it is a non-variant class, use the fast class helper + // Also use fast helper for isinst Nullable, which is equal to isinst of underlying type helper = CORINFO_HELP_ISINSTANCEOFCLASS; } else From e0cd0e2c4149fda8125d83388a0991c9186c4466 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 8 Jun 2023 22:57:17 +0800 Subject: [PATCH 02/13] Update JIT interface for getCastingHelper --- src/coreclr/inc/corinfo.h | 2 +- src/coreclr/inc/icorjitinfoimpl_generated.h | 2 +- src/coreclr/inc/jiteeversionguid.h | 10 +++++----- src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp | 4 ++-- src/coreclr/jit/importer.cpp | 2 +- .../tools/Common/JitInterface/CorInfoImpl_generated.cs | 6 +++--- .../Common/JitInterface/ThunkGenerator/ThunkInput.txt | 2 +- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 2 +- .../JitInterface/CorInfoImpl.RyuJit.cs | 4 ++-- .../tools/aot/jitinterface/jitinterface_generated.h | 6 +++--- .../tools/superpmi/superpmi-shared/methodcontext.cpp | 8 ++++---- .../tools/superpmi/superpmi-shared/methodcontext.h | 4 ++-- .../superpmi/superpmi-shim-collector/icorjitinfo.cpp | 6 +++--- .../superpmi-shim-counter/icorjitinfo_generated.cpp | 4 ++-- .../superpmi-shim-simple/icorjitinfo_generated.cpp | 4 ++-- src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp | 4 ++-- src/coreclr/vm/jitinterface.cpp | 9 ++++----- 17 files changed, 39 insertions(+), 40 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 04a8f2fb898d4d..b4b5e208fa0c37 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2459,7 +2459,7 @@ class ICorStaticInfo // returns the optimized "IsInstanceOf" or "ChkCast" helper virtual CorInfoHelpFunc getCastingHelper( - CORINFO_RESOLVED_TOKEN * pResolvedToken, + CORINFO_CLASS_HANDLE clsHnd, bool fThrowing ) = 0; diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index f3d93194df2588..43267b7d074e10 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -277,7 +277,7 @@ CorInfoHelpFunc getNewArrHelper( CORINFO_CLASS_HANDLE arrayCls) override; CorInfoHelpFunc getCastingHelper( - CORINFO_RESOLVED_TOKEN* pResolvedToken, + CORINFO_CLASS_HANDLE clsHnd, bool fThrowing) override; CorInfoHelpFunc getSharedCCtorHelper( diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index ebcf4919cb6afb..e497c0178ca94e 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 = { /* fda2f9dd-6b3e-4ecd-a7b8-79e5edf1f072 */ - 0xfda2f9dd, - 0x6b3e, - 0x4ecd, - {0xa7, 0xb8, 0x79, 0xe5, 0xed, 0xf1, 0xf0, 0x72} +constexpr GUID JITEEVersionIdentifier = { /* fb0ea359-ee8d-44f0-9418-a9b007d1935d */ + 0xfb0ea359, + 0xee8d, + 0x44f0, + {0x94, 0x18, 0xa9, 0xb0, 0x7, 0xd1, 0x93, 0x5d} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index da369eda01a370..b347e6e328ae6f 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -631,11 +631,11 @@ CorInfoHelpFunc WrapICorJitInfo::getNewArrHelper( } CorInfoHelpFunc WrapICorJitInfo::getCastingHelper( - CORINFO_RESOLVED_TOKEN* pResolvedToken, + CORINFO_CLASS_HANDLE clsHnd, bool fThrowing) { API_ENTER(getCastingHelper); - CorInfoHelpFunc temp = wrapHnd->getCastingHelper(pResolvedToken, fThrowing); + CorInfoHelpFunc temp = wrapHnd->getCastingHelper(clsHnd, fThrowing); API_LEAVE(getCastingHelper); return temp; } diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index b5223fc929f6ba..acc74edf01680b 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -5469,7 +5469,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree( // Pessimistically assume the jit cannot expand this as an inline test bool canExpandInline = false; bool partialExpand = false; - const CorInfoHelpFunc helper = info.compCompHnd->getCastingHelper(pResolvedToken, isCastClass); + const CorInfoHelpFunc helper = info.compCompHnd->getCastingHelper(hClass, isCastClass); CORINFO_CLASS_HANDLE exactCls = NO_CLASS_HANDLE; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 772a97e0cfb822..8a83541cb20b47 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -943,12 +943,12 @@ private static CorInfoHelpFunc _getNewArrHelper(IntPtr thisHandle, IntPtr* ppExc } [UnmanagedCallersOnly] - private static CorInfoHelpFunc _getCastingHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, byte fThrowing) + private static CorInfoHelpFunc _getCastingHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* clsHnd, byte fThrowing) { var _this = GetThis(thisHandle); try { - return _this.getCastingHelper(ref *pResolvedToken, fThrowing != 0); + return _this.getCastingHelper(clsHnd, fThrowing != 0); } catch (Exception ex) { @@ -2722,7 +2722,7 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[60] = (delegate* unmanaged)&_checkMethodModifier; callbacks[61] = (delegate* unmanaged)&_getNewHelper; callbacks[62] = (delegate* unmanaged)&_getNewArrHelper; - callbacks[63] = (delegate* unmanaged)&_getCastingHelper; + callbacks[63] = (delegate* unmanaged)&_getCastingHelper; callbacks[64] = (delegate* unmanaged)&_getSharedCCtorHelper; callbacks[65] = (delegate* unmanaged)&_getTypeForBox; callbacks[66] = (delegate* unmanaged)&_getBoxHelper; diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 89d87da12f848e..fb0567f9f11734 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -222,7 +222,7 @@ FUNCTIONS bool checkMethodModifier(CORINFO_METHOD_HANDLE hMethod, const char * modifier, bool fOptional) CorInfoHelpFunc getNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, bool* pHasSideEffects) CorInfoHelpFunc getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls) - CorInfoHelpFunc getCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing) + CorInfoHelpFunc getCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing) CorInfoHelpFunc getSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd) CORINFO_CLASS_HANDLE getTypeForBox(CORINFO_CLASS_HANDLE cls) CorInfoHelpFunc getBoxHelper(CORINFO_CLASS_HANDLE cls) diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 6744603dcb2288..1af6665b632324 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -1433,7 +1433,7 @@ private void PublishEmptyCode() _methodCodeNode.InitializeColdFrameInfos(Array.Empty()); } - private CorInfoHelpFunc getCastingHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fThrowing) + private CorInfoHelpFunc getCastingHelper(CORINFO_CLASS_STRUCT_* clsHnd, bool fThrowing) { return fThrowing ? CorInfoHelpFunc.CORINFO_HELP_CHKCASTANY : CorInfoHelpFunc.CORINFO_HELP_ISINSTANCEOFANY; } diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index 78325206266a73..fd790efafa2e8c 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -1033,9 +1033,9 @@ private ISymbolNode GetGenericLookupHelper(CORINFO_RUNTIME_LOOKUP_KIND runtimeLo return _compilation.NodeFactory.ReadyToRunHelperFromDictionaryLookup(helperId, helperArgument, MethodBeingCompiled); } - private CorInfoHelpFunc getCastingHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fThrowing) + private CorInfoHelpFunc getCastingHelper(CORINFO_CLASS_STRUCT_* clsHnd, bool fThrowing) { - TypeDesc type = HandleToObject(pResolvedToken.hClass); + TypeDesc type = HandleToObject(clsHnd); CorInfoHelpFunc helper; diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index 56fb164b359563..8cf2448bf70871 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -74,7 +74,7 @@ struct JitInterfaceCallbacks bool (* checkMethodModifier)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE hMethod, const char* modifier, bool fOptional); CorInfoHelpFunc (* getNewHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, bool* pHasSideEffects); CorInfoHelpFunc (* getNewArrHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE arrayCls); - CorInfoHelpFunc (* getCastingHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing); + CorInfoHelpFunc (* getCastingHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE clsHnd, bool fThrowing); CorInfoHelpFunc (* getSharedCCtorHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE clsHnd); CORINFO_CLASS_HANDLE (* getTypeForBox)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); CorInfoHelpFunc (* getBoxHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); @@ -824,11 +824,11 @@ class JitInterfaceWrapper : public ICorJitInfo } virtual CorInfoHelpFunc getCastingHelper( - CORINFO_RESOLVED_TOKEN* pResolvedToken, + CORINFO_CLASS_HANDLE clsHnd, bool fThrowing) { CorInfoExceptionClass* pException = nullptr; - CorInfoHelpFunc temp = _callbacks->getCastingHelper(_thisHandle, &pException, pResolvedToken, fThrowing); + CorInfoHelpFunc temp = _callbacks->getCastingHelper(_thisHandle, &pException, clsHnd, fThrowing); if (pException != nullptr) throw pException; return temp; } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 70378310e449a3..dd8af3a21065f8 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -3995,14 +3995,14 @@ CorInfoIsAccessAllowedResult MethodContext::repCanAccessClass(CORINFO_RESOLVED_T return temp; } -void MethodContext::recGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing, CorInfoHelpFunc result) +void MethodContext::recGetCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing, CorInfoHelpFunc result) { if (GetCastingHelper == nullptr) GetCastingHelper = new LightWeightMap(); Agnostic_GetCastingHelper key; ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.hClass = CastHandle(pResolvedToken->hClass); + key.hClass = CastHandle(clsHnd); key.fThrowing = (DWORD)fThrowing; DWORD value = (DWORD)result; @@ -4013,11 +4013,11 @@ void MethodContext::dmpGetCastingHelper(const Agnostic_GetCastingHelper& key, DW { printf("GetCastingHelper key cls-%016" PRIX64 ", thw-%u, value res-%u", key.hClass, key.fThrowing, value); } -CorInfoHelpFunc MethodContext::repGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing) +CorInfoHelpFunc MethodContext::repGetCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing) { Agnostic_GetCastingHelper key; ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.hClass = CastHandle(pResolvedToken->hClass); + key.hClass = CastHandle(clsHnd); key.fThrowing = (DWORD)fThrowing; DWORD value = LookupByKeyOrMiss(GetCastingHelper, key, ": key %016" PRIX64 "", key.hClass); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index e6dacd31f2a3ca..5f9b1dfc0dba23 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -526,9 +526,9 @@ class MethodContext CORINFO_METHOD_HANDLE callerHandle, CORINFO_HELPER_DESC* pAccessHelper); - void recGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing, CorInfoHelpFunc result); + void recGetCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing, CorInfoHelpFunc result); void dmpGetCastingHelper(const Agnostic_GetCastingHelper& key, DWORD value); - CorInfoHelpFunc repGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing); + CorInfoHelpFunc repGetCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing); void recEmbedModuleHandle(CORINFO_MODULE_HANDLE handle, void** ppIndirection, CORINFO_MODULE_HANDLE result); void dmpEmbedModuleHandle(DWORDLONG key, DLDL value); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index c746be1fe5bd69..e7a9877835a1a2 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -711,11 +711,11 @@ CorInfoHelpFunc interceptor_ICJI::getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls) } // returns the optimized "IsInstanceOf" or "ChkCast" helper -CorInfoHelpFunc interceptor_ICJI::getCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing) +CorInfoHelpFunc interceptor_ICJI::getCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing) { mc->cr->AddCall("getCastingHelper"); - CorInfoHelpFunc temp = original_ICorJitInfo->getCastingHelper(pResolvedToken, fThrowing); - mc->recGetCastingHelper(pResolvedToken, fThrowing, temp); + CorInfoHelpFunc temp = original_ICorJitInfo->getCastingHelper(clsHnd, fThrowing); + mc->recGetCastingHelper(clsHnd, fThrowing, temp); return temp; } 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 6d301f516f60b0..27dd353ea5f202 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -520,11 +520,11 @@ CorInfoHelpFunc interceptor_ICJI::getNewArrHelper( } CorInfoHelpFunc interceptor_ICJI::getCastingHelper( - CORINFO_RESOLVED_TOKEN* pResolvedToken, + CORINFO_CLASS_HANDLE clsHnd, bool fThrowing) { mcs->AddCall("getCastingHelper"); - return original_ICorJitInfo->getCastingHelper(pResolvedToken, fThrowing); + return original_ICorJitInfo->getCastingHelper(clsHnd, fThrowing); } CorInfoHelpFunc interceptor_ICJI::getSharedCCtorHelper( 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 7dd611b5283dc4..f9444930dd23a9 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -457,10 +457,10 @@ CorInfoHelpFunc interceptor_ICJI::getNewArrHelper( } CorInfoHelpFunc interceptor_ICJI::getCastingHelper( - CORINFO_RESOLVED_TOKEN* pResolvedToken, + CORINFO_CLASS_HANDLE clsHnd, bool fThrowing) { - return original_ICorJitInfo->getCastingHelper(pResolvedToken, fThrowing); + return original_ICorJitInfo->getCastingHelper(clsHnd, fThrowing); } CorInfoHelpFunc interceptor_ICJI::getSharedCCtorHelper( diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 16d52438b6c405..8db1961937fe96 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -598,10 +598,10 @@ CorInfoHelpFunc MyICJI::getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls) } // returns the optimized "IsInstanceOf" or "ChkCast" helper -CorInfoHelpFunc MyICJI::getCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing) +CorInfoHelpFunc MyICJI::getCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing) { jitInstance->mc->cr->AddCall("getCastingHelper"); - return jitInstance->mc->repGetCastingHelper(pResolvedToken, fThrowing); + return jitInstance->mc->repGetCastingHelper(clsHnd, fThrowing); } // returns helper to trigger static constructor diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 517e72a25d3070..e7b00611beeb5a 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -5914,7 +5914,7 @@ CorInfoHelpFunc CEEInfo::getNewArrHelperStatic(TypeHandle clsHnd) } /***********************************************************************/ -CorInfoHelpFunc CEEInfo::getCastingHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fThrowing) +CorInfoHelpFunc CEEInfo::getCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing) { CONTRACTL { THROWS; @@ -5927,9 +5927,9 @@ CorInfoHelpFunc CEEInfo::getCastingHelper(CORINFO_RESOLVED_TOKEN * pResolvedToke JIT_TO_EE_TRANSITION(); bool fClassMustBeRestored; - result = getCastingHelperStatic(TypeHandle(pResolvedToken->hClass), fThrowing, &fClassMustBeRestored); + result = getCastingHelperStatic(TypeHandle(clsHnd), fThrowing, &fClassMustBeRestored); if (fClassMustBeRestored) - classMustBeLoadedBeforeCodeIsRun(pResolvedToken->hClass); + classMustBeLoadedBeforeCodeIsRun(clsHnd); EE_TO_JIT_TRANSITION(); @@ -5990,10 +5990,9 @@ CorInfoHelpFunc CEEInfo::getCastingHelperStatic(TypeHandle clsHnd, bool fThrowin helper = CORINFO_HELP_ISINSTANCEOFARRAY; } else - if (!clsHnd.IsTypeDesc() && !(Nullable::IsNullableType(clsHnd) && fThrowing)) + if (!clsHnd.IsTypeDesc() && !Nullable::IsNullableType(clsHnd)) { // If it is a non-variant class, use the fast class helper - // Also use fast helper for isinst Nullable, which is equal to isinst of underlying type helper = CORINFO_HELP_ISINSTANCEOFCLASS; } else From 8522424cf135e18f224d3d200b871adae6b41628 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 9 Jun 2023 11:03:16 +0800 Subject: [PATCH 03/13] Revert --- src/coreclr/inc/corinfo.h | 2 +- src/coreclr/inc/icorjitinfoimpl_generated.h | 2 +- src/coreclr/inc/jiteeversionguid.h | 10 ++++---- .../jit/ICorJitInfo_wrapper_generated.hpp | 4 ++-- src/coreclr/jit/importer.cpp | 24 ++++++------------- .../JitInterface/CorInfoImpl_generated.cs | 6 ++--- .../ThunkGenerator/ThunkInput.txt | 2 +- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 2 +- .../JitInterface/CorInfoImpl.RyuJit.cs | 4 ++-- .../aot/jitinterface/jitinterface_generated.h | 6 ++--- .../superpmi-shared/methodcontext.cpp | 8 +++---- .../superpmi/superpmi-shared/methodcontext.h | 4 ++-- .../superpmi-shim-collector/icorjitinfo.cpp | 6 ++--- .../icorjitinfo_generated.cpp | 4 ++-- .../icorjitinfo_generated.cpp | 4 ++-- .../tools/superpmi/superpmi/icorjitinfo.cpp | 4 ++-- src/coreclr/vm/jitinterface.cpp | 6 ++--- 17 files changed, 44 insertions(+), 54 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index b4b5e208fa0c37..04a8f2fb898d4d 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2459,7 +2459,7 @@ class ICorStaticInfo // returns the optimized "IsInstanceOf" or "ChkCast" helper virtual CorInfoHelpFunc getCastingHelper( - CORINFO_CLASS_HANDLE clsHnd, + CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fThrowing ) = 0; diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index 43267b7d074e10..f3d93194df2588 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -277,7 +277,7 @@ CorInfoHelpFunc getNewArrHelper( CORINFO_CLASS_HANDLE arrayCls) override; CorInfoHelpFunc getCastingHelper( - CORINFO_CLASS_HANDLE clsHnd, + CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing) override; CorInfoHelpFunc getSharedCCtorHelper( diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index e497c0178ca94e..ebcf4919cb6afb 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 = { /* fb0ea359-ee8d-44f0-9418-a9b007d1935d */ - 0xfb0ea359, - 0xee8d, - 0x44f0, - {0x94, 0x18, 0xa9, 0xb0, 0x7, 0xd1, 0x93, 0x5d} +constexpr GUID JITEEVersionIdentifier = { /* fda2f9dd-6b3e-4ecd-a7b8-79e5edf1f072 */ + 0xfda2f9dd, + 0x6b3e, + 0x4ecd, + {0xa7, 0xb8, 0x79, 0xe5, 0xed, 0xf1, 0xf0, 0x72} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index b347e6e328ae6f..da369eda01a370 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -631,11 +631,11 @@ CorInfoHelpFunc WrapICorJitInfo::getNewArrHelper( } CorInfoHelpFunc WrapICorJitInfo::getCastingHelper( - CORINFO_CLASS_HANDLE clsHnd, + CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing) { API_ENTER(getCastingHelper); - CorInfoHelpFunc temp = wrapHnd->getCastingHelper(clsHnd, fThrowing); + CorInfoHelpFunc temp = wrapHnd->getCastingHelper(pResolvedToken, fThrowing); API_LEAVE(getCastingHelper); return temp; } diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index acc74edf01680b..b0127eb4f0c703 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -5422,19 +5422,9 @@ GenTree* Compiler::impCastClassOrIsInstToTree( { assert(op1->TypeGet() == TYP_REF); - // Import isinst Nullable as isinst V - CORINFO_CLASS_HANDLE hClass = info.compCompHnd->getTypeForBox(pResolvedToken->hClass); - - if (hClass != pResolvedToken->hClass) - { - // Convert nullable to underlying type - assert(op2->OperIsConst()); - op2 = gtNewIconEmbClsHndNode(hClass); - } - // Optimistically assume the jit should expand this as an inline test bool shouldExpandInline = true; - bool isClassExact = impIsClassExact(hClass); + bool isClassExact = impIsClassExact(pResolvedToken->hClass); // Profitability check. // @@ -5469,7 +5459,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree( // Pessimistically assume the jit cannot expand this as an inline test bool canExpandInline = false; bool partialExpand = false; - const CorInfoHelpFunc helper = info.compCompHnd->getCastingHelper(hClass, isCastClass); + const CorInfoHelpFunc helper = info.compCompHnd->getCastingHelper(pResolvedToken, isCastClass); CORINFO_CLASS_HANDLE exactCls = NO_CLASS_HANDLE; @@ -5482,7 +5472,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree( CORINFO_CLASS_HANDLE actualImplCls = NO_CLASS_HANDLE; if (this->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && ((helper == CORINFO_HELP_ISINSTANCEOFINTERFACE) || (helper == CORINFO_HELP_CHKCASTINTERFACE)) && - (info.compCompHnd->getExactClasses(hClass, 1, &actualImplCls) == 1) && + (info.compCompHnd->getExactClasses(pResolvedToken->hClass, 1, &actualImplCls) == 1) && (actualImplCls != NO_CLASS_HANDLE) && impIsClassExact(actualImplCls)) { // if an interface has a single implementation on NativeAOT where we won't load new types, @@ -5500,7 +5490,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree( exactCls = actualImplCls; JITDUMP("'%s' interface has a single implementation - '%s', using that to inline isinst/castclass.", - eeGetClassName(hClass), eeGetClassName(actualImplCls)); + eeGetClassName(pResolvedToken->hClass), eeGetClassName(actualImplCls)); } else if (isCastClass) { @@ -5510,7 +5500,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree( // For ChkCastAny we ignore cases where the class is known to be abstract or is an interface. if (helper == CORINFO_HELP_CHKCASTANY) { - const bool isAbstract = (info.compCompHnd->getClassAttribs(hClass) & + const bool isAbstract = (info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & (CORINFO_FLG_INTERFACE | CORINFO_FLG_ABSTRACT)) != 0; canExpandInline = !isAbstract; } @@ -5553,7 +5543,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree( if ((likelyCls != NO_CLASS_HANDLE) && (likelyClass.likelihood > (UINT32)JitConfig.JitGuardedDevirtualizationChainLikelihood())) { - if ((info.compCompHnd->compareTypesForCast(likelyCls, hClass) == + if ((info.compCompHnd->compareTypesForCast(likelyCls, pResolvedToken->hClass) == TypeCompareState::Must)) { bool isAbstract = (info.compCompHnd->getClassAttribs(likelyCls) & @@ -5720,7 +5710,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree( assert(lclDsc->lvSingleDef == 0); lclDsc->lvSingleDef = 1; JITDUMP("Marked V%02u as a single def temp\n", tmp); - lvaSetClass(tmp, hClass); + lvaSetClass(tmp, pResolvedToken->hClass); return gtNewLclvNode(tmp, TYP_REF); } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 8a83541cb20b47..772a97e0cfb822 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -943,12 +943,12 @@ private static CorInfoHelpFunc _getNewArrHelper(IntPtr thisHandle, IntPtr* ppExc } [UnmanagedCallersOnly] - private static CorInfoHelpFunc _getCastingHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* clsHnd, byte fThrowing) + private static CorInfoHelpFunc _getCastingHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, byte fThrowing) { var _this = GetThis(thisHandle); try { - return _this.getCastingHelper(clsHnd, fThrowing != 0); + return _this.getCastingHelper(ref *pResolvedToken, fThrowing != 0); } catch (Exception ex) { @@ -2722,7 +2722,7 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[60] = (delegate* unmanaged)&_checkMethodModifier; callbacks[61] = (delegate* unmanaged)&_getNewHelper; callbacks[62] = (delegate* unmanaged)&_getNewArrHelper; - callbacks[63] = (delegate* unmanaged)&_getCastingHelper; + callbacks[63] = (delegate* unmanaged)&_getCastingHelper; callbacks[64] = (delegate* unmanaged)&_getSharedCCtorHelper; callbacks[65] = (delegate* unmanaged)&_getTypeForBox; callbacks[66] = (delegate* unmanaged)&_getBoxHelper; diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index fb0567f9f11734..89d87da12f848e 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -222,7 +222,7 @@ FUNCTIONS bool checkMethodModifier(CORINFO_METHOD_HANDLE hMethod, const char * modifier, bool fOptional) CorInfoHelpFunc getNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, bool* pHasSideEffects) CorInfoHelpFunc getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls) - CorInfoHelpFunc getCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing) + CorInfoHelpFunc getCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing) CorInfoHelpFunc getSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd) CORINFO_CLASS_HANDLE getTypeForBox(CORINFO_CLASS_HANDLE cls) CorInfoHelpFunc getBoxHelper(CORINFO_CLASS_HANDLE cls) diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 1af6665b632324..6744603dcb2288 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -1433,7 +1433,7 @@ private void PublishEmptyCode() _methodCodeNode.InitializeColdFrameInfos(Array.Empty()); } - private CorInfoHelpFunc getCastingHelper(CORINFO_CLASS_STRUCT_* clsHnd, bool fThrowing) + private CorInfoHelpFunc getCastingHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fThrowing) { return fThrowing ? CorInfoHelpFunc.CORINFO_HELP_CHKCASTANY : CorInfoHelpFunc.CORINFO_HELP_ISINSTANCEOFANY; } diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index fd790efafa2e8c..78325206266a73 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -1033,9 +1033,9 @@ private ISymbolNode GetGenericLookupHelper(CORINFO_RUNTIME_LOOKUP_KIND runtimeLo return _compilation.NodeFactory.ReadyToRunHelperFromDictionaryLookup(helperId, helperArgument, MethodBeingCompiled); } - private CorInfoHelpFunc getCastingHelper(CORINFO_CLASS_STRUCT_* clsHnd, bool fThrowing) + private CorInfoHelpFunc getCastingHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fThrowing) { - TypeDesc type = HandleToObject(clsHnd); + TypeDesc type = HandleToObject(pResolvedToken.hClass); CorInfoHelpFunc helper; diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index 8cf2448bf70871..56fb164b359563 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -74,7 +74,7 @@ struct JitInterfaceCallbacks bool (* checkMethodModifier)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE hMethod, const char* modifier, bool fOptional); CorInfoHelpFunc (* getNewHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, bool* pHasSideEffects); CorInfoHelpFunc (* getNewArrHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE arrayCls); - CorInfoHelpFunc (* getCastingHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE clsHnd, bool fThrowing); + CorInfoHelpFunc (* getCastingHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing); CorInfoHelpFunc (* getSharedCCtorHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE clsHnd); CORINFO_CLASS_HANDLE (* getTypeForBox)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); CorInfoHelpFunc (* getBoxHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); @@ -824,11 +824,11 @@ class JitInterfaceWrapper : public ICorJitInfo } virtual CorInfoHelpFunc getCastingHelper( - CORINFO_CLASS_HANDLE clsHnd, + CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing) { CorInfoExceptionClass* pException = nullptr; - CorInfoHelpFunc temp = _callbacks->getCastingHelper(_thisHandle, &pException, clsHnd, fThrowing); + CorInfoHelpFunc temp = _callbacks->getCastingHelper(_thisHandle, &pException, pResolvedToken, fThrowing); if (pException != nullptr) throw pException; return temp; } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index dd8af3a21065f8..70378310e449a3 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -3995,14 +3995,14 @@ CorInfoIsAccessAllowedResult MethodContext::repCanAccessClass(CORINFO_RESOLVED_T return temp; } -void MethodContext::recGetCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing, CorInfoHelpFunc result) +void MethodContext::recGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing, CorInfoHelpFunc result) { if (GetCastingHelper == nullptr) GetCastingHelper = new LightWeightMap(); Agnostic_GetCastingHelper key; ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.hClass = CastHandle(clsHnd); + key.hClass = CastHandle(pResolvedToken->hClass); key.fThrowing = (DWORD)fThrowing; DWORD value = (DWORD)result; @@ -4013,11 +4013,11 @@ void MethodContext::dmpGetCastingHelper(const Agnostic_GetCastingHelper& key, DW { printf("GetCastingHelper key cls-%016" PRIX64 ", thw-%u, value res-%u", key.hClass, key.fThrowing, value); } -CorInfoHelpFunc MethodContext::repGetCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing) +CorInfoHelpFunc MethodContext::repGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing) { Agnostic_GetCastingHelper key; ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.hClass = CastHandle(clsHnd); + key.hClass = CastHandle(pResolvedToken->hClass); key.fThrowing = (DWORD)fThrowing; DWORD value = LookupByKeyOrMiss(GetCastingHelper, key, ": key %016" PRIX64 "", key.hClass); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 5f9b1dfc0dba23..e6dacd31f2a3ca 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -526,9 +526,9 @@ class MethodContext CORINFO_METHOD_HANDLE callerHandle, CORINFO_HELPER_DESC* pAccessHelper); - void recGetCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing, CorInfoHelpFunc result); + void recGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing, CorInfoHelpFunc result); void dmpGetCastingHelper(const Agnostic_GetCastingHelper& key, DWORD value); - CorInfoHelpFunc repGetCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing); + CorInfoHelpFunc repGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing); void recEmbedModuleHandle(CORINFO_MODULE_HANDLE handle, void** ppIndirection, CORINFO_MODULE_HANDLE result); void dmpEmbedModuleHandle(DWORDLONG key, DLDL value); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index e7a9877835a1a2..c746be1fe5bd69 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -711,11 +711,11 @@ CorInfoHelpFunc interceptor_ICJI::getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls) } // returns the optimized "IsInstanceOf" or "ChkCast" helper -CorInfoHelpFunc interceptor_ICJI::getCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing) +CorInfoHelpFunc interceptor_ICJI::getCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing) { mc->cr->AddCall("getCastingHelper"); - CorInfoHelpFunc temp = original_ICorJitInfo->getCastingHelper(clsHnd, fThrowing); - mc->recGetCastingHelper(clsHnd, fThrowing, temp); + CorInfoHelpFunc temp = original_ICorJitInfo->getCastingHelper(pResolvedToken, fThrowing); + mc->recGetCastingHelper(pResolvedToken, fThrowing, temp); return temp; } 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 27dd353ea5f202..6d301f516f60b0 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -520,11 +520,11 @@ CorInfoHelpFunc interceptor_ICJI::getNewArrHelper( } CorInfoHelpFunc interceptor_ICJI::getCastingHelper( - CORINFO_CLASS_HANDLE clsHnd, + CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing) { mcs->AddCall("getCastingHelper"); - return original_ICorJitInfo->getCastingHelper(clsHnd, fThrowing); + return original_ICorJitInfo->getCastingHelper(pResolvedToken, fThrowing); } CorInfoHelpFunc interceptor_ICJI::getSharedCCtorHelper( 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 f9444930dd23a9..7dd611b5283dc4 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -457,10 +457,10 @@ CorInfoHelpFunc interceptor_ICJI::getNewArrHelper( } CorInfoHelpFunc interceptor_ICJI::getCastingHelper( - CORINFO_CLASS_HANDLE clsHnd, + CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing) { - return original_ICorJitInfo->getCastingHelper(clsHnd, fThrowing); + return original_ICorJitInfo->getCastingHelper(pResolvedToken, fThrowing); } CorInfoHelpFunc interceptor_ICJI::getSharedCCtorHelper( diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 8db1961937fe96..16d52438b6c405 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -598,10 +598,10 @@ CorInfoHelpFunc MyICJI::getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls) } // returns the optimized "IsInstanceOf" or "ChkCast" helper -CorInfoHelpFunc MyICJI::getCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing) +CorInfoHelpFunc MyICJI::getCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing) { jitInstance->mc->cr->AddCall("getCastingHelper"); - return jitInstance->mc->repGetCastingHelper(clsHnd, fThrowing); + return jitInstance->mc->repGetCastingHelper(pResolvedToken, fThrowing); } // returns helper to trigger static constructor diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index e7b00611beeb5a..15365a90216a84 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -5914,7 +5914,7 @@ CorInfoHelpFunc CEEInfo::getNewArrHelperStatic(TypeHandle clsHnd) } /***********************************************************************/ -CorInfoHelpFunc CEEInfo::getCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThrowing) +CorInfoHelpFunc CEEInfo::getCastingHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fThrowing) { CONTRACTL { THROWS; @@ -5927,9 +5927,9 @@ CorInfoHelpFunc CEEInfo::getCastingHelper(CORINFO_CLASS_HANDLE clsHnd, bool fThr JIT_TO_EE_TRANSITION(); bool fClassMustBeRestored; - result = getCastingHelperStatic(TypeHandle(clsHnd), fThrowing, &fClassMustBeRestored); + result = getCastingHelperStatic(TypeHandle(pResolvedToken->hClass), fThrowing, &fClassMustBeRestored); if (fClassMustBeRestored) - classMustBeLoadedBeforeCodeIsRun(clsHnd); + classMustBeLoadedBeforeCodeIsRun(pResolvedToken->hClass); EE_TO_JIT_TRANSITION(); From c7224841dc4f5e36c2218e246fabd4194af7916b Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 9 Jun 2023 12:08:20 +0800 Subject: [PATCH 04/13] Resolve nullable as underlying type when CORINFO_TOKENKIND_Casting --- src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs | 8 ++++++++ src/coreclr/vm/jitinterface.cpp | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 30f0b145a18641..8abc4507e1aa6b 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1789,6 +1789,14 @@ private void resolveToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken) type = type.MakeArrayType(); } + else if (pResolvedToken.tokenType == CorInfoTokenKind.CORINFO_TOKENKIND_Casting) + { + if (type.IsVoid) + ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramSpecific, methodIL.OwningMethod); + + if (type.IsNullable) + type = type.Instantiation[0]; + } pResolvedToken.hClass = ObjectToHandle(type); #if !SUPPORT_JIT diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 15365a90216a84..7992b107b600f4 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1170,6 +1170,16 @@ void CEEInfo::resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken th = ClassLoader::LoadArrayTypeThrowing(th); break; + case CORINFO_TOKENKIND_Casting: + // Disallow ELEMENT_TYPE_BYREF and ELEMENT_TYPE_VOID + if (et == ELEMENT_TYPE_BYREF || et == ELEMENT_TYPE_VOID) + COMPlusThrow(kInvalidProgramException); + + // isinst and castclass to Nullable is same as underlying type + if (Nullable::IsNullableType(th)) + th = th.AsMethodTable()->GetInstantiation()[0]; + break; + default: // Disallow ELEMENT_TYPE_BYREF and ELEMENT_TYPE_VOID if (et == ELEMENT_TYPE_BYREF || et == ELEMENT_TYPE_VOID) From 8e5392ae41a3824bc852d833130bd53bcc171e21 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 9 Jun 2023 18:47:05 +0800 Subject: [PATCH 05/13] Simplify token validation --- src/coreclr/vm/jitinterface.cpp | 42 +++++++++++++-------------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 7992b107b600f4..dd46aa5645afb1 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1156,35 +1156,25 @@ void CEEInfo::resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken // tokenType specific verification and transformations // CorElementType et = th.GetInternalCorElementType(); - switch (tokenType) - { - case CORINFO_TOKENKIND_Ldtoken: - // Allow everything. - break; - case CORINFO_TOKENKIND_Newarr: - // Disallow ELEMENT_TYPE_BYREF and ELEMENT_TYPE_VOID - if (et == ELEMENT_TYPE_BYREF || et == ELEMENT_TYPE_VOID) - COMPlusThrow(kInvalidProgramException); - - th = ClassLoader::LoadArrayTypeThrowing(th); - break; - - case CORINFO_TOKENKIND_Casting: - // Disallow ELEMENT_TYPE_BYREF and ELEMENT_TYPE_VOID - if (et == ELEMENT_TYPE_BYREF || et == ELEMENT_TYPE_VOID) - COMPlusThrow(kInvalidProgramException); + if (tokenType != CORINFO_TOKENKIND_Ldtoken) + { + // Disallow ELEMENT_TYPE_BYREF and ELEMENT_TYPE_VOID + if (et == ELEMENT_TYPE_BYREF || et == ELEMENT_TYPE_VOID) + COMPlusThrow(kInvalidProgramException); - // isinst and castclass to Nullable is same as underlying type - if (Nullable::IsNullableType(th)) - th = th.AsMethodTable()->GetInstantiation()[0]; - break; + switch (tokenType) + { + case CORINFO_TOKENKIND_Newarr: + th = ClassLoader::LoadArrayTypeThrowing(th); + break; - default: - // Disallow ELEMENT_TYPE_BYREF and ELEMENT_TYPE_VOID - if (et == ELEMENT_TYPE_BYREF || et == ELEMENT_TYPE_VOID) - COMPlusThrow(kInvalidProgramException); - break; + case CORINFO_TOKENKIND_Casting: + // isinst and castclass to Nullable is same as underlying type + if (Nullable::IsNullableType(th)) + th = th.AsMethodTable()->GetInstantiation()[0]; + break; + } } // The JIT interface should always return fully loaded types From 3ddd0ea39fb8628836269eda995244c80ceae289 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 9 Jun 2023 21:02:33 +0800 Subject: [PATCH 06/13] Switch exhaustiveness --- src/coreclr/vm/jitinterface.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index dd46aa5645afb1..da174771a0f382 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1174,6 +1174,10 @@ void CEEInfo::resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken if (Nullable::IsNullableType(th)) th = th.AsMethodTable()->GetInstantiation()[0]; break; + + default: + // No additional checks. Satisfy switch exhaustiveness check. + break; } } From 3e5822953a977a9ef45773aa84b1a77d04771ef4 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 10 Jun 2023 01:24:17 +0800 Subject: [PATCH 07/13] IL test coverage for castclass --- .../JIT/opt/Casts/castclass_valuetype.il | 60 +++++++++++++++++++ .../JIT/opt/Casts/castclass_valuetype.ilproj | 11 ++++ 2 files changed, 71 insertions(+) create mode 100644 src/tests/JIT/opt/Casts/castclass_valuetype.il create mode 100644 src/tests/JIT/opt/Casts/castclass_valuetype.ilproj diff --git a/src/tests/JIT/opt/Casts/castclass_valuetype.il b/src/tests/JIT/opt/Casts/castclass_valuetype.il new file mode 100644 index 00000000000000..a13583f258e254 --- /dev/null +++ b/src/tests/JIT/opt/Casts/castclass_valuetype.il @@ -0,0 +1,60 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + + +.assembly extern mscorlib { auto } +.assembly extern xunit.core {} +.assembly extern System.Console { auto } +.assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) } + +.assembly 'castclass_valuetype' { } + +.class public auto Program extends [System.Runtime]System.Object +{ + .method public hidebysig static int32 Main() cil managed + { + .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( + 01 00 00 00 + ) + .entrypoint + .maxstack 8 + + .try + { + // castclass valuetype + ldc.i4.s 1234 + box [System.Runtime]System.Int32 + castclass [System.Runtime]System.Int32 + unbox [System.Runtime]System.Int32 + call void [System.Runtime]System.Int32::ToString() + call void [System.Console]System.Console::WriteLine(class [System.Runtime]System.String) + + // castclass nullable + ldc.i4.s 1234 + box [System.Runtime]System.Int32 + castclass valuetype [System.Runtime]System.Nullable`1<[System.Runtime]System.Int32> + unbox [System.Runtime]System.Int32 + call void [System.Runtime]System.Int32::ToString() + call void [System.Console]System.Console::WriteLine(class [System.Runtime]System.String) + + leave.s SUCCESS + } + catch [System.Runtime]System.Object + { + pop + leave.s FAIL + } + +SUCCESS: + ldstr "SUCCESS" + call void [System.Console]System.Console::WriteLine(class [System.Runtime]System.String) + ldc.i4 100 + ret + +FAIL: + ldstr "FAILED" + call void [System.Console]System.Console::WriteLine(class [System.Runtime]System.String) + ldc.i4 0 + ret + } +} \ No newline at end of file diff --git a/src/tests/JIT/opt/Casts/castclass_valuetype.ilproj b/src/tests/JIT/opt/Casts/castclass_valuetype.ilproj new file mode 100644 index 00000000000000..a7a65728eacd42 --- /dev/null +++ b/src/tests/JIT/opt/Casts/castclass_valuetype.ilproj @@ -0,0 +1,11 @@ + + + 1 + + + PdbOnly + + + + + From ab9520f668a20bb4fb2fae176e7ea0ad3728a228 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 10 Jun 2023 13:25:26 +0800 Subject: [PATCH 08/13] Remove unused comment --- src/coreclr/vm/jitinterface.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index da174771a0f382..735355fb56797d 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1176,7 +1176,6 @@ void CEEInfo::resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken break; default: - // No additional checks. Satisfy switch exhaustiveness check. break; } } From 1ab940bd2caf0142621991b3ccef1f4989e7c7d2 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 12 Jun 2023 12:57:33 +0800 Subject: [PATCH 09/13] Fix il --- src/tests/JIT/opt/Casts/castclass_valuetype.il | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tests/JIT/opt/Casts/castclass_valuetype.il b/src/tests/JIT/opt/Casts/castclass_valuetype.il index a13583f258e254..79e7632c498e24 100644 --- a/src/tests/JIT/opt/Casts/castclass_valuetype.il +++ b/src/tests/JIT/opt/Casts/castclass_valuetype.il @@ -23,17 +23,17 @@ { // castclass valuetype ldc.i4.s 1234 - box [System.Runtime]System.Int32 - castclass [System.Runtime]System.Int32 - unbox [System.Runtime]System.Int32 + box int32 + castclass int32 + unbox int32 call void [System.Runtime]System.Int32::ToString() call void [System.Console]System.Console::WriteLine(class [System.Runtime]System.String) // castclass nullable ldc.i4.s 1234 - box [System.Runtime]System.Int32 - castclass valuetype [System.Runtime]System.Nullable`1<[System.Runtime]System.Int32> - unbox [System.Runtime]System.Int32 + box int32 + castclass valuetype [System.Runtime]System.Nullable`1 + unbox int32 call void [System.Runtime]System.Int32::ToString() call void [System.Console]System.Console::WriteLine(class [System.Runtime]System.String) From 85ba6f203aa01beedc3a61f8f3b85b4231042dd7 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 16 Jun 2023 18:40:56 +0800 Subject: [PATCH 10/13] Revert implementation --- .../tools/Common/JitInterface/CorInfoImpl.cs | 8 ----- src/coreclr/vm/jitinterface.cpp | 33 +++++++++---------- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 8abc4507e1aa6b..30f0b145a18641 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1789,14 +1789,6 @@ private void resolveToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken) type = type.MakeArrayType(); } - else if (pResolvedToken.tokenType == CorInfoTokenKind.CORINFO_TOKENKIND_Casting) - { - if (type.IsVoid) - ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramSpecific, methodIL.OwningMethod); - - if (type.IsNullable) - type = type.Instantiation[0]; - } pResolvedToken.hClass = ObjectToHandle(type); #if !SUPPORT_JIT diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 735355fb56797d..15365a90216a84 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1156,28 +1156,25 @@ void CEEInfo::resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken // tokenType specific verification and transformations // CorElementType et = th.GetInternalCorElementType(); - - if (tokenType != CORINFO_TOKENKIND_Ldtoken) + switch (tokenType) { - // Disallow ELEMENT_TYPE_BYREF and ELEMENT_TYPE_VOID - if (et == ELEMENT_TYPE_BYREF || et == ELEMENT_TYPE_VOID) - COMPlusThrow(kInvalidProgramException); + case CORINFO_TOKENKIND_Ldtoken: + // Allow everything. + break; - switch (tokenType) - { - case CORINFO_TOKENKIND_Newarr: - th = ClassLoader::LoadArrayTypeThrowing(th); - break; + case CORINFO_TOKENKIND_Newarr: + // Disallow ELEMENT_TYPE_BYREF and ELEMENT_TYPE_VOID + if (et == ELEMENT_TYPE_BYREF || et == ELEMENT_TYPE_VOID) + COMPlusThrow(kInvalidProgramException); - case CORINFO_TOKENKIND_Casting: - // isinst and castclass to Nullable is same as underlying type - if (Nullable::IsNullableType(th)) - th = th.AsMethodTable()->GetInstantiation()[0]; - break; + th = ClassLoader::LoadArrayTypeThrowing(th); + break; - default: - break; - } + default: + // Disallow ELEMENT_TYPE_BYREF and ELEMENT_TYPE_VOID + if (et == ELEMENT_TYPE_BYREF || et == ELEMENT_TYPE_VOID) + COMPlusThrow(kInvalidProgramException); + break; } // The JIT interface should always return fully loaded types From 2b10425ccbb17f3454ab69338e7ac200fba10632 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 16 Jun 2023 19:54:39 +0800 Subject: [PATCH 11/13] Implement at JIT side --- src/coreclr/jit/importer.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index b0127eb4f0c703..21dc52b7fe19a2 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -5425,6 +5425,24 @@ GenTree* Compiler::impCastClassOrIsInstToTree( // Optimistically assume the jit should expand this as an inline test bool shouldExpandInline = true; bool isClassExact = impIsClassExact(pResolvedToken->hClass); + bool isSharedInst = info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST; + + // 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. + // However, when the type is shared generic parameter like Nullable>, the actual type will require + // runtime lookup. It's too complex to add another level of indirection in op2, fallback to the cast helper instead. + if (isClassExact && !isSharedInst) + { + CORINFO_CLASS_HANDLE hClass = info.compCompHnd->getTypeForBox(pResolvedToken->hClass); + + if (hClass != pResolvedToken->hClass) + { + bool runtimeLookup; + pResolvedToken->hClass = hClass; + op2 = impTokenToHandle(pResolvedToken, &runtimeLookup); + assert(!runtimeLookup); + } + } // Profitability check. // From 385522638083d3abcfca6b920a56b7de4007c476 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 17 Jun 2023 10:39:18 +0800 Subject: [PATCH 12/13] Fix IL test --- src/tests/JIT/opt/Casts/castclass_valuetype.il | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tests/JIT/opt/Casts/castclass_valuetype.il b/src/tests/JIT/opt/Casts/castclass_valuetype.il index 79e7632c498e24..03eee56ae07aee 100644 --- a/src/tests/JIT/opt/Casts/castclass_valuetype.il +++ b/src/tests/JIT/opt/Casts/castclass_valuetype.il @@ -22,19 +22,19 @@ .try { // castclass valuetype - ldc.i4.s 1234 + ldc.i4 1234 box int32 castclass int32 unbox int32 - call void [System.Runtime]System.Int32::ToString() + call instance string [System.Runtime]System.Int32::ToString() call void [System.Console]System.Console::WriteLine(class [System.Runtime]System.String) // castclass nullable - ldc.i4.s 1234 + ldc.i4 1234 box int32 castclass valuetype [System.Runtime]System.Nullable`1 unbox int32 - call void [System.Runtime]System.Int32::ToString() + call instance string [System.Runtime]System.Int32::ToString() call void [System.Console]System.Console::WriteLine(class [System.Runtime]System.String) leave.s SUCCESS From e71042b7d922d83bf40c0fb0f081d0d04633a365 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sun, 18 Jun 2023 20:05:05 +0800 Subject: [PATCH 13/13] Avoid unnecessary JIT to EE call --- src/coreclr/jit/importer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 21dc52b7fe19a2..ee4e8c9245c9d6 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -5425,13 +5425,12 @@ GenTree* Compiler::impCastClassOrIsInstToTree( // Optimistically assume the jit should expand this as an inline test bool shouldExpandInline = true; bool isClassExact = impIsClassExact(pResolvedToken->hClass); - bool isSharedInst = info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST; // 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. // However, when the type is shared generic parameter like Nullable>, the actual type will require // runtime lookup. It's too complex to add another level of indirection in op2, fallback to the cast helper instead. - if (isClassExact && !isSharedInst) + if (isClassExact && !(info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST)) { CORINFO_CLASS_HANDLE hClass = info.compCompHnd->getTypeForBox(pResolvedToken->hClass);