From 50956682738388266c57cdcad1092585eeb328b6 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 5 Mar 2024 02:03:34 +0100 Subject: [PATCH 01/40] Simpler change --- src/coreclr/jit/importer.cpp | 13 +++++++++++++ src/coreclr/jit/importercalls.cpp | 11 +++++++++++ src/coreclr/vm/jitinterface.cpp | 20 +++++++++++++------- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index bbcdb91f6c10fe..b15102a742fc29 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1570,6 +1570,19 @@ GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind) { assert(kind == CORINFO_LOOKUP_METHODPARAM || kind == CORINFO_LOOKUP_CLASSPARAM); + if (compIsForInlining() && (kind == CORINFO_LOOKUP_METHODPARAM)) + { + // Grab the generic context from the callsite for current inlinee + CallArg* instParam = impInlineInfo->iciCall->gtArgs.FindWellKnownArg(WellKnownArg::InstParam); + if (instParam != nullptr) + { + assert(instParam->GetNode()->OperIs(GT_LCL_VAR)); + ctxTree = gtNewLclvNode(instParam->GetNode()->AsLclVar()->GetLclNum(), TYP_I_IMPL); + ctxTree->gtFlags |= GTF_VAR_CONTEXT; + return ctxTree; + } + } + // Exact method descriptor as passed in ctxTree = gtNewLclvNode(pRoot->info.compTypeCtxtArg, TYP_I_IMPL); ctxTree->gtFlags |= GTF_VAR_CONTEXT; diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 4fb75b7d398092..1e7577557c4f8b 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -6730,6 +6730,17 @@ void Compiler::impMarkInlineCandidate(GenTree* callNode, // candidate, we're done. if (call->IsInlineCandidate() || !call->IsGuardedDevirtualizationCandidate()) { + // Runtime lookup is expected to be spilled into a temp for inline candidates. + CallArg* instParam = call->gtArgs.FindWellKnownArg(WellKnownArg::InstParam); + if ((instParam != nullptr) && instParam->GetNode()->OperIs(GT_RUNTIMELOOKUP)) + { + const unsigned lookupTmp = lvaGrabTemp(true DEBUGARG("spilling runtimelookup")); + impStoreTemp(lookupTmp, instParam->GetNode(), CHECK_SPILL_NONE); + GenTreeLclVar* lcl = gtNewLclvNode(lookupTmp, TYP_I_IMPL); + lcl->gtFlags |= GTF_VAR_CONTEXT; + instParam->SetEarlyNode(lcl); + } + return; } diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 5e6b0cbeeafdd1..e9280c215d1f56 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -3086,24 +3086,30 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr // Unless we decide otherwise, just do the lookup via a helper function pResult->indirections = CORINFO_USEHELPER; - // Runtime lookups in inlined contexts are not supported by the runtime for now - if (pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT()) + MethodDesc* pContextMD = GetMethodFromContext(pResolvedToken->tokenContext); + if (pContextMD == nullptr) { + // Class context is not yet supported pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_NOT_SUPPORTED; return; } - MethodDesc* pContextMD = GetMethodFromContext(pResolvedToken->tokenContext); + bool inlinedRuntimeLookup = pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT(); MethodTable* pContextMT = pContextMD->GetMethodTable(); - bool isStaticVirtual = (pConstrainedResolvedToken != nullptr && pContextMD != nullptr && pContextMD->IsStatic()); + + if (inlinedRuntimeLookup && !pContextMD->HasMethodInstantiation()) + { + pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_NOT_SUPPORTED; + return; + } // There is a pathological case where invalid IL refereces __Canon type directly, but there is no dictionary availabled to store the lookup. - if (!pContextMD->IsSharedByGenericInstantiations()) + if (!inlinedRuntimeLookup && !pContextMD->IsSharedByGenericInstantiations()) COMPlusThrow(kInvalidProgramException); BOOL fInstrument = FALSE; - if (pContextMD->RequiresInstMethodDescArg()) + if (pContextMD->RequiresInstMethodDescArg() || inlinedRuntimeLookup) { pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_METHODPARAM; } @@ -3116,7 +3122,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr } // If we've got a method type parameter of any kind then we must look in the method desc arg - if (pContextMD->RequiresInstMethodDescArg()) + if (pContextMD->RequiresInstMethodDescArg() || inlinedRuntimeLookup) { pResult->helper = fInstrument ? CORINFO_HELP_RUNTIMEHANDLE_METHOD_LOG : CORINFO_HELP_RUNTIMEHANDLE_METHOD; From 4bc4269b5fe623597366dd2c0dfedc2ec4e5b7e9 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Wed, 6 Mar 2024 03:42:25 +0100 Subject: [PATCH 02/40] Address feedback --- src/coreclr/jit/importer.cpp | 40 +++++++++++++++---------------- src/coreclr/jit/importercalls.cpp | 4 ++++ src/coreclr/jit/inline.h | 7 +++--- src/coreclr/vm/jitinterface.cpp | 14 +++++------ 4 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index b15102a742fc29..de0d44d3af2e3d 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1548,19 +1548,17 @@ GenTree* Compiler::impMethodPointer(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORI GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind) { - GenTree* ctxTree = nullptr; + GenTree* ctxTree; // Collectible types requires that for shared generic code, if we use the generic context parameter // that we report it. (This is a conservative approach, we could detect some cases particularly when the // context parameter is this that we don't need the eager reporting logic.) lvaGenericsContextInUse = true; - Compiler* pRoot = impInlineRoot(); - if (kind == CORINFO_LOOKUP_THISOBJ) { // this Object - ctxTree = gtNewLclvNode(pRoot->info.compThisArg, TYP_REF); + ctxTree = gtNewLclvNode(impInlineRoot()->info.compThisArg, TYP_REF); ctxTree->gtFlags |= GTF_VAR_CONTEXT; // context is the method table pointer of the this object @@ -1568,24 +1566,21 @@ GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind) } else { - assert(kind == CORINFO_LOOKUP_METHODPARAM || kind == CORINFO_LOOKUP_CLASSPARAM); + assert((kind == CORINFO_LOOKUP_METHODPARAM) || (kind == CORINFO_LOOKUP_CLASSPARAM)); - if (compIsForInlining() && (kind == CORINFO_LOOKUP_METHODPARAM)) + if (compIsForInlining() && (impInlineInfo->iciCallInstParam != nullptr)) { - // Grab the generic context from the callsite for current inlinee - CallArg* instParam = impInlineInfo->iciCall->gtArgs.FindWellKnownArg(WellKnownArg::InstParam); - if (instParam != nullptr) - { - assert(instParam->GetNode()->OperIs(GT_LCL_VAR)); - ctxTree = gtNewLclvNode(instParam->GetNode()->AsLclVar()->GetLclNum(), TYP_I_IMPL); - ctxTree->gtFlags |= GTF_VAR_CONTEXT; - return ctxTree; - } + // Grab the generic context from the callsite for current inlinee. + // For runtime lookups, the generic context is always spilled to a local + assert(impInlineInfo->iciCallInstParam->OperIs(GT_LCL_VAR)); + ctxTree = gtClone(impInlineInfo->iciCallInstParam); + } + else + { + // Exact method descriptor as passed in + ctxTree = gtNewLclvNode(impInlineRoot()->info.compTypeCtxtArg, TYP_I_IMPL); + ctxTree->gtFlags |= GTF_VAR_CONTEXT; } - - // Exact method descriptor as passed in - ctxTree = gtNewLclvNode(pRoot->info.compTypeCtxtArg, TYP_I_IMPL); - ctxTree->gtFlags |= GTF_VAR_CONTEXT; } return ctxTree; } @@ -12780,6 +12775,8 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo) InlLclVarInfo* lclVarInfo = pInlineInfo->lclVarInfo; InlineResult* inlineResult = pInlineInfo->inlineResult; + pInlineInfo->iciCallInstParam = nullptr; + /* init the argument struct */ memset(inlArgInfo, 0, (MAX_INL_ARGS + 1) * sizeof(inlArgInfo[0])); @@ -12792,8 +12789,11 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo) inlArgInfo[ilArgCnt].argIsThis = true; break; case WellKnownArg::RetBuffer: + // This does not appear in the table of inline arg info; do not include them + continue; case WellKnownArg::InstParam: - // These do not appear in the table of inline arg info; do not include them + pInlineInfo->iciCallInstParam = arg.GetNode(); + // This one does not appear in the table of inline arg info too. continue; default: break; diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 1e7577557c4f8b..8c935c7637695c 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -6734,6 +6734,10 @@ void Compiler::impMarkInlineCandidate(GenTree* callNode, CallArg* instParam = call->gtArgs.FindWellKnownArg(WellKnownArg::InstParam); if ((instParam != nullptr) && instParam->GetNode()->OperIs(GT_RUNTIMELOOKUP)) { + // NOTE: we don't try to preserve the evaluation order for the runtime lookup - we generally + // treat it as an invariant tree despite the fact that it may actually throw exceptions + // (e.g. OOM or TypeLoadException). We do not guarantee the exact position where those + // exceptions are going to be thrown. const unsigned lookupTmp = lvaGrabTemp(true DEBUGARG("spilling runtimelookup")); impStoreTemp(lookupTmp, instParam->GetNode(), CHECK_SPILL_NONE); GenTreeLclVar* lcl = gtNewLclvNode(lookupTmp, TYP_I_IMPL); diff --git a/src/coreclr/jit/inline.h b/src/coreclr/jit/inline.h index dca92e39241e49..5046de352ce5ae 100644 --- a/src/coreclr/jit/inline.h +++ b/src/coreclr/jit/inline.h @@ -702,9 +702,10 @@ struct InlineInfo bool hasSIMDTypeArgLocalOrReturn; #endif // FEATURE_SIMD - GenTreeCall* iciCall; // The GT_CALL node to be inlined. - Statement* iciStmt; // The statement iciCall is in. - BasicBlock* iciBlock; // The basic block iciStmt is in. + GenTreeCall* iciCall; // The GT_CALL node to be inlined. + GenTree* iciCallInstParam; // Cached InstParam arg (if exists) in iciCall + Statement* iciStmt; // The statement iciCall is in. + BasicBlock* iciBlock; // The basic block iciStmt is in. }; // InlineContext tracks the inline history in a method. diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index e9280c215d1f56..e7a2600875d59a 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -3094,22 +3094,20 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr return; } - bool inlinedRuntimeLookup = pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT(); - MethodTable* pContextMT = pContextMD->GetMethodTable(); - - if (inlinedRuntimeLookup && !pContextMD->HasMethodInstantiation()) + bool inlinedMethodParamLookup = pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT(); + if (inlinedMethodParamLookup && !pContextMD->HasMethodInstantiation()) { pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_NOT_SUPPORTED; return; } // There is a pathological case where invalid IL refereces __Canon type directly, but there is no dictionary availabled to store the lookup. - if (!inlinedRuntimeLookup && !pContextMD->IsSharedByGenericInstantiations()) + if (!inlinedMethodParamLookup && !pContextMD->IsSharedByGenericInstantiations()) COMPlusThrow(kInvalidProgramException); BOOL fInstrument = FALSE; - if (pContextMD->RequiresInstMethodDescArg() || inlinedRuntimeLookup) + if (pContextMD->RequiresInstMethodDescArg() || inlinedMethodParamLookup) { pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_METHODPARAM; } @@ -3121,8 +3119,10 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_THISOBJ; } + MethodTable* pContextMT = pContextMD->GetMethodTable(); + // If we've got a method type parameter of any kind then we must look in the method desc arg - if (pContextMD->RequiresInstMethodDescArg() || inlinedRuntimeLookup) + if (pContextMD->RequiresInstMethodDescArg() || inlinedMethodParamLookup) { pResult->helper = fInstrument ? CORINFO_HELP_RUNTIMEHANDLE_METHOD_LOG : CORINFO_HELP_RUNTIMEHANDLE_METHOD; From 4f3353feeef20bafcffd8bd95c4d24576f10b36a Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 8 Mar 2024 02:17:17 +0100 Subject: [PATCH 03/40] clean up --- src/coreclr/jit/compiler.h | 7 ++++--- src/coreclr/jit/compiler.hpp | 6 +++--- src/coreclr/jit/importer.cpp | 23 ++++++++++++++++++----- src/coreclr/jit/jiteh.cpp | 5 +++++ src/coreclr/jit/lclvars.cpp | 10 +++++----- src/coreclr/jit/morph.cpp | 3 +++ 6 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index b69ccd18f96480..8065bd93053618 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -4620,7 +4620,7 @@ class Compiler GenTreeFlags flags, void* compileTimeHandle); - GenTree* getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind); + GenTree* getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind, bool* pIsInvariant = nullptr); GenTree* impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP* pLookup, @@ -10198,8 +10198,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX unsigned compArgStackSize; // Incoming argument stack size in bytes #endif // FEATURE_FASTTAILCALL - unsigned compRetBuffArg; // position of hidden return param var (0, 1) (BAD_VAR_NUM means not present); - int compTypeCtxtArg; // position of hidden param for type context for generic code (CORINFO_CALLCONV_PARAMTYPE) + unsigned compRetBuffArg; // position of hidden return param var (0, 1) (BAD_VAR_NUM means not present); + unsigned compTypeCtxtArg; // position of hidden param for type context for generic code + // (CORINFO_CALLCONV_PARAMTYPE) unsigned compThisArg; // position of implicit this pointer param (not to be confused with lvaArg0Var) unsigned compILlocalsCount; // Number of vars : args + locals (incl. implicit but not hidden) unsigned compLocalsCount; // Number of vars : args + locals (incl. implicit and hidden) diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 05842d837395f5..60e71c9f9e2fdc 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -2443,7 +2443,7 @@ inline bool Compiler::lvaReportParamTypeArg() { if (info.compMethodInfo->options & (CORINFO_GENERICS_CTXT_FROM_METHODDESC | CORINFO_GENERICS_CTXT_FROM_METHODTABLE)) { - assert(info.compTypeCtxtArg != -1); + assert(info.compTypeCtxtArg != BAD_VAR_NUM); // If the VM requires us to keep the generics context alive and report it (for example, if any catch // clause catches a type that uses a generic parameter of this method) this flag will be set. @@ -2773,13 +2773,13 @@ inline unsigned Compiler::compMapILargNum(unsigned ILargNum) assert(ILargNum < info.compLocalsCount); // compLocals count already adjusted. } - if (ILargNum >= (unsigned)info.compTypeCtxtArg) + if (ILargNum >= info.compTypeCtxtArg) { ILargNum++; assert(ILargNum < info.compLocalsCount); // compLocals count already adjusted. } - if (ILargNum >= (unsigned)lvaVarargsHandleArg) + if (ILargNum >= lvaVarargsHandleArg) { ILargNum++; assert(ILargNum < info.compLocalsCount); // compLocals count already adjusted. diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index de0d44d3af2e3d..c50871ceb88240 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1538,7 +1538,8 @@ GenTree* Compiler::impMethodPointer(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORI // getRuntimeContextTree: find pointer to context for runtime lookup. // // Arguments: -// kind - lookup kind. +// kind - lookup kind. +// pIsInvariant - [OUT] whether the resulting tree is known to be invariant or not. // // Return Value: // Return GenTree pointer to generic shared context. @@ -1546,10 +1547,15 @@ GenTree* Compiler::impMethodPointer(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORI // Notes: // Reports about generic context using. -GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind) +GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind, bool* pIsInvariant) { GenTree* ctxTree; + if (pIsInvariant != nullptr) + { + *pIsInvariant = true; + } + // Collectible types requires that for shared generic code, if we use the generic context parameter // that we report it. (This is a conservative approach, we could detect some cases particularly when the // context parameter is this that we don't need the eager reporting logic.) @@ -1574,6 +1580,10 @@ GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind) // For runtime lookups, the generic context is always spilled to a local assert(impInlineInfo->iciCallInstParam->OperIs(GT_LCL_VAR)); ctxTree = gtClone(impInlineInfo->iciCallInstParam); + if (pIsInvariant != nullptr) + { + *pIsInvariant = false; + } } else { @@ -1609,7 +1619,8 @@ GenTree* Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken CORINFO_LOOKUP* pLookup, void* compileTimeHandle) { - GenTree* ctxTree = getRuntimeContextTree(pLookup->lookupKind.runtimeLookupKind); + bool ctxTreeIsInvariant; + GenTree* ctxTree = getRuntimeContextTree(pLookup->lookupKind.runtimeLookupKind, &ctxTreeIsInvariant); CORINFO_RUNTIME_LOOKUP* pRuntimeLookup = &pLookup->runtimeLookup; // It's available only via the run-time helper function @@ -1662,7 +1673,8 @@ GenTree* Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken if (i != 0) { - slotPtrTree = gtNewIndir(TYP_I_IMPL, slotPtrTree, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); + slotPtrTree = gtNewIndir(TYP_I_IMPL, slotPtrTree, + ctxTreeIsInvariant ? (GTF_IND_NONFAULTING | GTF_IND_INVARIANT) : GTF_EMPTY); } if ((i == 1 && pRuntimeLookup->indirectFirstOffset) || (i == 2 && pRuntimeLookup->indirectSecondOffset)) @@ -1685,7 +1697,8 @@ GenTree* Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken return slotPtrTree; } - slotPtrTree = gtNewIndir(TYP_I_IMPL, slotPtrTree, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); + slotPtrTree = + gtNewIndir(TYP_I_IMPL, slotPtrTree, ctxTreeIsInvariant ? (GTF_IND_NONFAULTING | GTF_IND_INVARIANT) : GTF_EMPTY); return slotPtrTree; } diff --git a/src/coreclr/jit/jiteh.cpp b/src/coreclr/jit/jiteh.cpp index e7195b5c98cb2b..1d53a630064a25 100644 --- a/src/coreclr/jit/jiteh.cpp +++ b/src/coreclr/jit/jiteh.cpp @@ -2369,6 +2369,11 @@ bool Compiler::fgCreateFiltersForGenericExceptions() } else { + // NOTE: It is a bit more complicated than this if this EH filter belongs to an inlinee as + // at this point inlining is already done, and we can't rely on the tricks we do in the + // importer for inlined runtime lookups. However, we currently never inline methods with EH, + // so we don't need to worry about this (yet). + // runtimeLookup = getTokenHandleTree(&resolvedToken, true); } GenTree* isInstOfT = gtNewHelperCallNode(CORINFO_HELP_ISINSTANCEOF_EXCEPTION, TYP_INT, runtimeLookup, arg); diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 55787580cc1df7..af3aca51e3cbed 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -1540,7 +1540,7 @@ unsigned Compiler::compMapILvarNum(unsigned ILvarNum) else if (ILvarNum == (unsigned)ICorDebugInfo::TYPECTXT_ILNUM) { noway_assert(info.compTypeCtxtArg >= 0); - varNum = unsigned(info.compTypeCtxtArg); + varNum = info.compTypeCtxtArg; } else if (ILvarNum < info.compILargsCount) { @@ -1593,7 +1593,7 @@ unsigned Compiler::compMap2ILvarNum(unsigned varNum) const // We create an extra argument for the type context parameter // needed for shared generic code. - if ((info.compMethodInfo->args.callConv & CORINFO_CALLCONV_PARAMTYPE) && varNum == (unsigned)info.compTypeCtxtArg) + if ((info.compMethodInfo->args.callConv & CORINFO_CALLCONV_PARAMTYPE) && varNum == info.compTypeCtxtArg) { return (unsigned)ICorDebugInfo::TYPECTXT_ILNUM; } @@ -1606,7 +1606,7 @@ unsigned Compiler::compMap2ILvarNum(unsigned varNum) const #endif // FEATURE_FIXED_OUT_ARGS // Now mutate varNum to remove extra parameters from the count. - if ((info.compMethodInfo->args.callConv & CORINFO_CALLCONV_PARAMTYPE) && varNum > (unsigned)info.compTypeCtxtArg) + if ((info.compMethodInfo->args.callConv & CORINFO_CALLCONV_PARAMTYPE) && varNum > info.compTypeCtxtArg) { varNum--; } @@ -5498,7 +5498,7 @@ void Compiler::lvaAssignVirtualFrameOffsetsToArgs() //@GENERICS: extra argument for instantiation info if (info.compMethodInfo->args.callConv & CORINFO_CALLCONV_PARAMTYPE) { - noway_assert(lclNum == (unsigned)info.compTypeCtxtArg); + noway_assert(lclNum == info.compTypeCtxtArg); argOffs = lvaAssignVirtualFrameOffsetToArg(lclNum++, REGSIZE_BYTES, argOffs UNIX_AMD64_ABI_ONLY_ARG(&callerArgOffset)); } @@ -5607,7 +5607,7 @@ void Compiler::lvaAssignVirtualFrameOffsetsToArgs() //@GENERICS: extra argument for instantiation info if (info.compMethodInfo->args.callConv & CORINFO_CALLCONV_PARAMTYPE) { - noway_assert(lclNum == (unsigned)info.compTypeCtxtArg); + noway_assert(lclNum == info.compTypeCtxtArg); argOffs = lvaAssignVirtualFrameOffsetToArg(lclNum++, REGSIZE_BYTES, argOffs UNIX_AMD64_ABI_ONLY_ARG(&callerArgOffset)); } diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index f0af492d6197a1..7ebee438273e2c 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -7000,6 +7000,9 @@ GenTree* Compiler::getVirtMethodPointerTree(GenTree* thisPtr, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_CALL_INFO* pCallInfo) { + // NOTE: Runtime lookups are tricky for inlinees and at this point we're already done with inlining. + // The good news is that we currently never inline methods with explicit tail calls. + // GenTree* exactTypeDesc = getTokenHandleTree(pResolvedToken, true); GenTree* exactMethodDesc = getTokenHandleTree(pResolvedToken, false); From c4b999720a1c3984954b13b920442083ba96954b Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 8 Mar 2024 04:39:02 +0100 Subject: [PATCH 04/40] Address feedback --- src/coreclr/jit/compiler.h | 4 +-- src/coreclr/jit/fginline.cpp | 3 +- src/coreclr/jit/importer.cpp | 67 +++++++++++++++++------------------- src/coreclr/jit/inline.h | 8 ++--- 4 files changed, 40 insertions(+), 42 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 8065bd93053618..35db1f7ddebfdf 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -4620,7 +4620,7 @@ class Compiler GenTreeFlags flags, void* compileTimeHandle); - GenTree* getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind, bool* pIsInvariant = nullptr); + GenTree* getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind); GenTree* impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP* pLookup, @@ -4906,7 +4906,7 @@ class Compiler unsigned impInlineFetchLocal(unsigned lclNum DEBUGARG(const char* reason)); - GenTree* impInlineFetchArg(unsigned lclNum, InlArgInfo* inlArgInfo, InlLclVarInfo* lclTypeInfo); + GenTree* impInlineFetchArg(InlArgInfo& argInfo, const InlLclVarInfo& lclInfo); bool impInlineIsThis(GenTree* tree, InlArgInfo* inlArgInfo); diff --git a/src/coreclr/jit/fginline.cpp b/src/coreclr/jit/fginline.cpp index cdabeae13d3232..ec9fc3a73d5abc 100644 --- a/src/coreclr/jit/fginline.cpp +++ b/src/coreclr/jit/fginline.cpp @@ -1180,6 +1180,7 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call, InlineResult* inlineRe inlineInfo.retExprClassHnd = nullptr; inlineInfo.retExprClassHndIsExact = false; inlineInfo.inlineResult = inlineResult; + inlineInfo.inlInstParamArgInfo = nullptr; #ifdef FEATURE_SIMD inlineInfo.hasSIMDTypeArgLocalOrReturn = false; #endif // FEATURE_SIMD @@ -1733,7 +1734,7 @@ Statement* Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo) if (call->gtFlags & GTF_CALL_NULLCHECK && !inlineInfo->thisDereferencedFirst) { // Call impInlineFetchArg to "reserve" a temp for the "this" pointer. - GenTree* thisOp = impInlineFetchArg(0, inlArgInfo, lclVarInfo); + GenTree* thisOp = impInlineFetchArg(inlArgInfo[0], lclVarInfo[0]); if (fgAddrCouldBeNull(thisOp)) { nullcheck = gtNewNullCheck(thisOp, block); diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index c50871ceb88240..9e562e97b544a0 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1539,7 +1539,6 @@ GenTree* Compiler::impMethodPointer(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORI // // Arguments: // kind - lookup kind. -// pIsInvariant - [OUT] whether the resulting tree is known to be invariant or not. // // Return Value: // Return GenTree pointer to generic shared context. @@ -1547,15 +1546,10 @@ GenTree* Compiler::impMethodPointer(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORI // Notes: // Reports about generic context using. -GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind, bool* pIsInvariant) +GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind) { GenTree* ctxTree; - if (pIsInvariant != nullptr) - { - *pIsInvariant = true; - } - // Collectible types requires that for shared generic code, if we use the generic context parameter // that we report it. (This is a conservative approach, we could detect some cases particularly when the // context parameter is this that we don't need the eager reporting logic.) @@ -1574,16 +1568,14 @@ GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind, bool* { assert((kind == CORINFO_LOOKUP_METHODPARAM) || (kind == CORINFO_LOOKUP_CLASSPARAM)); - if (compIsForInlining() && (impInlineInfo->iciCallInstParam != nullptr)) + if (compIsForInlining() && (impInlineInfo->inlInstParamArgInfo != nullptr)) { - // Grab the generic context from the callsite for current inlinee. - // For runtime lookups, the generic context is always spilled to a local - assert(impInlineInfo->iciCallInstParam->OperIs(GT_LCL_VAR)); - ctxTree = gtClone(impInlineInfo->iciCallInstParam); - if (pIsInvariant != nullptr) - { - *pIsInvariant = false; - } + InlLclVarInfo lclInfo = {}; + lclInfo.lclTypeInfo = TYP_I_IMPL; + + ctxTree = impInlineFetchArg(*impInlineInfo->inlInstParamArgInfo, lclInfo); + assert(ctxTree != nullptr); + assert(ctxTree->TypeIs(TYP_I_IMPL)); } else { @@ -1619,8 +1611,7 @@ GenTree* Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken CORINFO_LOOKUP* pLookup, void* compileTimeHandle) { - bool ctxTreeIsInvariant; - GenTree* ctxTree = getRuntimeContextTree(pLookup->lookupKind.runtimeLookupKind, &ctxTreeIsInvariant); + GenTree* ctxTree = getRuntimeContextTree(pLookup->lookupKind.runtimeLookupKind); CORINFO_RUNTIME_LOOKUP* pRuntimeLookup = &pLookup->runtimeLookup; // It's available only via the run-time helper function @@ -1662,6 +1653,8 @@ GenTree* Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken GenTree* slotPtrTree = ctxTree; GenTree* indOffTree = nullptr; + const bool ctxTreeIsInvariant = !compIsForInlining(); + // Applied repeated indirections for (WORD i = 0; i < pRuntimeLookup->indirections; i++) { @@ -6294,7 +6287,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) if (compIsForInlining()) { - op1 = impInlineFetchArg(lclNum, impInlineInfo->inlArgInfo, impInlineInfo->lclVarInfo); + op1 = impInlineFetchArg(impInlineInfo->inlArgInfo[lclNum], impInlineInfo->lclVarInfo[lclNum]); noway_assert(op1->gtOper == GT_LCL_VAR); lclNum = op1->AsLclVar()->GetLclNum(); @@ -6499,7 +6492,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) // In IL, LDARGA(_S) is used to load the byref managed pointer of struct argument, // followed by a ldfld to load the field. - op1 = impInlineFetchArg(lclNum, impInlineInfo->inlArgInfo, impInlineInfo->lclVarInfo); + op1 = impInlineFetchArg(impInlineInfo->inlArgInfo[lclNum], impInlineInfo->lclVarInfo[lclNum]); if (op1->gtOper != GT_LCL_VAR) { compInlineResult->NoteFatal(InlineObservation::CALLSITE_LDARGA_NOT_LOCAL_VAR); @@ -10477,7 +10470,8 @@ void Compiler::impLoadArg(unsigned ilArgNum, IL_OFFSET offset) tiRetVal = typeInfo(type); } - impPushOnStack(impInlineFetchArg(ilArgNum, impInlineInfo->inlArgInfo, impInlineInfo->lclVarInfo), tiRetVal); + impPushOnStack(impInlineFetchArg(impInlineInfo->inlArgInfo[ilArgNum], impInlineInfo->lclVarInfo[ilArgNum]), + tiRetVal); } else { @@ -12788,8 +12782,6 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo) InlLclVarInfo* lclVarInfo = pInlineInfo->lclVarInfo; InlineResult* inlineResult = pInlineInfo->inlineResult; - pInlineInfo->iciCallInstParam = nullptr; - /* init the argument struct */ memset(inlArgInfo, 0, (MAX_INL_ARGS + 1) * sizeof(inlArgInfo[0])); @@ -12805,9 +12797,18 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo) // This does not appear in the table of inline arg info; do not include them continue; case WellKnownArg::InstParam: - pInlineInfo->iciCallInstParam = arg.GetNode(); + { + InlArgInfo* ctxInfo = getAllocator(CMK_Unknown).allocate(1); + memset(ctxInfo, 0, sizeof(*ctxInfo)); + ctxInfo->arg = &arg; + ctxInfo->argHasTmp = true; + ctxInfo->argIsUsed = true; + ctxInfo->argIsInvariant = true; + pInlineInfo->inlInstParamArgInfo = ctxInfo; + // This one does not appear in the table of inline arg info too. continue; + } default: break; } @@ -13178,9 +13179,8 @@ unsigned Compiler::impInlineFetchLocal(unsigned lclNum DEBUGARG(const char* reas // impInlineFetchArg: return tree node for argument value in an inlinee // // Arguments: -// lclNum -- argument number in inlinee IL -// inlArgInfo -- argument info for inlinee -// lclVarInfo -- var info for inlinee +// argInfo -- argument info for inlinee +// lclInfo -- var info for inlinee // // Returns: // Tree for the argument's value. Often an inlinee-scoped temp @@ -13207,15 +13207,13 @@ unsigned Compiler::impInlineFetchLocal(unsigned lclNum DEBUGARG(const char* reas // This method will side effect inlArgInfo. It should only be called // for actual uses of the argument in the inlinee. -GenTree* Compiler::impInlineFetchArg(unsigned lclNum, InlArgInfo* inlArgInfo, InlLclVarInfo* lclVarInfo) +GenTree* Compiler::impInlineFetchArg(InlArgInfo& argInfo, const InlLclVarInfo& lclInfo) { // Cache the relevant arg and lcl info for this argument. // We will modify argInfo but not lclVarInfo. - InlArgInfo& argInfo = inlArgInfo[lclNum]; - const InlLclVarInfo& lclInfo = lclVarInfo[lclNum]; - const bool argCanBeModified = argInfo.argHasLdargaOp || argInfo.argHasStargOp; - const var_types lclTyp = lclInfo.lclTypeInfo; - GenTree* op1 = nullptr; + const bool argCanBeModified = argInfo.argHasLdargaOp || argInfo.argHasStargOp; + const var_types lclTyp = lclInfo.lclTypeInfo; + GenTree* op1 = nullptr; GenTree* argNode = argInfo.arg->GetNode(); assert(!argNode->OperIs(GT_RET_EXPR)); @@ -13266,7 +13264,6 @@ GenTree* Compiler::impInlineFetchArg(unsigned lclNum, InlArgInfo* inlArgInfo, In if (argInfo.argIsUsed || ((lclTyp == TYP_BYREF) && (op1->TypeGet() != TYP_BYREF))) { assert(op1->gtOper == GT_LCL_VAR); - assert(lclNum == op1->AsLclVar()->gtLclILoffs); // Create a new lcl var node - remember the argument lclNum op1 = impCreateLocalNode(argLclNum DEBUGARG(op1->AsLclVar()->gtLclILoffs)); @@ -13379,7 +13376,7 @@ GenTree* Compiler::impInlineFetchArg(unsigned lclNum, InlArgInfo* inlArgInfo, In !argInfo.argHasCallerLocalRef)) { /* Get a *LARGE* LCL_VAR node */ - op1 = gtNewLclLNode(tmpNum, genActualType(lclTyp) DEBUGARG(lclNum)); + op1 = gtNewLclLNode(tmpNum, genActualType(lclTyp)); /* Record op1 as the very first use of this argument. If there are no further uses of the arg, we may be diff --git a/src/coreclr/jit/inline.h b/src/coreclr/jit/inline.h index 5046de352ce5ae..342dc3fca5d238 100644 --- a/src/coreclr/jit/inline.h +++ b/src/coreclr/jit/inline.h @@ -686,6 +686,7 @@ struct InlineInfo unsigned argCnt; InlArgInfo inlArgInfo[MAX_INL_ARGS + 1]; + InlArgInfo* inlInstParamArgInfo; int lclTmpNum[MAX_INL_LCLS]; // map local# -> temp# (-1 if unused) InlLclVarInfo lclVarInfo[MAX_INL_LCLS + MAX_INL_ARGS + 1]; // type information from local sig @@ -702,10 +703,9 @@ struct InlineInfo bool hasSIMDTypeArgLocalOrReturn; #endif // FEATURE_SIMD - GenTreeCall* iciCall; // The GT_CALL node to be inlined. - GenTree* iciCallInstParam; // Cached InstParam arg (if exists) in iciCall - Statement* iciStmt; // The statement iciCall is in. - BasicBlock* iciBlock; // The basic block iciStmt is in. + GenTreeCall* iciCall; // The GT_CALL node to be inlined. + Statement* iciStmt; // The statement iciCall is in. + BasicBlock* iciBlock; // The basic block iciStmt is in. }; // InlineContext tracks the inline history in a method. From 0693f8944b8aa7079a91be6e99e3bc1cf24afc3d Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 8 Mar 2024 04:49:37 +0100 Subject: [PATCH 05/40] Clean up --- src/coreclr/jit/importer.cpp | 3 +-- src/coreclr/jit/importercalls.cpp | 15 --------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 9e562e97b544a0..6428a957284448 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -12801,9 +12801,8 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo) InlArgInfo* ctxInfo = getAllocator(CMK_Unknown).allocate(1); memset(ctxInfo, 0, sizeof(*ctxInfo)); ctxInfo->arg = &arg; - ctxInfo->argHasTmp = true; - ctxInfo->argIsUsed = true; ctxInfo->argIsInvariant = true; + ctxInfo->argIsLclVar = arg.GetNode()->OperIs(GT_LCL_VAR); pInlineInfo->inlInstParamArgInfo = ctxInfo; // This one does not appear in the table of inline arg info too. diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 8c935c7637695c..4fb75b7d398092 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -6730,21 +6730,6 @@ void Compiler::impMarkInlineCandidate(GenTree* callNode, // candidate, we're done. if (call->IsInlineCandidate() || !call->IsGuardedDevirtualizationCandidate()) { - // Runtime lookup is expected to be spilled into a temp for inline candidates. - CallArg* instParam = call->gtArgs.FindWellKnownArg(WellKnownArg::InstParam); - if ((instParam != nullptr) && instParam->GetNode()->OperIs(GT_RUNTIMELOOKUP)) - { - // NOTE: we don't try to preserve the evaluation order for the runtime lookup - we generally - // treat it as an invariant tree despite the fact that it may actually throw exceptions - // (e.g. OOM or TypeLoadException). We do not guarantee the exact position where those - // exceptions are going to be thrown. - const unsigned lookupTmp = lvaGrabTemp(true DEBUGARG("spilling runtimelookup")); - impStoreTemp(lookupTmp, instParam->GetNode(), CHECK_SPILL_NONE); - GenTreeLclVar* lcl = gtNewLclvNode(lookupTmp, TYP_I_IMPL); - lcl->gtFlags |= GTF_VAR_CONTEXT; - instParam->SetEarlyNode(lcl); - } - return; } From f300235edc50a0daa25249b9a050802a99ea66bb Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 8 Mar 2024 05:09:55 +0100 Subject: [PATCH 06/40] fix build --- src/coreclr/jit/lclvars.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index af3aca51e3cbed..f2e47ae2ddac44 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -4357,7 +4357,7 @@ PhaseStatus Compiler::lvaMarkLocalVars() else if (lvaReportParamTypeArg()) { // We should have a context arg. - assert(info.compTypeCtxtArg != (int)BAD_VAR_NUM); + assert(info.compTypeCtxtArg != BAD_VAR_NUM); lvaGetDesc(info.compTypeCtxtArg)->lvImplicitlyReferenced = reportParamTypeArg; } From 6da60553984883fef914a7ef33d5620d52e67578 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 8 Mar 2024 18:29:54 +0100 Subject: [PATCH 07/40] clean up --- src/coreclr/vm/jitinterface.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index e7a2600875d59a..392e38e3d22313 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -3087,6 +3087,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr pResult->indirections = CORINFO_USEHELPER; MethodDesc* pContextMD = GetMethodFromContext(pResolvedToken->tokenContext); + if (pContextMD == nullptr) { // Class context is not yet supported @@ -3094,19 +3095,15 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr return; } - bool inlinedMethodParamLookup = pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT(); - if (inlinedMethodParamLookup && !pContextMD->HasMethodInstantiation()) - { - pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_NOT_SUPPORTED; - return; - } + BOOL fInstrument = FALSE; + MethodTable* pContextMT = GetTypeFromContext(pResolvedToken->tokenContext).AsMethodTable(); + bool inlinedMethodParamLookup = pContextMD != nullptr && pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT(); - // There is a pathological case where invalid IL refereces __Canon type directly, but there is no dictionary availabled to store the lookup. + // There is a pathological case where invalid IL refereces __Canon type directly, + // but there is no dictionary available to store the lookup. if (!inlinedMethodParamLookup && !pContextMD->IsSharedByGenericInstantiations()) COMPlusThrow(kInvalidProgramException); - BOOL fInstrument = FALSE; - if (pContextMD->RequiresInstMethodDescArg() || inlinedMethodParamLookup) { pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_METHODPARAM; @@ -3119,8 +3116,6 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_THISOBJ; } - MethodTable* pContextMT = pContextMD->GetMethodTable(); - // If we've got a method type parameter of any kind then we must look in the method desc arg if (pContextMD->RequiresInstMethodDescArg() || inlinedMethodParamLookup) { From f0da1929b5f96ceceeb41e16a18344b650db63c4 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 9 Mar 2024 01:55:01 +0100 Subject: [PATCH 08/40] Class context? --- src/coreclr/vm/jitinterface.cpp | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 392e38e3d22313..2aa810b0066540 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -3086,25 +3086,29 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr // Unless we decide otherwise, just do the lookup via a helper function pResult->indirections = CORINFO_USEHELPER; - MethodDesc* pContextMD = GetMethodFromContext(pResolvedToken->tokenContext); + MethodDesc* pContextMD = GetMethodFromContext(pResolvedToken->tokenContext); + MethodTable* pContextMT = GetTypeFromContext(pResolvedToken->tokenContext).AsMethodTable(); + + bool inlinedMethodParamLookup = pContextMD != nullptr && pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT(); + bool inlinedClassParamLookup = pContextMD == nullptr && pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT(); - if (pContextMD == nullptr) + if ((inlinedMethodParamLookup && !pContextMD->HasMethodInstantiation()) || + (inlinedClassParamLookup && !pContextMT->HasInstantiation())) { - // Class context is not yet supported pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_NOT_SUPPORTED; return; } - BOOL fInstrument = FALSE; - MethodTable* pContextMT = GetTypeFromContext(pResolvedToken->tokenContext).AsMethodTable(); - bool inlinedMethodParamLookup = pContextMD != nullptr && pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT(); - // There is a pathological case where invalid IL refereces __Canon type directly, // but there is no dictionary available to store the lookup. - if (!inlinedMethodParamLookup && !pContextMD->IsSharedByGenericInstantiations()) + if (!inlinedClassParamLookup && !inlinedMethodParamLookup && !pContextMD->IsSharedByGenericInstantiations()) COMPlusThrow(kInvalidProgramException); - if (pContextMD->RequiresInstMethodDescArg() || inlinedMethodParamLookup) + if (inlinedClassParamLookup) + { + pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_CLASSPARAM; + } + else if (pContextMD->RequiresInstMethodDescArg() || inlinedMethodParamLookup) { pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_METHODPARAM; } @@ -3116,8 +3120,10 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_THISOBJ; } + BOOL fInstrument = FALSE; + // If we've got a method type parameter of any kind then we must look in the method desc arg - if (pContextMD->RequiresInstMethodDescArg() || inlinedMethodParamLookup) + if (!inlinedClassParamLookup && (pContextMD->RequiresInstMethodDescArg() || inlinedMethodParamLookup)) { pResult->helper = fInstrument ? CORINFO_HELP_RUNTIMEHANDLE_METHOD_LOG : CORINFO_HELP_RUNTIMEHANDLE_METHOD; @@ -3184,7 +3190,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr { _ASSERTE(pContextMT->GetNumGenericArgs() > 0); - if (pContextMD->RequiresInstMethodTableArg()) + if (!inlinedClassParamLookup && pContextMD->RequiresInstMethodTableArg()) { // If we've got a vtable extra argument, go through that pResult->helper = fInstrument ? CORINFO_HELP_RUNTIMEHANDLE_CLASS_LOG : CORINFO_HELP_RUNTIMEHANDLE_CLASS; @@ -3192,7 +3198,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr // If we've got an object, go through its vtable else { - _ASSERTE(pContextMD->AcquiresInstMethodTableFromThis()); + _ASSERTE(inlinedClassParamLookup || pContextMD->AcquiresInstMethodTableFromThis()); pResult->helper = fInstrument ? CORINFO_HELP_RUNTIMEHANDLE_CLASS_LOG : CORINFO_HELP_RUNTIMEHANDLE_CLASS; } From 99f89fc7ee32c1a0afe9cb01342180b7d5178c62 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 9 Mar 2024 04:05:33 +0100 Subject: [PATCH 09/40] Disable class context --- src/coreclr/jit/importer.cpp | 46 +++++++++++++++++++++------------ src/coreclr/vm/jitinterface.cpp | 4 ++- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 6428a957284448..7c2025cff00735 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1555,35 +1555,47 @@ GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind) // context parameter is this that we don't need the eager reporting logic.) lvaGenericsContextInUse = true; - if (kind == CORINFO_LOOKUP_THISOBJ) + // Always use generic context from the callsite if we're inlining and it's available. + if (compIsForInlining() && (impInlineInfo->inlInstParamArgInfo != nullptr)) { - // this Object - ctxTree = gtNewLclvNode(impInlineRoot()->info.compThisArg, TYP_REF); - ctxTree->gtFlags |= GTF_VAR_CONTEXT; + InlLclVarInfo lclInfo = {}; + lclInfo.lclTypeInfo = TYP_I_IMPL; - // context is the method table pointer of the this object - ctxTree = gtNewMethodTableLookup(ctxTree); + ctxTree = impInlineFetchArg(*impInlineInfo->inlInstParamArgInfo, lclInfo); + assert(ctxTree != nullptr); + assert(ctxTree->TypeIs(TYP_I_IMPL)); } - else + else if (kind == CORINFO_LOOKUP_THISOBJ) { - assert((kind == CORINFO_LOOKUP_METHODPARAM) || (kind == CORINFO_LOOKUP_CLASSPARAM)); - - if (compIsForInlining() && (impInlineInfo->inlInstParamArgInfo != nullptr)) + // Use "this" from the callsite if we're inlining + if (compIsForInlining()) { - InlLclVarInfo lclInfo = {}; - lclInfo.lclTypeInfo = TYP_I_IMPL; + // "this" is always the first argument in inlArgInfo + assert(impInlineInfo->argCnt > 0); + assert(impInlineInfo->inlArgInfo[0].argIsThis); - ctxTree = impInlineFetchArg(*impInlineInfo->inlInstParamArgInfo, lclInfo); - assert(ctxTree != nullptr); - assert(ctxTree->TypeIs(TYP_I_IMPL)); + ctxTree = impInlineFetchArg(impInlineInfo->inlArgInfo[0], impInlineInfo->lclVarInfo[0]); + // context is the method table pointer of the this object + ctxTree = gtNewMethodTableLookup(ctxTree); } else { - // Exact method descriptor as passed in - ctxTree = gtNewLclvNode(impInlineRoot()->info.compTypeCtxtArg, TYP_I_IMPL); + assert(info.compThisArg != BAD_VAR_NUM); + ctxTree = gtNewLclvNode(info.compThisArg, TYP_REF); ctxTree->gtFlags |= GTF_VAR_CONTEXT; + + // context is the method table pointer of the this object + ctxTree = gtNewMethodTableLookup(ctxTree); } } + else + { + assert((kind == CORINFO_LOOKUP_METHODPARAM) || (kind == CORINFO_LOOKUP_CLASSPARAM)); + + // Exact method descriptor as passed in + ctxTree = gtNewLclvNode(impInlineRoot()->info.compTypeCtxtArg, TYP_I_IMPL); + ctxTree->gtFlags |= GTF_VAR_CONTEXT; + } return ctxTree; } diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 2aa810b0066540..80534e2129418c 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -3106,7 +3106,9 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr if (inlinedClassParamLookup) { - pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_CLASSPARAM; + // TODO: how do we figure out whether we need CORINFO_LOOKUP_THISOBJ or CORINFO_LOOKUP_CLASSPARAM? + pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_NOT_SUPPORTED; + return; } else if (pContextMD->RequiresInstMethodDescArg() || inlinedMethodParamLookup) { From 93b199bbde1adaf5e47fcb52a89be2137f729dad Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 9 Mar 2024 04:52:47 +0100 Subject: [PATCH 10/40] Add containingMd to embedGenericHandle --- src/coreclr/inc/corinfo.h | 1 + src/coreclr/inc/icorjitinfoimpl_generated.h | 1 + src/coreclr/inc/jiteeversionguid.h | 10 +++---- .../jit/ICorJitInfo_wrapper_generated.hpp | 3 ++- src/coreclr/jit/importer.cpp | 2 +- src/coreclr/jit/jiteh.cpp | 4 ++- src/coreclr/jit/morph.cpp | 5 +++- .../JitInterface/CorInfoImpl_generated.cs | 6 ++--- .../ThunkGenerator/ThunkInput.txt | 2 +- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 2 +- .../JitInterface/CorInfoImpl.RyuJit.cs | 2 +- .../aot/jitinterface/jitinterface_generated.h | 5 ++-- .../superpmi-shared/methodcontext.cpp | 2 ++ .../superpmi/superpmi-shared/methodcontext.h | 2 ++ .../superpmi-shim-collector/icorjitinfo.cpp | 5 ++-- .../icorjitinfo_generated.cpp | 3 ++- .../icorjitinfo_generated.cpp | 3 ++- .../tools/superpmi/superpmi/icorjitinfo.cpp | 3 ++- src/coreclr/vm/jitinterface.cpp | 27 ++++++++++++------- src/coreclr/vm/jitinterface.h | 1 + 20 files changed, 58 insertions(+), 31 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 5fad5e4b2429e4..c8dc57b76e8103 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -3180,6 +3180,7 @@ class ICorDynamicInfo : public ICorStaticInfo virtual void embedGenericHandle( CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fEmbedParent, // `true` - embeds parent type handle of the field/method handle + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT * pResult ) = 0; diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index 46c0c817bad07d..36a692408e7691 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -556,6 +556,7 @@ CORINFO_FIELD_HANDLE embedFieldHandle( void embedGenericHandle( CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) override; void getLocationOfThisType( diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 11675936acfa37..74634509796b21 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 = { /* 991d4864-450b-4737-87b1-a2dccbd676a5 */ + 0x991d4864, + 0x450b, + 0x4737, + {0x87, 0xb1, 0xa2, 0xdc, 0xcb, 0xd6, 0x76, 0xa5} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index 1205512fabff0f..cc3c45fef10926 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -1321,10 +1321,11 @@ CORINFO_FIELD_HANDLE WrapICorJitInfo::embedFieldHandle( void WrapICorJitInfo::embedGenericHandle( CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { API_ENTER(embedGenericHandle); - wrapHnd->embedGenericHandle(pResolvedToken, fEmbedParent, pResult); + wrapHnd->embedGenericHandle(pResolvedToken, fEmbedParent, containingFtn, pResult); API_LEAVE(embedGenericHandle); } diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 7c2025cff00735..54e7b58d36526c 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1273,7 +1273,7 @@ GenTree* Compiler::impTokenToHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, assert(!fgGlobalMorph); CORINFO_GENERICHANDLE_RESULT embedInfo; - info.compCompHnd->embedGenericHandle(pResolvedToken, importParent, &embedInfo); + info.compCompHnd->embedGenericHandle(pResolvedToken, importParent, info.compMethodHnd, &embedInfo); if (pRuntimeLookup) { diff --git a/src/coreclr/jit/jiteh.cpp b/src/coreclr/jit/jiteh.cpp index 1d53a630064a25..4c7b0667745e6d 100644 --- a/src/coreclr/jit/jiteh.cpp +++ b/src/coreclr/jit/jiteh.cpp @@ -2339,7 +2339,9 @@ bool Compiler::fgCreateFiltersForGenericExceptions() info.compCompHnd->resolveToken(&resolvedToken); CORINFO_GENERICHANDLE_RESULT embedInfo; - info.compCompHnd->embedGenericHandle(&resolvedToken, true, &embedInfo); + // NOTE: inlining is done at this point, so we don't know which method contained this token. + // It's fine because currently this is never used for something that belongs to an inlinee. + info.compCompHnd->embedGenericHandle(&resolvedToken, true, nullptr, &embedInfo); if (!embedInfo.lookup.lookupKind.needsRuntimeLookup) { // Exception type does not need runtime lookup diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 7ebee438273e2c..0c8c895791efc8 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -7022,7 +7022,10 @@ GenTree* Compiler::getVirtMethodPointerTree(GenTree* thisPtr, GenTree* Compiler::getTokenHandleTree(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool parent) { CORINFO_GENERICHANDLE_RESULT embedInfo; - info.compCompHnd->embedGenericHandle(pResolvedToken, parent, &embedInfo); + + // NOTE: inlining is done at this point, so we don't know which method contained this token. + // It's fine because currently this is never used for something that belongs to an inlinee. + info.compCompHnd->embedGenericHandle(pResolvedToken, parent, nullptr, &embedInfo); GenTree* result = getLookupTree(pResolvedToken, &embedInfo.lookup, gtTokenToIconFlags(pResolvedToken->token), embedInfo.compileTimeHandle); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 7789862f5074a1..706b1a69d27858 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -1993,12 +1993,12 @@ private static CorInfoHelpFunc _getLazyStringLiteralHelper(IntPtr thisHandle, In } [UnmanagedCallersOnly] - private static void _embedGenericHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, byte fEmbedParent, CORINFO_GENERICHANDLE_RESULT* pResult) + private static void _embedGenericHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, byte fEmbedParent, CORINFO_METHOD_STRUCT_* containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { var _this = GetThis(thisHandle); try { - _this.embedGenericHandle(ref *pResolvedToken, fEmbedParent != 0, ref *pResult); + _this.embedGenericHandle(ref *pResolvedToken, fEmbedParent != 0, containingFtn, ref *pResult); } catch (Exception ex) { @@ -2701,7 +2701,7 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[131] = (delegate* unmanaged)&_embedClassHandle; callbacks[132] = (delegate* unmanaged)&_embedMethodHandle; callbacks[133] = (delegate* unmanaged)&_embedFieldHandle; - callbacks[134] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[134] = (delegate* unmanaged)&_embedGenericHandle; callbacks[135] = (delegate* unmanaged)&_getLocationOfThisType; callbacks[136] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; callbacks[137] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index fda65c03b9ab17..9abffd3c37a48d 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -296,7 +296,7 @@ FUNCTIONS CORINFO_CLASS_HANDLE embedClassHandle(CORINFO_CLASS_HANDLE handle, void **ppIndirection); CORINFO_METHOD_HANDLE embedMethodHandle(CORINFO_METHOD_HANDLE handle, void **ppIndirection); CORINFO_FIELD_HANDLE embedFieldHandle(CORINFO_FIELD_HANDLE handle, void **ppIndirection); - void embedGenericHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fEmbedParent, CORINFO_GENERICHANDLE_RESULT * pResult); + void embedGenericHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fEmbedParent, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT * pResult); void getLocationOfThisType(CORINFO_METHOD_HANDLE context, CORINFO_LOOKUP_KIND* pLookupKind); void getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP *pLookup); void* GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void ** ppIndirection); 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 ad83b1eb42a5d6..185e36cbd84a36 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -2752,7 +2752,7 @@ private void ceeInfoEmbedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken return null; } - private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fEmbedParent, ref CORINFO_GENERICHANDLE_RESULT pResult) + private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fEmbedParent, CORINFO_METHOD_STRUCT_* containingFtn, ref CORINFO_GENERICHANDLE_RESULT pResult) { ceeInfoEmbedGenericHandle(ref pResolvedToken, fEmbedParent, ref pResult); 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 8755580e3f2903..f51d8601a79c74 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -1721,7 +1721,7 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO } } - private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fEmbedParent, ref CORINFO_GENERICHANDLE_RESULT pResult) + private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fEmbedParent, CORINFO_METHOD_STRUCT_* containingFtn, ref CORINFO_GENERICHANDLE_RESULT pResult) { #if DEBUG // In debug, write some bogus data to the struct to ensure we have filled everything diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index 3723b57aa4d8e2..c7d936b12b14d0 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -145,7 +145,7 @@ struct JitInterfaceCallbacks CORINFO_CLASS_HANDLE (* embedClassHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE handle, void** ppIndirection); CORINFO_METHOD_HANDLE (* embedMethodHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE handle, void** ppIndirection); CORINFO_FIELD_HANDLE (* embedFieldHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE handle, void** ppIndirection); - void (* embedGenericHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, CORINFO_GENERICHANDLE_RESULT* pResult); + void (* embedGenericHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult); void (* getLocationOfThisType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE context, CORINFO_LOOKUP_KIND* pLookupKind); void (* getAddressOfPInvokeTarget)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP* pLookup); void* (* GetCookieForPInvokeCalliSig)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* szMetaSig, void** ppIndirection); @@ -1496,10 +1496,11 @@ class JitInterfaceWrapper : public ICorJitInfo virtual void embedGenericHandle( CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { CorInfoExceptionClass* pException = nullptr; - _callbacks->embedGenericHandle(_thisHandle, &pException, pResolvedToken, fEmbedParent, pResult); + _callbacks->embedGenericHandle(_thisHandle, &pException, pResolvedToken, fEmbedParent, containingFtn, pResult); if (pException != nullptr) throw pException; } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index c72b8b1eec1f6c..02c739832dcddd 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -3101,6 +3101,7 @@ CorInfoHelpFunc MethodContext::repGetNewHelper(CORINFO_CLASS_HANDLE classHandle void MethodContext::recEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { if (EmbedGenericHandle == nullptr) @@ -3131,6 +3132,7 @@ void MethodContext::dmpEmbedGenericHandle(const Agnostic_EmbedGenericHandle& } void MethodContext::repEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { AssertMapExistsNoMessage(EmbedGenericHandle); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 74128026015006..67ee475c650b36 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -423,11 +423,13 @@ class MethodContext void recEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult); void dmpEmbedGenericHandle(const Agnostic_EmbedGenericHandle& key, const Agnostic_CORINFO_GENERICHANDLE_RESULT& value); void repEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult); void recGetEHinfo(CORINFO_METHOD_HANDLE ftn, unsigned EHnumber, CORINFO_EH_CLAUSE* clause); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 0cbcfb2df1b0b1..2bb0d4ac9b9e83 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1523,11 +1523,12 @@ CORINFO_FIELD_HANDLE interceptor_ICJI::embedFieldHandle(CORINFO_FIELD_HANDLE han void interceptor_ICJI::embedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, // TRUE - embeds parent type handle of the field/method // handle + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { mc->cr->AddCall("embedGenericHandle"); - original_ICorJitInfo->embedGenericHandle(pResolvedToken, fEmbedParent, pResult); - mc->recEmbedGenericHandle(pResolvedToken, fEmbedParent, pResult); + original_ICorJitInfo->embedGenericHandle(pResolvedToken, fEmbedParent, containingFtn, pResult); + mc->recEmbedGenericHandle(pResolvedToken, fEmbedParent, containingFtn, pResult); } // Return information used to locate the exact enclosing type of the current method. 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..54d8aa6cfe4db0 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -1083,10 +1083,11 @@ CORINFO_FIELD_HANDLE interceptor_ICJI::embedFieldHandle( void interceptor_ICJI::embedGenericHandle( CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { mcs->AddCall("embedGenericHandle"); - original_ICorJitInfo->embedGenericHandle(pResolvedToken, fEmbedParent, pResult); + original_ICorJitInfo->embedGenericHandle(pResolvedToken, fEmbedParent, containingFtn, pResult); } void interceptor_ICJI::getLocationOfThisType( 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..f23d93c6e18952 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -949,9 +949,10 @@ CORINFO_FIELD_HANDLE interceptor_ICJI::embedFieldHandle( void interceptor_ICJI::embedGenericHandle( CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { - original_ICorJitInfo->embedGenericHandle(pResolvedToken, fEmbedParent, pResult); + original_ICorJitInfo->embedGenericHandle(pResolvedToken, fEmbedParent, containingFtn, pResult); } void interceptor_ICJI::getLocationOfThisType( diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 2c0b79bab4fcd9..ac5568628a9bda 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -1332,10 +1332,11 @@ CORINFO_FIELD_HANDLE MyICJI::embedFieldHandle(CORINFO_FIELD_HANDLE handle, void* // void MyICJI::embedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, // TRUE - embeds parent type handle of the field/method handle + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { jitInstance->mc->cr->AddCall("embedGenericHandle"); - jitInstance->mc->repEmbedGenericHandle(pResolvedToken, fEmbedParent, pResult); + jitInstance->mc->repEmbedGenericHandle(pResolvedToken, fEmbedParent, containingFtn, pResult); } // Return information used to locate the exact enclosing type of the current method. diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 80534e2129418c..4fd2c5e395ac1e 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -2792,6 +2792,7 @@ void CEEInfo::MethodCompileComplete(CORINFO_METHOD_HANDLE methHnd) void CEEInfo::embedGenericHandle( CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fEmbedParent, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT *pResult) { CONTRACTL { @@ -2894,6 +2895,7 @@ void CEEInfo::embedGenericHandle( pResolvedToken, NULL, pTemplateMD, + (MethodDesc*)containingFtn, &pResult->lookup); } else @@ -3064,6 +3066,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken, MethodDesc * pTemplateMD /* for method-based slots */, + MethodDesc * pContainingMD, CORINFO_LOOKUP *pResultLookup) { CONTRACTL{ @@ -3099,18 +3102,22 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr return; } + if (inlinedClassParamLookup) + { + if (pContainingMD == nullptr) + { + pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_NOT_SUPPORTED; + return; + } + pContextMD = pContainingMD; + } + // There is a pathological case where invalid IL refereces __Canon type directly, // but there is no dictionary available to store the lookup. if (!inlinedClassParamLookup && !inlinedMethodParamLookup && !pContextMD->IsSharedByGenericInstantiations()) COMPlusThrow(kInvalidProgramException); - if (inlinedClassParamLookup) - { - // TODO: how do we figure out whether we need CORINFO_LOOKUP_THISOBJ or CORINFO_LOOKUP_CLASSPARAM? - pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_NOT_SUPPORTED; - return; - } - else if (pContextMD->RequiresInstMethodDescArg() || inlinedMethodParamLookup) + if (pContextMD->RequiresInstMethodDescArg() || inlinedMethodParamLookup) { pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_METHODPARAM; } @@ -3125,7 +3132,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr BOOL fInstrument = FALSE; // If we've got a method type parameter of any kind then we must look in the method desc arg - if (!inlinedClassParamLookup && (pContextMD->RequiresInstMethodDescArg() || inlinedMethodParamLookup)) + if (pContextMD->RequiresInstMethodDescArg() || inlinedMethodParamLookup) { pResult->helper = fInstrument ? CORINFO_HELP_RUNTIMEHANDLE_METHOD_LOG : CORINFO_HELP_RUNTIMEHANDLE_METHOD; @@ -3192,7 +3199,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr { _ASSERTE(pContextMT->GetNumGenericArgs() > 0); - if (!inlinedClassParamLookup && pContextMD->RequiresInstMethodTableArg()) + if (pContextMD->RequiresInstMethodTableArg()) { // If we've got a vtable extra argument, go through that pResult->helper = fInstrument ? CORINFO_HELP_RUNTIMEHANDLE_CLASS_LOG : CORINFO_HELP_RUNTIMEHANDLE_CLASS; @@ -5431,6 +5438,7 @@ void CEEInfo::getCallInfo( pResolvedToken, pConstrainedResolvedToken, pMD, + nullptr, &pResult->codePointerLookup); } else @@ -5482,6 +5490,7 @@ void CEEInfo::getCallInfo( pResolvedToken, pConstrainedResolvedToken, pMD, + nullptr, &pResult->stubLookup); } else diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index bbca5c355fbb97..23489179dfaea4 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -558,6 +558,7 @@ class CEEInfo : public ICorJitInfo CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken /* for ConstrainedMethodEntrySlot */, MethodDesc * pTemplateMD /* for method-based slots */, + MethodDesc * pContainingMD, CORINFO_LOOKUP *pResultLookup); #if defined(FEATURE_GDBJIT) From 728272efc2f38391ed7fb7ddd809bb22d7a0d278 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 9 Mar 2024 05:18:12 +0100 Subject: [PATCH 11/40] clean up --- src/coreclr/vm/jitinterface.cpp | 36 +++++++++++---------------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 4fd2c5e395ac1e..eb9a7c3d828c6d 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -3089,35 +3089,23 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr // Unless we decide otherwise, just do the lookup via a helper function pResult->indirections = CORINFO_USEHELPER; - MethodDesc* pContextMD = GetMethodFromContext(pResolvedToken->tokenContext); - MethodTable* pContextMT = GetTypeFromContext(pResolvedToken->tokenContext).AsMethodTable(); + MethodDesc* pContextMD = GetMethodFromContext(pResolvedToken->tokenContext); - bool inlinedMethodParamLookup = pContextMD != nullptr && pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT(); - bool inlinedClassParamLookup = pContextMD == nullptr && pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT(); - - if ((inlinedMethodParamLookup && !pContextMD->HasMethodInstantiation()) || - (inlinedClassParamLookup && !pContextMT->HasInstantiation())) - { - pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_NOT_SUPPORTED; - return; - } - - if (inlinedClassParamLookup) + bool isInlining = pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT(); + if (isInlining) { - if (pContainingMD == nullptr) - { - pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_NOT_SUPPORTED; - return; - } + _ASSERT(pContainingMD != nullptr); pContextMD = pContainingMD; } + MethodTable* pContextMT = pContextMD->GetMethodTable(); + // There is a pathological case where invalid IL refereces __Canon type directly, // but there is no dictionary available to store the lookup. - if (!inlinedClassParamLookup && !inlinedMethodParamLookup && !pContextMD->IsSharedByGenericInstantiations()) + if (!isInlining && !pContextMD->IsSharedByGenericInstantiations()) COMPlusThrow(kInvalidProgramException); - if (pContextMD->RequiresInstMethodDescArg() || inlinedMethodParamLookup) + if (pContextMD->RequiresInstMethodDescArg()) { pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_METHODPARAM; } @@ -3132,7 +3120,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr BOOL fInstrument = FALSE; // If we've got a method type parameter of any kind then we must look in the method desc arg - if (pContextMD->RequiresInstMethodDescArg() || inlinedMethodParamLookup) + if (pContextMD->RequiresInstMethodDescArg()) { pResult->helper = fInstrument ? CORINFO_HELP_RUNTIMEHANDLE_METHOD_LOG : CORINFO_HELP_RUNTIMEHANDLE_METHOD; @@ -3207,7 +3195,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr // If we've got an object, go through its vtable else { - _ASSERTE(inlinedClassParamLookup || pContextMD->AcquiresInstMethodTableFromThis()); + _ASSERTE(pContextMD->AcquiresInstMethodTableFromThis()); pResult->helper = fInstrument ? CORINFO_HELP_RUNTIMEHANDLE_CLASS_LOG : CORINFO_HELP_RUNTIMEHANDLE_CLASS; } @@ -5438,7 +5426,7 @@ void CEEInfo::getCallInfo( pResolvedToken, pConstrainedResolvedToken, pMD, - nullptr, + (MethodDesc*)callerHandle, &pResult->codePointerLookup); } else @@ -5490,7 +5478,7 @@ void CEEInfo::getCallInfo( pResolvedToken, pConstrainedResolvedToken, pMD, - nullptr, + (MethodDesc*)callerHandle, &pResult->stubLookup); } else From 7c4e36d7d21640c6c167251397b1aafcf5871925 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 9 Mar 2024 14:06:32 +0100 Subject: [PATCH 12/40] initial NAOT support --- src/coreclr/inc/corinfo.h | 1 + src/coreclr/inc/icorjitinfoimpl_generated.h | 1 + src/coreclr/inc/jiteeversionguid.h | 10 ++++----- .../jit/ICorJitInfo_wrapper_generated.hpp | 3 ++- src/coreclr/jit/importercalls.cpp | 2 +- .../JitInterface/CorInfoImpl_generated.cs | 6 ++--- .../ThunkGenerator/ThunkInput.txt | 2 +- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 2 +- .../JitInterface/CorInfoImpl.RyuJit.cs | 16 +++++++++----- .../aot/jitinterface/jitinterface_generated.h | 5 +++-- .../tools/superpmi/superpmi-shared/agnostic.h | 7 ++++++ .../tools/superpmi/superpmi-shared/lwmlist.h | 2 +- .../superpmi-shared/methodcontext.cpp | 22 +++++++++++-------- .../superpmi/superpmi-shared/methodcontext.h | 6 ++--- .../superpmi-shim-collector/icorjitinfo.cpp | 5 +++-- .../icorjitinfo_generated.cpp | 3 ++- .../icorjitinfo_generated.cpp | 3 ++- .../tools/superpmi/superpmi/icorjitinfo.cpp | 4 ++-- src/coreclr/vm/jitinterface.cpp | 20 ++++++++++------- 19 files changed, 73 insertions(+), 47 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index c8dc57b76e8103..94227043572cd4 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2221,6 +2221,7 @@ class ICorStaticInfo // should be looked up at runtime. virtual void expandRawHandleIntrinsic( CORINFO_RESOLVED_TOKEN * pResolvedToken, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT * pResult) = 0; // Is the given type in System.Private.Corelib and marked with IntrinsicAttribute? diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index 36a692408e7691..6c7f83e1e5acd8 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -104,6 +104,7 @@ CORINFO_CLASS_HANDLE getDefaultEqualityComparerClass( void expandRawHandleIntrinsic( CORINFO_RESOLVED_TOKEN* pResolvedToken, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) override; bool isIntrinsicType( diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 74634509796b21..b658a091d38da6 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 = { /* 991d4864-450b-4737-87b1-a2dccbd676a5 */ - 0x991d4864, - 0x450b, - 0x4737, - {0x87, 0xb1, 0xa2, 0xdc, 0xcb, 0xd6, 0x76, 0xa5} +constexpr GUID JITEEVersionIdentifier = { /* 19aca9ab-66c1-47bd-bc45-db47a3ed02b6 */ + 0x19aca9ab, + 0x66c1, + 0x47bd, + {0xbc, 0x45, 0xdb, 0x47, 0xa3, 0xed, 0x02, 0xb6} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index cc3c45fef10926..a20ee9aa3b74c6 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -202,10 +202,11 @@ CORINFO_CLASS_HANDLE WrapICorJitInfo::getDefaultEqualityComparerClass( void WrapICorJitInfo::expandRawHandleIntrinsic( CORINFO_RESOLVED_TOKEN* pResolvedToken, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { API_ENTER(expandRawHandleIntrinsic); - wrapHnd->expandRawHandleIntrinsic(pResolvedToken, pResult); + wrapHnd->expandRawHandleIntrinsic(pResolvedToken, containingFtn, pResult); API_LEAVE(expandRawHandleIntrinsic); } diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 4fb75b7d398092..92858e34511f4f 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3151,7 +3151,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, resolvedToken.tokenType = CORINFO_TOKENKIND_Method; CORINFO_GENERICHANDLE_RESULT embedInfo; - info.compCompHnd->expandRawHandleIntrinsic(&resolvedToken, &embedInfo); + info.compCompHnd->expandRawHandleIntrinsic(&resolvedToken, info.compMethodHnd, &embedInfo); GenTree* rawHandle = impLookupToTree(&resolvedToken, &embedInfo.lookup, gtTokenToIconFlags(memberRef), embedInfo.compileTimeHandle); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 706b1a69d27858..74ebad63130816 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -291,12 +291,12 @@ private static byte _resolveVirtualMethod(IntPtr thisHandle, IntPtr* ppException } [UnmanagedCallersOnly] - private static void _expandRawHandleIntrinsic(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_GENERICHANDLE_RESULT* pResult) + private static void _expandRawHandleIntrinsic(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_STRUCT_* containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { var _this = GetThis(thisHandle); try { - _this.expandRawHandleIntrinsic(ref *pResolvedToken, ref *pResult); + _this.expandRawHandleIntrinsic(ref *pResolvedToken, containingFtn, ref *pResult); } catch (Exception ex) { @@ -2586,7 +2586,7 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[16] = (delegate* unmanaged)&_getUnboxedEntry; callbacks[17] = (delegate* unmanaged)&_getDefaultComparerClass; callbacks[18] = (delegate* unmanaged)&_getDefaultEqualityComparerClass; - callbacks[19] = (delegate* unmanaged)&_expandRawHandleIntrinsic; + callbacks[19] = (delegate* unmanaged)&_expandRawHandleIntrinsic; callbacks[20] = (delegate* unmanaged)&_isIntrinsicType; callbacks[21] = (delegate* unmanaged)&_getUnmanagedCallConv; callbacks[22] = (delegate* unmanaged)&_pInvokeMarshalingRequired; diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 9abffd3c37a48d..7e31170301071f 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -181,7 +181,7 @@ FUNCTIONS CORINFO_METHOD_HANDLE getUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg); CORINFO_CLASS_HANDLE getDefaultComparerClass(CORINFO_CLASS_HANDLE elemType); CORINFO_CLASS_HANDLE getDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE elemType); - void expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_GENERICHANDLE_RESULT * pResult); + void expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT * pResult); bool isIntrinsicType( CORINFO_CLASS_HANDLE classHnd ); CorInfoCallConvExtension getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition); bool pInvokeMarshalingRequired( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig ); 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 185e36cbd84a36..cc1afb37fe5831 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -2957,7 +2957,7 @@ private void getGSCookie(IntPtr* pCookieVal, IntPtr** ppCookieVal) private void getMethodVTableOffset(CORINFO_METHOD_STRUCT_* method, ref uint offsetOfIndirection, ref uint offsetAfterIndirection, ref bool isRelative) { throw new NotImplementedException("getMethodVTableOffset"); } - private void expandRawHandleIntrinsic(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref CORINFO_GENERICHANDLE_RESULT pResult) + private void expandRawHandleIntrinsic(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_METHOD_STRUCT_* containingFtn, ref CORINFO_GENERICHANDLE_RESULT pResult) { throw new NotImplementedException("expandRawHandleIntrinsic"); } private void* getMethodSync(CORINFO_METHOD_STRUCT_* ftn, ref void* ppIndirection) 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 f51d8601a79c74..a633407d1fdee8 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -239,7 +239,7 @@ private static CORINFO_RUNTIME_LOOKUP_KIND GetLookupKindFromContextSource(Generi } } - private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object entity, ReadyToRunHelperId helperId, ref CORINFO_LOOKUP lookup) + private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object entity, ReadyToRunHelperId helperId, MethodDesc containingFtn, ref CORINFO_LOOKUP lookup) { if (_compilation.NeedsRuntimeLookup(helperId, entity)) { @@ -1414,6 +1414,7 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO ComputeLookup(ref pResolvedToken, targetOfLookup, ReadyToRunHelperId.MethodEntry, + HandleToObject(callerHandle), ref pResult->codePointerOrStubLookup); targetIsFatFunctionPointer = true; @@ -1565,6 +1566,7 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO ComputeLookup(ref pResolvedToken, constrainedCallInfo, constrainedHelperId, + HandleToObject(callerHandle), ref pResult->codePointerOrStubLookup); targetIsFatFunctionPointer = true; @@ -1587,6 +1589,7 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO ComputeLookup(ref pResolvedToken, targetOfLookup, ReadyToRunHelperId.MethodHandle, + HandleToObject(callerHandle), ref pResult->codePointerOrStubLookup); // RyuJIT will assert if we report CORINFO_CALLCONV_PARAMTYPE for a result of a ldvirtftn @@ -1604,6 +1607,7 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO ComputeLookup(ref pResolvedToken, GetRuntimeDeterminedObjectForToken(ref pResolvedToken), ReadyToRunHelperId.VirtualDispatchCell, + HandleToObject(callerHandle), ref pResult->codePointerOrStubLookup); Debug.Assert(pResult->codePointerOrStubLookup.lookupKind.needsRuntimeLookup); } @@ -1812,7 +1816,7 @@ private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool Debug.Assert(pResult.compileTimeHandle != null); - ComputeLookup(ref pResolvedToken, target, helperId, ref pResult.lookup); + ComputeLookup(ref pResolvedToken, target, helperId, HandleToObject(containingFtn), ref pResult.lookup); } private CORINFO_METHOD_STRUCT_* embedMethodHandle(CORINFO_METHOD_STRUCT_* handle, ref void* ppIndirection) @@ -1857,7 +1861,7 @@ private void getMethodVTableOffset(CORINFO_METHOD_STRUCT_* method, ref uint offs offsetAfterIndirection = (uint)(EETypeNode.GetVTableOffset(pointerSize) + slot * pointerSize); } - private void expandRawHandleIntrinsic(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref CORINFO_GENERICHANDLE_RESULT pResult) + private void expandRawHandleIntrinsic(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_METHOD_STRUCT_* containingFtn, ref CORINFO_GENERICHANDLE_RESULT pResult) { // Resolved token as a potentially RuntimeDetermined object. MethodDesc method = (MethodDesc)GetRuntimeDeterminedObjectForToken(ref pResolvedToken); @@ -1867,15 +1871,15 @@ private void expandRawHandleIntrinsic(ref CORINFO_RESOLVED_TOKEN pResolvedToken, switch (method.Name) { case "Of": - ComputeLookup(ref pResolvedToken, method.Instantiation[0], ReadyToRunHelperId.TypeHandle, ref pResult.lookup); + ComputeLookup(ref pResolvedToken, method.Instantiation[0], ReadyToRunHelperId.TypeHandle, HandleToObject(containingFtn), ref pResult.lookup); pResult.handleType = CorInfoGenericHandleType.CORINFO_HANDLETYPE_CLASS; break; case "DefaultConstructorOf": - ComputeLookup(ref pResolvedToken, method.Instantiation[0], ReadyToRunHelperId.DefaultConstructor, ref pResult.lookup); + ComputeLookup(ref pResolvedToken, method.Instantiation[0], ReadyToRunHelperId.DefaultConstructor, HandleToObject(containingFtn), ref pResult.lookup); pResult.handleType = CorInfoGenericHandleType.CORINFO_HANDLETYPE_METHOD; break; case "AllocatorOf": - ComputeLookup(ref pResolvedToken, method.Instantiation[0], ReadyToRunHelperId.ObjectAllocator, ref pResult.lookup); + ComputeLookup(ref pResolvedToken, method.Instantiation[0], ReadyToRunHelperId.ObjectAllocator, HandleToObject(containingFtn), ref pResult.lookup); pResult.handleType = CorInfoGenericHandleType.CORINFO_HANDLETYPE_UNKNOWN; break; default: diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index c7d936b12b14d0..6e77e7dba1ffb3 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -30,7 +30,7 @@ struct JitInterfaceCallbacks CORINFO_METHOD_HANDLE (* getUnboxedEntry)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg); CORINFO_CLASS_HANDLE (* getDefaultComparerClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE elemType); CORINFO_CLASS_HANDLE (* getDefaultEqualityComparerClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE elemType); - void (* expandRawHandleIntrinsic)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_GENERICHANDLE_RESULT* pResult); + void (* expandRawHandleIntrinsic)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult); bool (* isIntrinsicType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE classHnd); CorInfoCallConvExtension (* getUnmanagedCallConv)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition); bool (* pInvokeMarshalingRequired)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); @@ -389,10 +389,11 @@ class JitInterfaceWrapper : public ICorJitInfo virtual void expandRawHandleIntrinsic( CORINFO_RESOLVED_TOKEN* pResolvedToken, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { CorInfoExceptionClass* pException = nullptr; - _callbacks->expandRawHandleIntrinsic(_thisHandle, &pException, pResolvedToken, pResult); + _callbacks->expandRawHandleIntrinsic(_thisHandle, &pException, pResolvedToken, containingFtn, pResult); if (pException != nullptr) throw pException; } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h index 3ee4190e889065..56a296dd85c690 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h @@ -423,9 +423,16 @@ struct Agnostic_CheckMethodModifier struct Agnostic_EmbedGenericHandle { Agnostic_CORINFO_RESOLVED_TOKEN ResolvedToken; + DWORDLONG hContainingFtn; DWORD fEmbedParent; }; +struct Agnostic_ExpandRawHandleIntrinsic +{ + Agnostic_CORINFO_RESOLVED_TOKEN ResolvedToken; + DWORDLONG hContainingFtn; +}; + struct Agnostic_CORINFO_GENERICHANDLE_RESULT { Agnostic_CORINFO_LOOKUP lookup; diff --git a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h index a44faac3cee24e..9a97d9f3f2c2f5 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -146,7 +146,7 @@ LWM(InitClass, Agnostic_InitClass, DWORD) LWM(IsDelegateCreationAllowed, DLDL, DWORD) LWM(IsFieldStatic, DWORDLONG, DWORD) LWM(GetArrayOrStringLength, DWORDLONG, DWORD) -LWM(ExpandRawHandleIntrinsic, Agnostic_CORINFO_RESOLVED_TOKENin, Agnostic_CORINFO_GENERICHANDLE_RESULT) +LWM(ExpandRawHandleIntrinsic, Agnostic_ExpandRawHandleIntrinsic, Agnostic_CORINFO_GENERICHANDLE_RESULT) LWM(IsIntrinsicType, DWORDLONG, DWORD) LWM(IsSDArray, DWORDLONG, DWORD) LWM(GetStringLiteral, DLDDD, DD) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 02c739832dcddd..249dc459b4b434 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -1670,14 +1670,15 @@ void MethodContext::repGetCallInfoFromMethodHandle(CORINFO_METHOD_HANDLE methodH LogException(EXCEPTIONCODE_MC, "Didn't find key %016" PRIX64 ".", methodHandle); } -void MethodContext::recExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_GENERICHANDLE_RESULT* pResult) +void MethodContext::recExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { if (ExpandRawHandleIntrinsic == nullptr) - ExpandRawHandleIntrinsic = new LightWeightMap; + ExpandRawHandleIntrinsic = new LightWeightMap; - Agnostic_CORINFO_RESOLVED_TOKENin key; + Agnostic_ExpandRawHandleIntrinsic key; ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key = SpmiRecordsHelper::CreateAgnostic_CORINFO_RESOLVED_TOKENin(pResolvedToken); + key.ResolvedToken = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, ExpandRawHandleIntrinsic); + key.hContainingFtn = CastHandle(containingFtn); Agnostic_CORINFO_GENERICHANDLE_RESULT value; value.lookup = SpmiRecordsHelper::StoreAgnostic_CORINFO_LOOKUP(&pResult->lookup); @@ -1687,19 +1688,21 @@ void MethodContext::recExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolve ExpandRawHandleIntrinsic->Add(key, value); DEBUG_REC(dmpExpandRawHandleIntrinsic(key, value)); } -void MethodContext::dmpExpandRawHandleIntrinsic(const Agnostic_CORINFO_RESOLVED_TOKENin& key, const Agnostic_CORINFO_GENERICHANDLE_RESULT& result) +void MethodContext::dmpExpandRawHandleIntrinsic(const Agnostic_ExpandRawHandleIntrinsic& key, const Agnostic_CORINFO_GENERICHANDLE_RESULT& result) { printf("ExpandRawHandleIntrinsic key: %s, value %s cth-%016" PRIx64 " ht-%u", - SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKENin(key).c_str(), + SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(key.ResolvedToken).c_str(), SpmiDumpHelper::DumpAgnostic_CORINFO_LOOKUP(result.lookup).c_str(), result.compileTimeHandle, result.handleType); } -void MethodContext::repExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_GENERICHANDLE_RESULT* pResult) +void MethodContext::repExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { - Agnostic_CORINFO_RESOLVED_TOKENin key; + Agnostic_ExpandRawHandleIntrinsic key; ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key = SpmiRecordsHelper::CreateAgnostic_CORINFO_RESOLVED_TOKENin(pResolvedToken); + + key.ResolvedToken = SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, ExpandRawHandleIntrinsic); + key.hContainingFtn = CastHandle(containingFtn); Agnostic_CORINFO_GENERICHANDLE_RESULT value = LookupByKeyOrMiss(ExpandRawHandleIntrinsic, key, ": key %x", pResolvedToken->token); @@ -3111,6 +3114,7 @@ void MethodContext::recEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolve ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding key.ResolvedToken = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, EmbedGenericHandle); key.fEmbedParent = (DWORD)fEmbedParent; + key.hContainingFtn = CastHandle(containingFtn); Agnostic_CORINFO_GENERICHANDLE_RESULT value; value.lookup = SpmiRecordsHelper::StoreAgnostic_CORINFO_LOOKUP(&pResult->lookup); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 67ee475c650b36..ff1420c8200879 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -272,9 +272,9 @@ class MethodContext void dmpIsSDArray(DWORDLONG key, DWORD value); bool repIsSDArray(CORINFO_CLASS_HANDLE cls); - void recExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_GENERICHANDLE_RESULT* pResult); - void dmpExpandRawHandleIntrinsic(const Agnostic_CORINFO_RESOLVED_TOKENin& key, const Agnostic_CORINFO_GENERICHANDLE_RESULT& result); - void repExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_GENERICHANDLE_RESULT* pResult); + void recExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult); + void dmpExpandRawHandleIntrinsic(const Agnostic_ExpandRawHandleIntrinsic& key, const Agnostic_CORINFO_GENERICHANDLE_RESULT& result); + void repExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult); void recIsIntrinsicType(CORINFO_CLASS_HANDLE cls, bool result); void dmpIsIntrinsicType(DWORDLONG key, DWORD value); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 2bb0d4ac9b9e83..bff44379f899b5 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -259,11 +259,12 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::getDefaultEqualityComparerClass(CORINFO_C } void interceptor_ICJI::expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { mc->cr->AddCall("expandRawHandleIntrinsic"); - original_ICorJitInfo->expandRawHandleIntrinsic(pResolvedToken, pResult); - mc->recExpandRawHandleIntrinsic(pResolvedToken, pResult); + original_ICorJitInfo->expandRawHandleIntrinsic(pResolvedToken, containingFtn, pResult); + mc->recExpandRawHandleIntrinsic(pResolvedToken, containingFtn, pResult); } // Is the given type in System.Private.Corelib and marked with IntrinsicAttribute? 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 54d8aa6cfe4db0..89d361f845e77a 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -171,10 +171,11 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::getDefaultEqualityComparerClass( void interceptor_ICJI::expandRawHandleIntrinsic( CORINFO_RESOLVED_TOKEN* pResolvedToken, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { mcs->AddCall("expandRawHandleIntrinsic"); - original_ICorJitInfo->expandRawHandleIntrinsic(pResolvedToken, pResult); + original_ICorJitInfo->expandRawHandleIntrinsic(pResolvedToken, containingFtn, pResult); } bool interceptor_ICJI::isIntrinsicType( 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 f23d93c6e18952..52f1b2e7ddcdd7 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -152,9 +152,10 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::getDefaultEqualityComparerClass( void interceptor_ICJI::expandRawHandleIntrinsic( CORINFO_RESOLVED_TOKEN* pResolvedToken, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { - original_ICorJitInfo->expandRawHandleIntrinsic(pResolvedToken, pResult); + original_ICorJitInfo->expandRawHandleIntrinsic(pResolvedToken, containingFtn, pResult); } bool interceptor_ICJI::isIntrinsicType( diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index ac5568628a9bda..166a361a741258 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -221,10 +221,10 @@ CORINFO_CLASS_HANDLE MyICJI::getDefaultEqualityComparerClass(CORINFO_CLASS_HANDL return result; } -void MyICJI::expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_GENERICHANDLE_RESULT* pResult) +void MyICJI::expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) { jitInstance->mc->cr->AddCall("expandRawHandleIntrinsic"); - jitInstance->mc->repExpandRawHandleIntrinsic(pResolvedToken, pResult); + jitInstance->mc->repExpandRawHandleIntrinsic(pResolvedToken, containingFtn, pResult); } // Is the given type in System.Private.Corelib and marked with IntrinsicAttribute? diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index eb9a7c3d828c6d..c5f2e53702164e 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -3089,22 +3089,27 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr // Unless we decide otherwise, just do the lookup via a helper function pResult->indirections = CORINFO_USEHELPER; - MethodDesc* pContextMD = GetMethodFromContext(pResolvedToken->tokenContext); + MethodDesc* pContextMD; - bool isInlining = pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT(); - if (isInlining) + bool inlinedLookup = pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT(); + if (inlinedLookup) { _ASSERT(pContainingMD != nullptr); pContextMD = pContainingMD; } + else + { + pContextMD = GetMethodFromContext(pResolvedToken->tokenContext); + } MethodTable* pContextMT = pContextMD->GetMethodTable(); - // There is a pathological case where invalid IL refereces __Canon type directly, - // but there is no dictionary available to store the lookup. - if (!isInlining && !pContextMD->IsSharedByGenericInstantiations()) + // There is a pathological case where invalid IL refereces __Canon type directly, but there is no dictionary availabled to store the lookup. + if (!inlinedLookup && !pContextMD->IsSharedByGenericInstantiations()) COMPlusThrow(kInvalidProgramException); + BOOL fInstrument = FALSE; + if (pContextMD->RequiresInstMethodDescArg()) { pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_METHODPARAM; @@ -3117,8 +3122,6 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_THISOBJ; } - BOOL fInstrument = FALSE; - // If we've got a method type parameter of any kind then we must look in the method desc arg if (pContextMD->RequiresInstMethodDescArg()) { @@ -8939,6 +8942,7 @@ CORINFO_METHOD_HANDLE CEEInfo::getUnboxedEntry( /*********************************************************************/ void CEEInfo::expandRawHandleIntrinsic( CORINFO_RESOLVED_TOKEN * pResolvedToken, + CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT * pResult) { LIMITED_METHOD_CONTRACT; From 0283ae7eedc7aa428e5e77039bac985316651ef6 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 9 Mar 2024 14:17:42 +0100 Subject: [PATCH 13/40] Implement NAOT --- src/coreclr/jit/jiteh.cpp | 2 +- src/coreclr/jit/morph.cpp | 2 +- .../JitInterface/CorInfoImpl.RyuJit.cs | 16 +++++++++------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/coreclr/jit/jiteh.cpp b/src/coreclr/jit/jiteh.cpp index 4c7b0667745e6d..a607ee9f672d3e 100644 --- a/src/coreclr/jit/jiteh.cpp +++ b/src/coreclr/jit/jiteh.cpp @@ -2341,7 +2341,7 @@ bool Compiler::fgCreateFiltersForGenericExceptions() CORINFO_GENERICHANDLE_RESULT embedInfo; // NOTE: inlining is done at this point, so we don't know which method contained this token. // It's fine because currently this is never used for something that belongs to an inlinee. - info.compCompHnd->embedGenericHandle(&resolvedToken, true, nullptr, &embedInfo); + info.compCompHnd->embedGenericHandle(&resolvedToken, true, info.compMethodHnd, &embedInfo); if (!embedInfo.lookup.lookupKind.needsRuntimeLookup) { // Exception type does not need runtime lookup diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 0c8c895791efc8..2122b0619a76b1 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -7025,7 +7025,7 @@ GenTree* Compiler::getTokenHandleTree(CORINFO_RESOLVED_TOKEN* pResolvedToken, bo // NOTE: inlining is done at this point, so we don't know which method contained this token. // It's fine because currently this is never used for something that belongs to an inlinee. - info.compCompHnd->embedGenericHandle(pResolvedToken, parent, nullptr, &embedInfo); + info.compCompHnd->embedGenericHandle(pResolvedToken, parent, info.compMethodHnd, &embedInfo); GenTree* result = getLookupTree(pResolvedToken, &embedInfo.lookup, gtTokenToIconFlags(pResolvedToken->token), embedInfo.compileTimeHandle); 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 a633407d1fdee8..285b032bae8b65 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -246,15 +246,17 @@ private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object ent lookup.lookupKind.needsRuntimeLookup = true; lookup.runtimeLookup.signature = null; - // Do not bother computing the runtime lookup if we are inlining. The JIT is going - // to abort the inlining attempt anyway. - if (pResolvedToken.tokenContext != contextFromMethodBeingCompiled()) + MethodDesc contextMethod; + bool inlinedLookup = pResolvedToken.tokenContext != contextFromMethodBeingCompiled(); + if (inlinedLookup) { - lookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_NOT_SUPPORTED; - return; + Debug.Assert(containingFtn != null); + contextMethod = containingFtn; + } + else + { + contextMethod = methodFromContext(pResolvedToken.tokenContext); } - - MethodDesc contextMethod = methodFromContext(pResolvedToken.tokenContext); GenericDictionaryLookup genericLookup = _compilation.ComputeGenericLookup(contextMethod, helperId, entity); From cd51417dcbf8e52f938d8ff604749cb6c86059b5 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 9 Mar 2024 14:54:24 +0100 Subject: [PATCH 14/40] Clean up --- src/coreclr/jit/importer.cpp | 18 ++++++++++++------ src/coreclr/jit/jiteh.cpp | 5 ----- src/coreclr/jit/morph.cpp | 10 ++++++---- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 54e7b58d36526c..9c3d10dbc556a6 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1538,7 +1538,7 @@ GenTree* Compiler::impMethodPointer(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORI // getRuntimeContextTree: find pointer to context for runtime lookup. // // Arguments: -// kind - lookup kind. +// kind - lookup kind. // // Return Value: // Return GenTree pointer to generic shared context. @@ -1564,6 +1564,10 @@ GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind) ctxTree = impInlineFetchArg(*impInlineInfo->inlInstParamArgInfo, lclInfo); assert(ctxTree != nullptr); assert(ctxTree->TypeIs(TYP_I_IMPL)); + if (ctxTree->OperIs(GT_LCL_VAR)) + { + ctxTree->gtFlags |= GTF_VAR_CONTEXT; + } } else if (kind == CORINFO_LOOKUP_THISOBJ) { @@ -1575,18 +1579,20 @@ GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind) assert(impInlineInfo->inlArgInfo[0].argIsThis); ctxTree = impInlineFetchArg(impInlineInfo->inlArgInfo[0], impInlineInfo->lclVarInfo[0]); - // context is the method table pointer of the this object - ctxTree = gtNewMethodTableLookup(ctxTree); + if (ctxTree->OperIs(GT_LCL_VAR)) + { + ctxTree->gtFlags |= GTF_VAR_CONTEXT; + } } else { assert(info.compThisArg != BAD_VAR_NUM); ctxTree = gtNewLclvNode(info.compThisArg, TYP_REF); ctxTree->gtFlags |= GTF_VAR_CONTEXT; - - // context is the method table pointer of the this object - ctxTree = gtNewMethodTableLookup(ctxTree); } + + // context is the method table pointer of the this object + ctxTree = gtNewMethodTableLookup(ctxTree); } else { diff --git a/src/coreclr/jit/jiteh.cpp b/src/coreclr/jit/jiteh.cpp index a607ee9f672d3e..2893d8283c0968 100644 --- a/src/coreclr/jit/jiteh.cpp +++ b/src/coreclr/jit/jiteh.cpp @@ -2371,11 +2371,6 @@ bool Compiler::fgCreateFiltersForGenericExceptions() } else { - // NOTE: It is a bit more complicated than this if this EH filter belongs to an inlinee as - // at this point inlining is already done, and we can't rely on the tricks we do in the - // importer for inlined runtime lookups. However, we currently never inline methods with EH, - // so we don't need to worry about this (yet). - // runtimeLookup = getTokenHandleTree(&resolvedToken, true); } GenTree* isInstOfT = gtNewHelperCallNode(CORINFO_HELP_ISINSTANCEOF_EXCEPTION, TYP_INT, runtimeLookup, arg); diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 2122b0619a76b1..9521b40d68444e 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -7000,9 +7000,6 @@ GenTree* Compiler::getVirtMethodPointerTree(GenTree* thisPtr, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_CALL_INFO* pCallInfo) { - // NOTE: Runtime lookups are tricky for inlinees and at this point we're already done with inlining. - // The good news is that we currently never inline methods with explicit tail calls. - // GenTree* exactTypeDesc = getTokenHandleTree(pResolvedToken, true); GenTree* exactMethodDesc = getTokenHandleTree(pResolvedToken, false); @@ -7010,7 +7007,8 @@ GenTree* Compiler::getVirtMethodPointerTree(GenTree* thisPtr, } //------------------------------------------------------------------------ -// getTokenHandleTree: get a handle tree for a token +// getTokenHandleTree: get a handle tree for a token. This method should never +// be called for tokens imported from inlinees. // // Arguments: // pResolvedToken - token to get a handle for @@ -7025,6 +7023,10 @@ GenTree* Compiler::getTokenHandleTree(CORINFO_RESOLVED_TOKEN* pResolvedToken, bo // NOTE: inlining is done at this point, so we don't know which method contained this token. // It's fine because currently this is never used for something that belongs to an inlinee. + // Namely, we currently use it for: + // 1) Methods with EH are never inlined + // 2) Methods with explicit tail calls are never inlined + // info.compCompHnd->embedGenericHandle(pResolvedToken, parent, info.compMethodHnd, &embedInfo); GenTree* result = getLookupTree(pResolvedToken, &embedInfo.lookup, gtTokenToIconFlags(pResolvedToken->token), From b94506dde715742d4902a9b872dcf816b02133e9 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 9 Mar 2024 15:00:33 +0100 Subject: [PATCH 15/40] Cleanup getRuntimeContextTree --- src/coreclr/jit/importer.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 9c3d10dbc556a6..3d6c368633b8ac 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1564,10 +1564,7 @@ GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind) ctxTree = impInlineFetchArg(*impInlineInfo->inlInstParamArgInfo, lclInfo); assert(ctxTree != nullptr); assert(ctxTree->TypeIs(TYP_I_IMPL)); - if (ctxTree->OperIs(GT_LCL_VAR)) - { - ctxTree->gtFlags |= GTF_VAR_CONTEXT; - } + // We don't need to worry about GTF_VAR_CONTEXT here, it should be set on the callsite anyway. } else if (kind == CORINFO_LOOKUP_THISOBJ) { @@ -1579,10 +1576,10 @@ GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind) assert(impInlineInfo->inlArgInfo[0].argIsThis); ctxTree = impInlineFetchArg(impInlineInfo->inlArgInfo[0], impInlineInfo->lclVarInfo[0]); - if (ctxTree->OperIs(GT_LCL_VAR)) - { - ctxTree->gtFlags |= GTF_VAR_CONTEXT; - } + + // "this" is expected to be always a local, and we must mark it as a context + assert(ctxTree->OperIs(GT_LCL_VAR)); + ctxTree->gtFlags |= GTF_VAR_CONTEXT; } else { From cfe264ed27c3c0bf6de1c1cddcb1b1157d4aef95 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 9 Mar 2024 16:46:37 +0100 Subject: [PATCH 16/40] Enable for R2R as well --- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 25 ++++++++----------- .../JitInterface/CorInfoImpl.RyuJit.cs | 12 ++------- src/coreclr/vm/jitinterface.cpp | 13 ++-------- 3 files changed, 14 insertions(+), 36 deletions(-) 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 cc1afb37fe5831..5c3b194854adb4 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -2185,7 +2185,7 @@ private void ceeInfoGetCallInfo( useInstantiatingStub = true; } - ComputeRuntimeLookupForSharedGenericToken(entryKind, ref pResolvedToken, pConstrainedResolvedToken, originalMethod, ref pResult->codePointerOrStubLookup); + ComputeRuntimeLookupForSharedGenericToken(entryKind, ref pResolvedToken, pConstrainedResolvedToken, originalMethod, HandleToObject(callerHandle), ref pResult->codePointerOrStubLookup); } } else @@ -2275,7 +2275,7 @@ private void ceeInfoGetCallInfo( if (pResult->exactContextNeedsRuntimeLookup) { - ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind.DispatchStubAddrSlot, ref pResolvedToken, null, originalMethod, ref pResult->codePointerOrStubLookup); + ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind.DispatchStubAddrSlot, ref pResolvedToken, null, originalMethod, HandleToObject(callerHandle), ref pResult->codePointerOrStubLookup); } else { @@ -2558,6 +2558,7 @@ private void ComputeRuntimeLookupForSharedGenericToken( ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, MethodDesc templateMethod, + MethodDesc containingFtn, ref CORINFO_LOOKUP pResultLookup) { pResultLookup.lookupKind.needsRuntimeLookup = true; @@ -2573,18 +2574,12 @@ private void ComputeRuntimeLookupForSharedGenericToken( pResult.indirections = CORINFO.USEHELPER; pResult.sizeOffset = CORINFO.CORINFO_NO_SIZE_CHECK; - // Runtime lookups in inlined contexts are not supported by the runtime for now - if (pResolvedToken.tokenContext != contextFromMethodBeingCompiled()) - { - pResultLookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_NOT_SUPPORTED; - return; - } - - MethodDesc contextMethod = methodFromContext(pResolvedToken.tokenContext); - TypeDesc contextType = typeFromContext(pResolvedToken.tokenContext); + bool inlinedLookup = pResolvedToken.tokenContext != contextFromMethodBeingCompiled(); + MethodDesc contextMethod = inlinedLookup ? containingFtn : methodFromContext(pResolvedToken.tokenContext); + Debug.Assert(contextMethod != null); // There is a pathological case where invalid IL refereces __Canon type directly, but there is no dictionary availabled to store the lookup. - if (!contextMethod.IsSharedByGenericInstantiations) + if (!inlinedLookup && !contextMethod.IsSharedByGenericInstantiations) { ThrowHelper.ThrowInvalidProgramException(); } @@ -2643,7 +2638,7 @@ private void ComputeRuntimeLookupForSharedGenericToken( // different way that is more version resilient... plus we can't have pointers to existing MTs/MDs in the sigs) } - private void ceeInfoEmbedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fEmbedParent, ref CORINFO_GENERICHANDLE_RESULT pResult) + private void ceeInfoEmbedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fEmbedParent, CORINFO_METHOD_STRUCT_* containingFtn, ref CORINFO_GENERICHANDLE_RESULT pResult) { #if DEBUG // In debug, write some bogus data to the struct to ensure we have filled everything @@ -2727,7 +2722,7 @@ private void ceeInfoEmbedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken throw new NotImplementedException(pResult.handleType.ToString()); } - ComputeRuntimeLookupForSharedGenericToken(entryKind, ref pResolvedToken, pConstrainedResolvedToken: null, templateMethod, ref pResult.lookup); + ComputeRuntimeLookupForSharedGenericToken(entryKind, ref pResolvedToken, pConstrainedResolvedToken: null, templateMethod, HandleToObject(containingFtn), ref pResult.lookup); } else { @@ -2754,7 +2749,7 @@ private void ceeInfoEmbedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fEmbedParent, CORINFO_METHOD_STRUCT_* containingFtn, ref CORINFO_GENERICHANDLE_RESULT pResult) { - ceeInfoEmbedGenericHandle(ref pResolvedToken, fEmbedParent, ref pResult); + ceeInfoEmbedGenericHandle(ref pResolvedToken, fEmbedParent, containingFtn, ref pResult); Debug.Assert(pResult.compileTimeHandle != null); 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 8a0534e17ae046..5102fa95df2d93 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -246,17 +246,9 @@ private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object ent lookup.lookupKind.needsRuntimeLookup = true; lookup.runtimeLookup.signature = null; - MethodDesc contextMethod; bool inlinedLookup = pResolvedToken.tokenContext != contextFromMethodBeingCompiled(); - if (inlinedLookup) - { - Debug.Assert(containingFtn != null); - contextMethod = containingFtn; - } - else - { - contextMethod = methodFromContext(pResolvedToken.tokenContext); - } + MethodDesc contextMethod = inlinedLookup ? containingFtn : methodFromContext(pResolvedToken.tokenContext); + Debug.Assert(contextMethod != null); GenericDictionaryLookup genericLookup = _compilation.ComputeGenericLookup(contextMethod, helperId, entity); diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index c5f2e53702164e..b4064db0fad3d9 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -3089,18 +3089,9 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr // Unless we decide otherwise, just do the lookup via a helper function pResult->indirections = CORINFO_USEHELPER; - MethodDesc* pContextMD; - bool inlinedLookup = pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT(); - if (inlinedLookup) - { - _ASSERT(pContainingMD != nullptr); - pContextMD = pContainingMD; - } - else - { - pContextMD = GetMethodFromContext(pResolvedToken->tokenContext); - } + MethodDesc* pContextMD = inlinedLookup ? pContainingMD : GetMethodFromContext(pResolvedToken->tokenContext); + _ASSERT(pContextMD != nullptr); MethodTable* pContextMT = pContextMD->GetMethodTable(); From 366ad39b5f30b09bac6f50e00b4e5112365b9ae6 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 9 Mar 2024 19:03:37 +0100 Subject: [PATCH 17/40] Address feedback --- src/coreclr/inc/corinfo.h | 4 ++-- src/coreclr/inc/icorjitinfoimpl_generated.h | 4 ++-- src/coreclr/inc/jiteeversionguid.h | 10 ++++----- .../jit/ICorJitInfo_wrapper_generated.hpp | 8 +++---- .../JitInterface/CorInfoImpl_generated.cs | 8 +++---- .../ThunkGenerator/ThunkInput.txt | 4 ++-- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 20 ++++++++--------- .../JitInterface/CorInfoImpl.RyuJit.cs | 22 +++++++++---------- .../aot/jitinterface/jitinterface_generated.h | 12 +++++----- .../tools/superpmi/superpmi-shared/agnostic.h | 4 ++-- .../superpmi-shared/methodcontext.cpp | 14 ++++++------ .../superpmi/superpmi-shared/methodcontext.h | 8 +++---- .../superpmi-shim-collector/icorjitinfo.cpp | 12 +++++----- .../icorjitinfo_generated.cpp | 8 +++---- .../icorjitinfo_generated.cpp | 8 +++---- .../tools/superpmi/superpmi/icorjitinfo.cpp | 8 +++---- src/coreclr/vm/jitinterface.cpp | 15 ++++++------- 17 files changed, 83 insertions(+), 86 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 94227043572cd4..f8fd80a17fca7b 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2221,7 +2221,7 @@ class ICorStaticInfo // should be looked up at runtime. virtual void expandRawHandleIntrinsic( CORINFO_RESOLVED_TOKEN * pResolvedToken, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT * pResult) = 0; // Is the given type in System.Private.Corelib and marked with IntrinsicAttribute? @@ -3181,7 +3181,7 @@ class ICorDynamicInfo : public ICorStaticInfo virtual void embedGenericHandle( CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fEmbedParent, // `true` - embeds parent type handle of the field/method handle - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT * pResult ) = 0; diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index 6c7f83e1e5acd8..c8f2bb41e98fd3 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -104,7 +104,7 @@ CORINFO_CLASS_HANDLE getDefaultEqualityComparerClass( void expandRawHandleIntrinsic( CORINFO_RESOLVED_TOKEN* pResolvedToken, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) override; bool isIntrinsicType( @@ -557,7 +557,7 @@ CORINFO_FIELD_HANDLE embedFieldHandle( void embedGenericHandle( CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) override; void getLocationOfThisType( diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index b658a091d38da6..e77ad34badef11 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 = { /* 19aca9ab-66c1-47bd-bc45-db47a3ed02b6 */ - 0x19aca9ab, - 0x66c1, - 0x47bd, - {0xbc, 0x45, 0xdb, 0x47, 0xa3, 0xed, 0x02, 0xb6} +constexpr GUID JITEEVersionIdentifier = { /* 7b28330a-e945-491d-83f4-6ff1b040a6e2 */ + 0x7b28330a, + 0xe945, + 0x491d, + {0x83, 0xf4, 0x6f, 0xf1, 0xb0, 0x40, 0xa6, 0xe2} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index a20ee9aa3b74c6..f28f8a08301055 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -202,11 +202,11 @@ CORINFO_CLASS_HANDLE WrapICorJitInfo::getDefaultEqualityComparerClass( void WrapICorJitInfo::expandRawHandleIntrinsic( CORINFO_RESOLVED_TOKEN* pResolvedToken, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { API_ENTER(expandRawHandleIntrinsic); - wrapHnd->expandRawHandleIntrinsic(pResolvedToken, containingFtn, pResult); + wrapHnd->expandRawHandleIntrinsic(pResolvedToken, callerHandle, pResult); API_LEAVE(expandRawHandleIntrinsic); } @@ -1322,11 +1322,11 @@ CORINFO_FIELD_HANDLE WrapICorJitInfo::embedFieldHandle( void WrapICorJitInfo::embedGenericHandle( CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { API_ENTER(embedGenericHandle); - wrapHnd->embedGenericHandle(pResolvedToken, fEmbedParent, containingFtn, pResult); + wrapHnd->embedGenericHandle(pResolvedToken, fEmbedParent, callerHandle, pResult); API_LEAVE(embedGenericHandle); } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 74ebad63130816..8c488fa75c58a8 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -291,12 +291,12 @@ private static byte _resolveVirtualMethod(IntPtr thisHandle, IntPtr* ppException } [UnmanagedCallersOnly] - private static void _expandRawHandleIntrinsic(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_STRUCT_* containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) + private static void _expandRawHandleIntrinsic(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_STRUCT_* callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { var _this = GetThis(thisHandle); try { - _this.expandRawHandleIntrinsic(ref *pResolvedToken, containingFtn, ref *pResult); + _this.expandRawHandleIntrinsic(ref *pResolvedToken, callerHandle, ref *pResult); } catch (Exception ex) { @@ -1993,12 +1993,12 @@ private static CorInfoHelpFunc _getLazyStringLiteralHelper(IntPtr thisHandle, In } [UnmanagedCallersOnly] - private static void _embedGenericHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, byte fEmbedParent, CORINFO_METHOD_STRUCT_* containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) + private static void _embedGenericHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, byte fEmbedParent, CORINFO_METHOD_STRUCT_* callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { var _this = GetThis(thisHandle); try { - _this.embedGenericHandle(ref *pResolvedToken, fEmbedParent != 0, containingFtn, ref *pResult); + _this.embedGenericHandle(ref *pResolvedToken, fEmbedParent != 0, callerHandle, ref *pResult); } catch (Exception ex) { diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 7e31170301071f..9d99113f68fbd5 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -181,7 +181,7 @@ FUNCTIONS CORINFO_METHOD_HANDLE getUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg); CORINFO_CLASS_HANDLE getDefaultComparerClass(CORINFO_CLASS_HANDLE elemType); CORINFO_CLASS_HANDLE getDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE elemType); - void expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT * pResult); + void expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT * pResult); bool isIntrinsicType( CORINFO_CLASS_HANDLE classHnd ); CorInfoCallConvExtension getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition); bool pInvokeMarshalingRequired( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig ); @@ -296,7 +296,7 @@ FUNCTIONS CORINFO_CLASS_HANDLE embedClassHandle(CORINFO_CLASS_HANDLE handle, void **ppIndirection); CORINFO_METHOD_HANDLE embedMethodHandle(CORINFO_METHOD_HANDLE handle, void **ppIndirection); CORINFO_FIELD_HANDLE embedFieldHandle(CORINFO_FIELD_HANDLE handle, void **ppIndirection); - void embedGenericHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fEmbedParent, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT * pResult); + void embedGenericHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fEmbedParent, CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT * pResult); void getLocationOfThisType(CORINFO_METHOD_HANDLE context, CORINFO_LOOKUP_KIND* pLookupKind); void getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP *pLookup); void* GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void ** ppIndirection); 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 7297aaaa2a21d1..39e5fa26d7a8ea 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -2558,9 +2558,11 @@ private void ComputeRuntimeLookupForSharedGenericToken( ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, MethodDesc templateMethod, - MethodDesc containingFtn, + MethodDesc callerHandle, ref CORINFO_LOOKUP pResultLookup) { + Debug.Assert(callerHandle != null); + pResultLookup.lookupKind.needsRuntimeLookup = true; pResultLookup.lookupKind.runtimeLookupFlags = 0; @@ -2574,12 +2576,10 @@ private void ComputeRuntimeLookupForSharedGenericToken( pResult.indirections = CORINFO.USEHELPER; pResult.sizeOffset = CORINFO.CORINFO_NO_SIZE_CHECK; - bool inlinedLookup = pResolvedToken.tokenContext != contextFromMethodBeingCompiled(); - MethodDesc contextMethod = inlinedLookup ? containingFtn : methodFromContext(pResolvedToken.tokenContext); - Debug.Assert(contextMethod != null); + MethodDesc contextMethod = callerHandle; // There is a pathological case where invalid IL refereces __Canon type directly, but there is no dictionary availabled to store the lookup. - if (!inlinedLookup && !contextMethod.IsSharedByGenericInstantiations) + if (!contextMethod.IsSharedByGenericInstantiations) { ThrowHelper.ThrowInvalidProgramException(); } @@ -2638,7 +2638,7 @@ private void ComputeRuntimeLookupForSharedGenericToken( // different way that is more version resilient... plus we can't have pointers to existing MTs/MDs in the sigs) } - private void ceeInfoEmbedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fEmbedParent, CORINFO_METHOD_STRUCT_* containingFtn, ref CORINFO_GENERICHANDLE_RESULT pResult) + private void ceeInfoEmbedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fEmbedParent, CORINFO_METHOD_STRUCT_* callerHandle, ref CORINFO_GENERICHANDLE_RESULT pResult) { #if DEBUG // In debug, write some bogus data to the struct to ensure we have filled everything @@ -2722,7 +2722,7 @@ private void ceeInfoEmbedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken throw new NotImplementedException(pResult.handleType.ToString()); } - ComputeRuntimeLookupForSharedGenericToken(entryKind, ref pResolvedToken, pConstrainedResolvedToken: null, templateMethod, HandleToObject(containingFtn), ref pResult.lookup); + ComputeRuntimeLookupForSharedGenericToken(entryKind, ref pResolvedToken, pConstrainedResolvedToken: null, templateMethod, HandleToObject(callerHandle), ref pResult.lookup); } else { @@ -2747,9 +2747,9 @@ private void ceeInfoEmbedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken return null; } - private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fEmbedParent, CORINFO_METHOD_STRUCT_* containingFtn, ref CORINFO_GENERICHANDLE_RESULT pResult) + private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fEmbedParent, CORINFO_METHOD_STRUCT_* callerHandle, ref CORINFO_GENERICHANDLE_RESULT pResult) { - ceeInfoEmbedGenericHandle(ref pResolvedToken, fEmbedParent, containingFtn, ref pResult); + ceeInfoEmbedGenericHandle(ref pResolvedToken, fEmbedParent, callerHandle, ref pResult); Debug.Assert(pResult.compileTimeHandle != null); @@ -2952,7 +2952,7 @@ private void getGSCookie(IntPtr* pCookieVal, IntPtr** ppCookieVal) private void getMethodVTableOffset(CORINFO_METHOD_STRUCT_* method, ref uint offsetOfIndirection, ref uint offsetAfterIndirection, ref bool isRelative) { throw new NotImplementedException("getMethodVTableOffset"); } - private void expandRawHandleIntrinsic(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_METHOD_STRUCT_* containingFtn, ref CORINFO_GENERICHANDLE_RESULT pResult) + private void expandRawHandleIntrinsic(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_METHOD_STRUCT_* callerHandle, ref CORINFO_GENERICHANDLE_RESULT pResult) { throw new NotImplementedException("expandRawHandleIntrinsic"); } private void* getMethodSync(CORINFO_METHOD_STRUCT_* ftn, ref void* ppIndirection) 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 b5b7349da04ee2..a4f9b30dabc959 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -239,18 +239,16 @@ private static CORINFO_RUNTIME_LOOKUP_KIND GetLookupKindFromContextSource(Generi } } - private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object entity, ReadyToRunHelperId helperId, MethodDesc containingFtn, ref CORINFO_LOOKUP lookup) + private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object entity, ReadyToRunHelperId helperId, MethodDesc callerHandle, ref CORINFO_LOOKUP lookup) { + Debug.Assert(callerHandle != null); + if (_compilation.NeedsRuntimeLookup(helperId, entity)) { lookup.lookupKind.needsRuntimeLookup = true; lookup.runtimeLookup.signature = null; - bool inlinedLookup = pResolvedToken.tokenContext != contextFromMethodBeingCompiled(); - MethodDesc contextMethod = inlinedLookup ? containingFtn : methodFromContext(pResolvedToken.tokenContext); - Debug.Assert(contextMethod != null); - - GenericDictionaryLookup genericLookup = _compilation.ComputeGenericLookup(contextMethod, helperId, entity); + GenericDictionaryLookup genericLookup = _compilation.ComputeGenericLookup(callerHandle, helperId, entity); if (genericLookup.UseHelper) { @@ -1719,7 +1717,7 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO } } - private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fEmbedParent, CORINFO_METHOD_STRUCT_* containingFtn, ref CORINFO_GENERICHANDLE_RESULT pResult) + private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fEmbedParent, CORINFO_METHOD_STRUCT_* callerHandle, ref CORINFO_GENERICHANDLE_RESULT pResult) { #if DEBUG // In debug, write some bogus data to the struct to ensure we have filled everything @@ -1810,7 +1808,7 @@ private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool Debug.Assert(pResult.compileTimeHandle != null); - ComputeLookup(ref pResolvedToken, target, helperId, HandleToObject(containingFtn), ref pResult.lookup); + ComputeLookup(ref pResolvedToken, target, helperId, HandleToObject(callerHandle), ref pResult.lookup); } private CORINFO_METHOD_STRUCT_* embedMethodHandle(CORINFO_METHOD_STRUCT_* handle, ref void* ppIndirection) @@ -1855,7 +1853,7 @@ private void getMethodVTableOffset(CORINFO_METHOD_STRUCT_* method, ref uint offs offsetAfterIndirection = (uint)(EETypeNode.GetVTableOffset(pointerSize) + slot * pointerSize); } - private void expandRawHandleIntrinsic(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_METHOD_STRUCT_* containingFtn, ref CORINFO_GENERICHANDLE_RESULT pResult) + private void expandRawHandleIntrinsic(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_METHOD_STRUCT_* callerHandle, ref CORINFO_GENERICHANDLE_RESULT pResult) { // Resolved token as a potentially RuntimeDetermined object. MethodDesc method = (MethodDesc)GetRuntimeDeterminedObjectForToken(ref pResolvedToken); @@ -1865,15 +1863,15 @@ private void expandRawHandleIntrinsic(ref CORINFO_RESOLVED_TOKEN pResolvedToken, switch (method.Name) { case "Of": - ComputeLookup(ref pResolvedToken, method.Instantiation[0], ReadyToRunHelperId.TypeHandle, HandleToObject(containingFtn), ref pResult.lookup); + ComputeLookup(ref pResolvedToken, method.Instantiation[0], ReadyToRunHelperId.TypeHandle, HandleToObject(callerHandle), ref pResult.lookup); pResult.handleType = CorInfoGenericHandleType.CORINFO_HANDLETYPE_CLASS; break; case "DefaultConstructorOf": - ComputeLookup(ref pResolvedToken, method.Instantiation[0], ReadyToRunHelperId.DefaultConstructor, HandleToObject(containingFtn), ref pResult.lookup); + ComputeLookup(ref pResolvedToken, method.Instantiation[0], ReadyToRunHelperId.DefaultConstructor, HandleToObject(callerHandle), ref pResult.lookup); pResult.handleType = CorInfoGenericHandleType.CORINFO_HANDLETYPE_METHOD; break; case "AllocatorOf": - ComputeLookup(ref pResolvedToken, method.Instantiation[0], ReadyToRunHelperId.ObjectAllocator, HandleToObject(containingFtn), ref pResult.lookup); + ComputeLookup(ref pResolvedToken, method.Instantiation[0], ReadyToRunHelperId.ObjectAllocator, HandleToObject(callerHandle), ref pResult.lookup); pResult.handleType = CorInfoGenericHandleType.CORINFO_HANDLETYPE_UNKNOWN; break; default: diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index 6e77e7dba1ffb3..8a3a3a7d2dec82 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -30,7 +30,7 @@ struct JitInterfaceCallbacks CORINFO_METHOD_HANDLE (* getUnboxedEntry)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg); CORINFO_CLASS_HANDLE (* getDefaultComparerClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE elemType); CORINFO_CLASS_HANDLE (* getDefaultEqualityComparerClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE elemType); - void (* expandRawHandleIntrinsic)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult); + void (* expandRawHandleIntrinsic)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult); bool (* isIntrinsicType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE classHnd); CorInfoCallConvExtension (* getUnmanagedCallConv)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition); bool (* pInvokeMarshalingRequired)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); @@ -145,7 +145,7 @@ struct JitInterfaceCallbacks CORINFO_CLASS_HANDLE (* embedClassHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE handle, void** ppIndirection); CORINFO_METHOD_HANDLE (* embedMethodHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE handle, void** ppIndirection); CORINFO_FIELD_HANDLE (* embedFieldHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE handle, void** ppIndirection); - void (* embedGenericHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult); + void (* embedGenericHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult); void (* getLocationOfThisType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE context, CORINFO_LOOKUP_KIND* pLookupKind); void (* getAddressOfPInvokeTarget)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP* pLookup); void* (* GetCookieForPInvokeCalliSig)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* szMetaSig, void** ppIndirection); @@ -389,11 +389,11 @@ class JitInterfaceWrapper : public ICorJitInfo virtual void expandRawHandleIntrinsic( CORINFO_RESOLVED_TOKEN* pResolvedToken, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { CorInfoExceptionClass* pException = nullptr; - _callbacks->expandRawHandleIntrinsic(_thisHandle, &pException, pResolvedToken, containingFtn, pResult); + _callbacks->expandRawHandleIntrinsic(_thisHandle, &pException, pResolvedToken, callerHandle, pResult); if (pException != nullptr) throw pException; } @@ -1497,11 +1497,11 @@ class JitInterfaceWrapper : public ICorJitInfo virtual void embedGenericHandle( CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { CorInfoExceptionClass* pException = nullptr; - _callbacks->embedGenericHandle(_thisHandle, &pException, pResolvedToken, fEmbedParent, containingFtn, pResult); + _callbacks->embedGenericHandle(_thisHandle, &pException, pResolvedToken, fEmbedParent, callerHandle, pResult); if (pException != nullptr) throw pException; } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h index 56a296dd85c690..2c3100d24ebdd6 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h @@ -423,14 +423,14 @@ struct Agnostic_CheckMethodModifier struct Agnostic_EmbedGenericHandle { Agnostic_CORINFO_RESOLVED_TOKEN ResolvedToken; - DWORDLONG hContainingFtn; + DWORDLONG hCallerHandle; DWORD fEmbedParent; }; struct Agnostic_ExpandRawHandleIntrinsic { Agnostic_CORINFO_RESOLVED_TOKEN ResolvedToken; - DWORDLONG hContainingFtn; + DWORDLONG hCallerHandle; }; struct Agnostic_CORINFO_GENERICHANDLE_RESULT diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 249dc459b4b434..0dcfd0faca7b30 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -1670,7 +1670,7 @@ void MethodContext::repGetCallInfoFromMethodHandle(CORINFO_METHOD_HANDLE methodH LogException(EXCEPTIONCODE_MC, "Didn't find key %016" PRIX64 ".", methodHandle); } -void MethodContext::recExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) +void MethodContext::recExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { if (ExpandRawHandleIntrinsic == nullptr) ExpandRawHandleIntrinsic = new LightWeightMap; @@ -1678,7 +1678,7 @@ void MethodContext::recExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolve Agnostic_ExpandRawHandleIntrinsic key; ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding key.ResolvedToken = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, ExpandRawHandleIntrinsic); - key.hContainingFtn = CastHandle(containingFtn); + key.hCallerHandle = CastHandle(callerHandle); Agnostic_CORINFO_GENERICHANDLE_RESULT value; value.lookup = SpmiRecordsHelper::StoreAgnostic_CORINFO_LOOKUP(&pResult->lookup); @@ -1696,13 +1696,13 @@ void MethodContext::dmpExpandRawHandleIntrinsic(const Agnostic_ExpandRawHandleIn result.compileTimeHandle, result.handleType); } -void MethodContext::repExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) +void MethodContext::repExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { Agnostic_ExpandRawHandleIntrinsic key; ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding key.ResolvedToken = SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, ExpandRawHandleIntrinsic); - key.hContainingFtn = CastHandle(containingFtn); + key.hCallerHandle = CastHandle(callerHandle); Agnostic_CORINFO_GENERICHANDLE_RESULT value = LookupByKeyOrMiss(ExpandRawHandleIntrinsic, key, ": key %x", pResolvedToken->token); @@ -3104,7 +3104,7 @@ CorInfoHelpFunc MethodContext::repGetNewHelper(CORINFO_CLASS_HANDLE classHandle void MethodContext::recEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { if (EmbedGenericHandle == nullptr) @@ -3114,7 +3114,7 @@ void MethodContext::recEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolve ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding key.ResolvedToken = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, EmbedGenericHandle); key.fEmbedParent = (DWORD)fEmbedParent; - key.hContainingFtn = CastHandle(containingFtn); + key.hCallerHandle = CastHandle(callerHandle); Agnostic_CORINFO_GENERICHANDLE_RESULT value; value.lookup = SpmiRecordsHelper::StoreAgnostic_CORINFO_LOOKUP(&pResult->lookup); @@ -3136,7 +3136,7 @@ void MethodContext::dmpEmbedGenericHandle(const Agnostic_EmbedGenericHandle& } void MethodContext::repEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { AssertMapExistsNoMessage(EmbedGenericHandle); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index ff1420c8200879..058257c3ed3a32 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -272,9 +272,9 @@ class MethodContext void dmpIsSDArray(DWORDLONG key, DWORD value); bool repIsSDArray(CORINFO_CLASS_HANDLE cls); - void recExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult); + void recExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult); void dmpExpandRawHandleIntrinsic(const Agnostic_ExpandRawHandleIntrinsic& key, const Agnostic_CORINFO_GENERICHANDLE_RESULT& result); - void repExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult); + void repExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult); void recIsIntrinsicType(CORINFO_CLASS_HANDLE cls, bool result); void dmpIsIntrinsicType(DWORDLONG key, DWORD value); @@ -423,13 +423,13 @@ class MethodContext void recEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult); void dmpEmbedGenericHandle(const Agnostic_EmbedGenericHandle& key, const Agnostic_CORINFO_GENERICHANDLE_RESULT& value); void repEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult); void recGetEHinfo(CORINFO_METHOD_HANDLE ftn, unsigned EHnumber, CORINFO_EH_CLAUSE* clause); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index bff44379f899b5..7b9265f37cef9c 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -259,12 +259,12 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::getDefaultEqualityComparerClass(CORINFO_C } void interceptor_ICJI::expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { mc->cr->AddCall("expandRawHandleIntrinsic"); - original_ICorJitInfo->expandRawHandleIntrinsic(pResolvedToken, containingFtn, pResult); - mc->recExpandRawHandleIntrinsic(pResolvedToken, containingFtn, pResult); + original_ICorJitInfo->expandRawHandleIntrinsic(pResolvedToken, callerHandle, pResult); + mc->recExpandRawHandleIntrinsic(pResolvedToken, callerHandle, pResult); } // Is the given type in System.Private.Corelib and marked with IntrinsicAttribute? @@ -1524,12 +1524,12 @@ CORINFO_FIELD_HANDLE interceptor_ICJI::embedFieldHandle(CORINFO_FIELD_HANDLE han void interceptor_ICJI::embedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, // TRUE - embeds parent type handle of the field/method // handle - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { mc->cr->AddCall("embedGenericHandle"); - original_ICorJitInfo->embedGenericHandle(pResolvedToken, fEmbedParent, containingFtn, pResult); - mc->recEmbedGenericHandle(pResolvedToken, fEmbedParent, containingFtn, pResult); + original_ICorJitInfo->embedGenericHandle(pResolvedToken, fEmbedParent, callerHandle, pResult); + mc->recEmbedGenericHandle(pResolvedToken, fEmbedParent, callerHandle, pResult); } // Return information used to locate the exact enclosing type of the current method. 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 89d361f845e77a..9b2c6585672191 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -171,11 +171,11 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::getDefaultEqualityComparerClass( void interceptor_ICJI::expandRawHandleIntrinsic( CORINFO_RESOLVED_TOKEN* pResolvedToken, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { mcs->AddCall("expandRawHandleIntrinsic"); - original_ICorJitInfo->expandRawHandleIntrinsic(pResolvedToken, containingFtn, pResult); + original_ICorJitInfo->expandRawHandleIntrinsic(pResolvedToken, callerHandle, pResult); } bool interceptor_ICJI::isIntrinsicType( @@ -1084,11 +1084,11 @@ CORINFO_FIELD_HANDLE interceptor_ICJI::embedFieldHandle( void interceptor_ICJI::embedGenericHandle( CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { mcs->AddCall("embedGenericHandle"); - original_ICorJitInfo->embedGenericHandle(pResolvedToken, fEmbedParent, containingFtn, pResult); + original_ICorJitInfo->embedGenericHandle(pResolvedToken, fEmbedParent, callerHandle, pResult); } void interceptor_ICJI::getLocationOfThisType( 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 52f1b2e7ddcdd7..8b731e0a2773d6 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -152,10 +152,10 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::getDefaultEqualityComparerClass( void interceptor_ICJI::expandRawHandleIntrinsic( CORINFO_RESOLVED_TOKEN* pResolvedToken, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { - original_ICorJitInfo->expandRawHandleIntrinsic(pResolvedToken, containingFtn, pResult); + original_ICorJitInfo->expandRawHandleIntrinsic(pResolvedToken, callerHandle, pResult); } bool interceptor_ICJI::isIntrinsicType( @@ -950,10 +950,10 @@ CORINFO_FIELD_HANDLE interceptor_ICJI::embedFieldHandle( void interceptor_ICJI::embedGenericHandle( CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { - original_ICorJitInfo->embedGenericHandle(pResolvedToken, fEmbedParent, containingFtn, pResult); + original_ICorJitInfo->embedGenericHandle(pResolvedToken, fEmbedParent, callerHandle, pResult); } void interceptor_ICJI::getLocationOfThisType( diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 166a361a741258..804a74fd67ddc7 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -221,10 +221,10 @@ CORINFO_CLASS_HANDLE MyICJI::getDefaultEqualityComparerClass(CORINFO_CLASS_HANDL return result; } -void MyICJI::expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE containingFtn, CORINFO_GENERICHANDLE_RESULT* pResult) +void MyICJI::expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { jitInstance->mc->cr->AddCall("expandRawHandleIntrinsic"); - jitInstance->mc->repExpandRawHandleIntrinsic(pResolvedToken, containingFtn, pResult); + jitInstance->mc->repExpandRawHandleIntrinsic(pResolvedToken, callerHandle, pResult); } // Is the given type in System.Private.Corelib and marked with IntrinsicAttribute? @@ -1332,11 +1332,11 @@ CORINFO_FIELD_HANDLE MyICJI::embedFieldHandle(CORINFO_FIELD_HANDLE handle, void* // void MyICJI::embedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fEmbedParent, // TRUE - embeds parent type handle of the field/method handle - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT* pResult) { jitInstance->mc->cr->AddCall("embedGenericHandle"); - jitInstance->mc->repEmbedGenericHandle(pResolvedToken, fEmbedParent, containingFtn, pResult); + jitInstance->mc->repEmbedGenericHandle(pResolvedToken, fEmbedParent, callerHandle, pResult); } // Return information used to locate the exact enclosing type of the current method. diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index b4064db0fad3d9..440ba1a6a470d1 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -2792,7 +2792,7 @@ void CEEInfo::MethodCompileComplete(CORINFO_METHOD_HANDLE methHnd) void CEEInfo::embedGenericHandle( CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fEmbedParent, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT *pResult) { CONTRACTL { @@ -2895,7 +2895,7 @@ void CEEInfo::embedGenericHandle( pResolvedToken, NULL, pTemplateMD, - (MethodDesc*)containingFtn, + (MethodDesc*)callerHandle, &pResult->lookup); } else @@ -3074,6 +3074,8 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr PRECONDITION(CheckPointer(pResultLookup)); } CONTRACTL_END; + _ASSERT(pContainingMD != nullptr); + pResultLookup->lookupKind.needsRuntimeLookup = true; pResultLookup->lookupKind.runtimeLookupFlags = 0; @@ -3089,14 +3091,11 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr // Unless we decide otherwise, just do the lookup via a helper function pResult->indirections = CORINFO_USEHELPER; - bool inlinedLookup = pResolvedToken->tokenContext != METHOD_BEING_COMPILED_CONTEXT(); - MethodDesc* pContextMD = inlinedLookup ? pContainingMD : GetMethodFromContext(pResolvedToken->tokenContext); - _ASSERT(pContextMD != nullptr); - + MethodDesc* pContextMD = pContainingMD; MethodTable* pContextMT = pContextMD->GetMethodTable(); // There is a pathological case where invalid IL refereces __Canon type directly, but there is no dictionary availabled to store the lookup. - if (!inlinedLookup && !pContextMD->IsSharedByGenericInstantiations()) + if (!pContextMD->IsSharedByGenericInstantiations()) COMPlusThrow(kInvalidProgramException); BOOL fInstrument = FALSE; @@ -8933,7 +8932,7 @@ CORINFO_METHOD_HANDLE CEEInfo::getUnboxedEntry( /*********************************************************************/ void CEEInfo::expandRawHandleIntrinsic( CORINFO_RESOLVED_TOKEN * pResolvedToken, - CORINFO_METHOD_HANDLE containingFtn, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_GENERICHANDLE_RESULT * pResult) { LIMITED_METHOD_CONTRACT; From 183925a59479743931c4f21a4eecf8a7d33419f0 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 9 Mar 2024 19:08:33 +0100 Subject: [PATCH 18/40] clean up --- src/coreclr/vm/jitinterface.cpp | 6 +++--- src/coreclr/vm/jitinterface.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 440ba1a6a470d1..789f0bb4ee2af0 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -3066,7 +3066,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken, MethodDesc * pTemplateMD /* for method-based slots */, - MethodDesc * pContainingMD, + MethodDesc * pCallerMD, CORINFO_LOOKUP *pResultLookup) { CONTRACTL{ @@ -3074,7 +3074,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr PRECONDITION(CheckPointer(pResultLookup)); } CONTRACTL_END; - _ASSERT(pContainingMD != nullptr); + _ASSERT(pCallerMD != nullptr); pResultLookup->lookupKind.needsRuntimeLookup = true; pResultLookup->lookupKind.runtimeLookupFlags = 0; @@ -3091,7 +3091,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr // Unless we decide otherwise, just do the lookup via a helper function pResult->indirections = CORINFO_USEHELPER; - MethodDesc* pContextMD = pContainingMD; + MethodDesc* pContextMD = pCallerMD; MethodTable* pContextMT = pContextMD->GetMethodTable(); // There is a pathological case where invalid IL refereces __Canon type directly, but there is no dictionary availabled to store the lookup. diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 23489179dfaea4..9b307983a24d0c 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -558,7 +558,7 @@ class CEEInfo : public ICorJitInfo CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken /* for ConstrainedMethodEntrySlot */, MethodDesc * pTemplateMD /* for method-based slots */, - MethodDesc * pContainingMD, + MethodDesc * pCallerMD, CORINFO_LOOKUP *pResultLookup); #if defined(FEATURE_GDBJIT) From 9078bdb81ffddfa3502045e45fa8c5a9d04c2cc2 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 11 Mar 2024 01:25:46 +0100 Subject: [PATCH 19/40] fix jit assert --- src/coreclr/jit/importer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index b4c52580692dbe..72d36fd5b0fd75 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1551,9 +1551,9 @@ GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind) GenTree* ctxTree; // Collectible types requires that for shared generic code, if we use the generic context parameter - // that we report it. (This is a conservative approach, we could detect some cases particularly when the - // context parameter is this that we don't need the eager reporting logic.) - lvaGenericsContextInUse = true; + // that we report it. Conservatively mark the root method as using generic context, MARK_LOCAL_VARS phase + // will clean it up if it turns out to be unnecessary. + impInlineRoot()->lvaGenericsContextInUse = true; // Always use generic context from the callsite if we're inlining and it's available. if (compIsForInlining() && (impInlineInfo->inlInstParamArgInfo != nullptr)) From 550f8ffa20e20f89edae5b02d7481c5f603bad45 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 11 Mar 2024 03:12:01 +0100 Subject: [PATCH 20/40] repro --- .../JitInterface/CorInfoImpl.RyuJit.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) 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 a4f9b30dabc959..41d88b6dbc1247 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -248,6 +248,23 @@ private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object ent lookup.lookupKind.needsRuntimeLookup = true; lookup.runtimeLookup.signature = null; + // Are we inlining a method that requires a runtime lookup? + if (pResolvedToken.tokenContext != contextFromMethodBeingCompiled()) + { + // REPRO: if it's not the problematic method - give up. + if (MethodBeingCompiled.GetDisplayName() != "System.Buffers.SharedArrayPool`1<__Canon>.Rent(Int32)" || + pResolvedToken.tokenType != CorInfoTokenKind.CORINFO_TOKENKIND_Method) + { + lookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_NOT_SUPPORTED; + return; + } + + Console.WriteLine("Root method: " + MethodBeingCompiled); + Console.WriteLine("Inlinee with a runtime lookup: " + callerHandle); + Console.WriteLine("Context kind: " + (CorInfoContextFlags)((nuint)pResolvedToken.tokenContext & (nuint)CorInfoContextFlags.CORINFO_CONTEXTFLAGS_MASK)); + Console.WriteLine("Token type: " + pResolvedToken.tokenType); + Console.WriteLine("-----"); + } GenericDictionaryLookup genericLookup = _compilation.ComputeGenericLookup(callerHandle, helperId, entity); if (genericLookup.UseHelper) From 410ce12d0dd576623e71fb3563793645fa94adeb Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 11 Mar 2024 04:00:00 +0100 Subject: [PATCH 21/40] fix repro --- .../aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 41d88b6dbc1247..cc72e6e10888f2 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -252,8 +252,7 @@ private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object ent if (pResolvedToken.tokenContext != contextFromMethodBeingCompiled()) { // REPRO: if it's not the problematic method - give up. - if (MethodBeingCompiled.GetDisplayName() != "System.Buffers.SharedArrayPool`1<__Canon>.Rent(Int32)" || - pResolvedToken.tokenType != CorInfoTokenKind.CORINFO_TOKENKIND_Method) + if (MethodBeingCompiled.GetDisplayName() != "System.Buffers.SharedArrayPool`1<__Canon>.Rent(Int32)") { lookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_NOT_SUPPORTED; return; From 2e540ec81f4824294f3805550ba19ad7cf059312 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 11 Mar 2024 12:27:50 +0100 Subject: [PATCH 22/40] Add CallerHandle to getReadyToRunHelper --- src/coreclr/inc/corinfo.h | 1 + src/coreclr/inc/icorjitinfoimpl_generated.h | 1 + src/coreclr/inc/jiteeversionguid.h | 10 +++++----- src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp | 3 ++- src/coreclr/jit/compiler.h | 2 +- src/coreclr/jit/flowgraph.cpp | 2 +- src/coreclr/jit/gentree.cpp | 4 ++-- src/coreclr/jit/importer.cpp | 6 +++--- .../Common/JitInterface/CorInfoImpl_generated.cs | 6 +++--- .../JitInterface/ThunkGenerator/ThunkInput.txt | 2 +- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 2 +- .../JitInterface/CorInfoImpl.RyuJit.cs | 12 ++++++------ .../tools/aot/jitinterface/jitinterface_generated.h | 5 +++-- .../tools/superpmi/superpmi-shared/agnostic.h | 1 + .../tools/superpmi/superpmi-shared/methodcontext.cpp | 4 ++++ .../tools/superpmi/superpmi-shared/methodcontext.h | 2 ++ .../superpmi/superpmi-shim-collector/icorjitinfo.cpp | 5 +++-- .../superpmi-shim-counter/icorjitinfo_generated.cpp | 3 ++- .../superpmi-shim-simple/icorjitinfo_generated.cpp | 3 ++- src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp | 3 ++- src/coreclr/vm/jitinterface.cpp | 1 + 21 files changed, 47 insertions(+), 31 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index f8fd80a17fca7b..d3561e04cc061e 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2638,6 +2638,7 @@ class ICorStaticInfo CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_LOOKUP_KIND * pGenericLookupKind, CorInfoHelpFunc id, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP * pLookup ) = 0; diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index c8f2bb41e98fd3..1489c91c0935bd 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -298,6 +298,7 @@ bool getReadyToRunHelper( CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP* pLookup) override; void getReadyToRunDelegateCtorHelper( diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index e77ad34badef11..f9fed1212415d4 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 = { /* 7b28330a-e945-491d-83f4-6ff1b040a6e2 */ - 0x7b28330a, - 0xe945, - 0x491d, - {0x83, 0xf4, 0x6f, 0xf1, 0xb0, 0x40, 0xa6, 0xe2} +constexpr GUID JITEEVersionIdentifier = { /* 869120e3-3d61-42c3-bada-297da00f3044 */ + 0x869120e3, + 0x3d61, + 0x42c3, + {0xba, 0xda, 0x29, 0x7d, 0xa0, 0x0f, 0x30, 0x44} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index f28f8a08301055..57749ac645a0df 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -688,10 +688,11 @@ bool WrapICorJitInfo::getReadyToRunHelper( CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP* pLookup) { API_ENTER(getReadyToRunHelper); - bool temp = wrapHnd->getReadyToRunHelper(pResolvedToken, pGenericLookupKind, id, pLookup); + bool temp = wrapHnd->getReadyToRunHelper(pResolvedToken, pGenericLookupKind, id, callerHandle, pLookup); API_LEAVE(getReadyToRunHelper); return temp; } diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 8b1b85427f0ab4..ced464500a6a01 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -3440,7 +3440,7 @@ class Compiler GenTreeAllocObj* gtNewAllocObjNode( unsigned int helper, bool helperHasSideEffects, CORINFO_CLASS_HANDLE clsHnd, var_types type, GenTree* op1); - GenTreeAllocObj* gtNewAllocObjNode(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool useParent); + GenTreeAllocObj* gtNewAllocObjNode(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, bool useParent); GenTree* gtNewRuntimeLookup(CORINFO_GENERIC_HANDLE hnd, CorInfoGenericHandleType hndTyp, GenTree* lookupTree); diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp index 7e6d0b6dc5c2f4..d414b5e17d75f3 100644 --- a/src/coreclr/jit/flowgraph.cpp +++ b/src/coreclr/jit/flowgraph.cpp @@ -1048,7 +1048,7 @@ GenTree* Compiler::fgOptimizeDelegateConstructor(GenTreeCall* call, assert(oper != GT_FTN_ADDR); CORINFO_CONST_LOOKUP genericLookup; info.compCompHnd->getReadyToRunHelper(&ldftnToken->m_token, &pLookup.lookupKind, - CORINFO_HELP_READYTORUN_GENERIC_HANDLE, &genericLookup); + CORINFO_HELP_READYTORUN_GENERIC_HANDLE, info.compMethodHnd, &genericLookup); GenTree* ctxTree = getRuntimeContextTree(pLookup.lookupKind.runtimeLookupKind); call = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_DELEGATE_CTOR, TYP_VOID, thisPointer, targetObjPointers, ctxTree); diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 1537ba3e25dc40..b8fdeeb8c91521 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -9092,7 +9092,7 @@ GenTree* Compiler::gtNewBitCastNode(var_types type, GenTree* arg) // can't be represented in jitted code. If this happens, this method will return // nullptr. // -GenTreeAllocObj* Compiler::gtNewAllocObjNode(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool useParent) +GenTreeAllocObj* Compiler::gtNewAllocObjNode(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, bool useParent) { const bool mustRestoreHandle = true; bool* const pRuntimeLookup = nullptr; @@ -9108,7 +9108,7 @@ GenTreeAllocObj* Compiler::gtNewAllocObjNode(CORINFO_RESOLVED_TOKEN* pResolvedTo helper = CORINFO_HELP_READYTORUN_NEW; CORINFO_LOOKUP_KIND* const pGenericLookupKind = nullptr; usingReadyToRunHelper = - info.compCompHnd->getReadyToRunHelper(pResolvedToken, pGenericLookupKind, helper, &lookup); + info.compCompHnd->getReadyToRunHelper(pResolvedToken, pGenericLookupKind, helper, callerHandle, &lookup); } #endif diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 72d36fd5b0fd75..e1b78d72680b8b 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1485,7 +1485,7 @@ GenTreeCall* Compiler::impReadyToRunHelperToTree(CORINFO_RESOLVED_TOKEN* pResolv GenTree* arg1) { CORINFO_CONST_LOOKUP lookup; - if (!info.compCompHnd->getReadyToRunHelper(pResolvedToken, pGenericLookupKind, helper, &lookup)) + if (!info.compCompHnd->getReadyToRunHelper(pResolvedToken, pGenericLookupKind, helper, info.compMethodHnd, &lookup)) { return nullptr; } @@ -3265,7 +3265,7 @@ void Compiler::impImportAndPushBox(CORINFO_RESOLVED_TOKEN* pResolvedToken) Statement* const cursor = impLastStmt; const bool useParent = false; - op1 = gtNewAllocObjNode(pResolvedToken, useParent); + op1 = gtNewAllocObjNode(pResolvedToken, info.compMethodHnd, useParent); if (op1 == nullptr) { // If we fail to create the newobj node, we must be inlining @@ -8501,7 +8501,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) } const bool useParent = true; - op1 = gtNewAllocObjNode(&resolvedToken, useParent); + op1 = gtNewAllocObjNode(&resolvedToken, info.compMethodHnd, useParent); if (op1 == nullptr) { return; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 8c488fa75c58a8..cc1f915974446c 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -1033,12 +1033,12 @@ private static byte _getStringChar(IntPtr thisHandle, IntPtr* ppException, CORIN } [UnmanagedCallersOnly] - private static byte _getReadyToRunHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, CORINFO_CONST_LOOKUP* pLookup) + private static byte _getReadyToRunHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, CORINFO_METHOD_STRUCT_* callerHandle, CORINFO_CONST_LOOKUP* pLookup) { var _this = GetThis(thisHandle); try { - return _this.getReadyToRunHelper(ref *pResolvedToken, ref *pGenericLookupKind, id, ref *pLookup) ? (byte)1 : (byte)0; + return _this.getReadyToRunHelper(ref *pResolvedToken, ref *pGenericLookupKind, id, callerHandle, ref *pLookup) ? (byte)1 : (byte)0; } catch (Exception ex) { @@ -2636,7 +2636,7 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[66] = (delegate* unmanaged)&_isObjectImmutable; callbacks[67] = (delegate* unmanaged)&_getStringChar; callbacks[68] = (delegate* unmanaged)&_getObjectType; - callbacks[69] = (delegate* unmanaged)&_getReadyToRunHelper; + callbacks[69] = (delegate* unmanaged)&_getReadyToRunHelper; callbacks[70] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper; callbacks[71] = (delegate* unmanaged)&_initClass; callbacks[72] = (delegate* unmanaged)&_classMustBeLoadedBeforeCodeIsRun; diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 9d99113f68fbd5..13b812129a8a71 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -231,7 +231,7 @@ FUNCTIONS bool isObjectImmutable(CORINFO_OBJECT_HANDLE objPtr) bool getStringChar(CORINFO_OBJECT_HANDLE strObj, int index, uint16_t* value); CORINFO_CLASS_HANDLE getObjectType(CORINFO_OBJECT_HANDLE objPtr) - bool getReadyToRunHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_LOOKUP_KIND * pGenericLookupKind, CorInfoHelpFunc id, CORINFO_CONST_LOOKUP *pLookup) + bool getReadyToRunHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_LOOKUP_KIND * pGenericLookupKind, CorInfoHelpFunc id, CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP *pLookup) void getReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN * pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, CORINFO_LOOKUP *pLookup) CorInfoInitClassResult initClass(CORINFO_FIELD_HANDLE field, CORINFO_METHOD_HANDLE method, CORINFO_CONTEXT_HANDLE context) void classMustBeLoadedBeforeCodeIsRun(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 39e5fa26d7a8ea..a6542690e1f453 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -827,7 +827,7 @@ public void CompileMethod(MethodWithGCInfo methodCodeNodeNeedingCode, Logger log } } - private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref CORINFO_LOOKUP_KIND pGenericLookupKind, CorInfoHelpFunc id, ref CORINFO_CONST_LOOKUP pLookup) + private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref CORINFO_LOOKUP_KIND pGenericLookupKind, CorInfoHelpFunc id, CORINFO_METHOD_STRUCT_* callerHandle, ref CORINFO_CONST_LOOKUP pLookup) { switch (id) { 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 cc72e6e10888f2..968f2294849be1 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -311,7 +311,7 @@ private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object ent } } - private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref CORINFO_LOOKUP_KIND pGenericLookupKind, CorInfoHelpFunc id, ref CORINFO_CONST_LOOKUP pLookup) + private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref CORINFO_LOOKUP_KIND pGenericLookupKind, CorInfoHelpFunc id, CORINFO_METHOD_STRUCT_* callerHandle, ref CORINFO_CONST_LOOKUP pLookup) { switch (id) { @@ -342,7 +342,7 @@ private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref Debug.Assert(typeToInitialize.IsCanonicalSubtype(CanonicalFormKind.Any)); DefType helperArg = typeToInitialize.ConvertToSharedRuntimeDeterminedForm(); - ISymbolNode helper = GetGenericLookupHelper(pGenericLookupKind.runtimeLookupKind, ReadyToRunHelperId.GetNonGCStaticBase, helperArg); + ISymbolNode helper = GetGenericLookupHelper(pGenericLookupKind.runtimeLookupKind, ReadyToRunHelperId.GetNonGCStaticBase, HandleToObject(callerHandle), helperArg); pLookup = CreateConstLookupToSymbol(helper); } break; @@ -352,7 +352,7 @@ private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref ReadyToRunHelperId helperId = (ReadyToRunHelperId)pGenericLookupKind.runtimeLookupFlags; object helperArg = HandleToObject(pGenericLookupKind.runtimeLookupArgs); - ISymbolNode helper = GetGenericLookupHelper(pGenericLookupKind.runtimeLookupKind, helperId, helperArg); + ISymbolNode helper = GetGenericLookupHelper(pGenericLookupKind.runtimeLookupKind, helperId, HandleToObject(callerHandle), helperArg); pLookup = CreateConstLookupToSymbol(helper); } break; @@ -1061,16 +1061,16 @@ private void SetDebugInformation(IMethodNode methodCodeNodeNeedingCode, MethodIL _debugInfo = _compilation.GetDebugInfo(methodIL); } - private ISymbolNode GetGenericLookupHelper(CORINFO_RUNTIME_LOOKUP_KIND runtimeLookupKind, ReadyToRunHelperId helperId, object helperArgument) + private ISymbolNode GetGenericLookupHelper(CORINFO_RUNTIME_LOOKUP_KIND runtimeLookupKind, ReadyToRunHelperId helperId, MethodDesc callerHandle, object helperArgument) { if (runtimeLookupKind == CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_THISOBJ || runtimeLookupKind == CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_CLASSPARAM) { - return _compilation.NodeFactory.ReadyToRunHelperFromTypeLookup(helperId, helperArgument, MethodBeingCompiled.OwningType); + return _compilation.NodeFactory.ReadyToRunHelperFromTypeLookup(helperId, helperArgument, callerHandle.OwningType); } Debug.Assert(runtimeLookupKind == CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_METHODPARAM); - return _compilation.NodeFactory.ReadyToRunHelperFromDictionaryLookup(helperId, helperArgument, MethodBeingCompiled); + return _compilation.NodeFactory.ReadyToRunHelperFromDictionaryLookup(helperId, helperArgument, callerHandle); } private CorInfoHelpFunc getCastingHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool fThrowing) diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index 8a3a3a7d2dec82..a150fec736da44 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -80,7 +80,7 @@ struct JitInterfaceCallbacks bool (* isObjectImmutable)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_OBJECT_HANDLE objPtr); bool (* getStringChar)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_OBJECT_HANDLE strObj, int index, uint16_t* value); CORINFO_CLASS_HANDLE (* getObjectType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_OBJECT_HANDLE objPtr); - bool (* getReadyToRunHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, CORINFO_CONST_LOOKUP* pLookup); + bool (* getReadyToRunHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP* pLookup); void (* getReadyToRunDelegateCtorHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pTargetMethod, unsigned int targetConstraint, CORINFO_CLASS_HANDLE delegateType, CORINFO_LOOKUP* pLookup); CorInfoInitClassResult (* initClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, CORINFO_METHOD_HANDLE method, CORINFO_CONTEXT_HANDLE context); void (* classMustBeLoadedBeforeCodeIsRun)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); @@ -875,10 +875,11 @@ class JitInterfaceWrapper : public ICorJitInfo CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP* pLookup) { CorInfoExceptionClass* pException = nullptr; - bool temp = _callbacks->getReadyToRunHelper(_thisHandle, &pException, pResolvedToken, pGenericLookupKind, id, pLookup); + bool temp = _callbacks->getReadyToRunHelper(_thisHandle, &pException, pResolvedToken, pGenericLookupKind, id, callerHandle, pLookup); if (pException != nullptr) throw pException; return temp; } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h index 2c3100d24ebdd6..198ec25e981904 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h @@ -686,6 +686,7 @@ struct GetReadyToRunHelper_TOKENin Agnostic_CORINFO_RESOLVED_TOKEN ResolvedToken; Agnostic_CORINFO_LOOKUP_KIND GenericLookupKind; DWORD id; + DWORDLONG callerHandle; }; struct GetReadyToRunHelper_TOKENout diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 0dcfd0faca7b30..5e4e14dced7c5e 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -2276,6 +2276,7 @@ CORINFO_CLASS_HANDLE MethodContext::repGetObjectType(CORINFO_OBJECT_HANDLE objPt void MethodContext::recGetReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP* pLookup, bool result) { @@ -2287,6 +2288,7 @@ void MethodContext::recGetReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToke key.ResolvedToken = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, GetReadyToRunHelper); key.GenericLookupKind = SpmiRecordsHelper::CreateAgnostic_CORINFO_LOOKUP_KIND(pGenericLookupKind); key.id = (DWORD)id; + key.callerHandle = CastHandle(callerHandle); GetReadyToRunHelper_TOKENout value; value.Lookup = SpmiRecordsHelper::StoreAgnostic_CORINFO_CONST_LOOKUP(pLookup); value.result = result; @@ -2307,6 +2309,7 @@ void MethodContext::dmpGetReadyToRunHelper(GetReadyToRunHelper_TOKENin key, GetR bool MethodContext::repGetReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP* pLookup) { AssertMapExistsNoMessage(GetReadyToRunHelper); @@ -2316,6 +2319,7 @@ bool MethodContext::repGetReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToke key.ResolvedToken = SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, GetReadyToRunHelper); key.GenericLookupKind = SpmiRecordsHelper::CreateAgnostic_CORINFO_LOOKUP_KIND(pGenericLookupKind); key.id = (DWORD)id; + key.callerHandle = CastHandle(callerHandle); GetReadyToRunHelper_TOKENout value = LookupByKeyOrMissNoMessage(GetReadyToRunHelper, key); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 058257c3ed3a32..c5178d7f9a3335 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -315,12 +315,14 @@ class MethodContext void recGetReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP* pLookup, bool result); void dmpGetReadyToRunHelper(GetReadyToRunHelper_TOKENin key, GetReadyToRunHelper_TOKENout value); bool repGetReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP* pLookup); void recGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 7b9265f37cef9c..d9d02ea621a91e 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -781,11 +781,12 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::getObjectType(CORINFO_OBJECT_HANDLE typeO bool interceptor_ICJI::getReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP* pLookup) { mc->cr->AddCall("getReadyToRunHelper"); - bool result = original_ICorJitInfo->getReadyToRunHelper(pResolvedToken, pGenericLookupKind, id, pLookup); - mc->recGetReadyToRunHelper(pResolvedToken, pGenericLookupKind, id, pLookup, result); + bool result = original_ICorJitInfo->getReadyToRunHelper(pResolvedToken, pGenericLookupKind, id, callerHandle, pLookup); + mc->recGetReadyToRunHelper(pResolvedToken, pGenericLookupKind, id, callerHandle, pLookup, result); return result; } 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 9b2c6585672191..3a46964ae28d40 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -565,10 +565,11 @@ bool interceptor_ICJI::getReadyToRunHelper( CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP* pLookup) { mcs->AddCall("getReadyToRunHelper"); - return original_ICorJitInfo->getReadyToRunHelper(pResolvedToken, pGenericLookupKind, id, pLookup); + return original_ICorJitInfo->getReadyToRunHelper(pResolvedToken, pGenericLookupKind, id, callerHandle, pLookup); } void interceptor_ICJI::getReadyToRunDelegateCtorHelper( 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 8b731e0a2773d6..1c1e39cf4d988c 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -496,9 +496,10 @@ bool interceptor_ICJI::getReadyToRunHelper( CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP* pLookup) { - return original_ICorJitInfo->getReadyToRunHelper(pResolvedToken, pGenericLookupKind, id, pLookup); + return original_ICorJitInfo->getReadyToRunHelper(pResolvedToken, pGenericLookupKind, id, callerHandle, pLookup); } void interceptor_ICJI::getReadyToRunDelegateCtorHelper( diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 804a74fd67ddc7..c35cc73879044d 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -653,10 +653,11 @@ CORINFO_CLASS_HANDLE MyICJI::getObjectType(CORINFO_OBJECT_HANDLE objPtr) bool MyICJI::getReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP* pLookup) { jitInstance->mc->cr->AddCall("getReadyToRunHelper"); - return jitInstance->mc->repGetReadyToRunHelper(pResolvedToken, pGenericLookupKind, id, pLookup); + return jitInstance->mc->repGetReadyToRunHelper(pResolvedToken, pGenericLookupKind, id, callerHandle, pLookup); } void MyICJI::getReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 789f0bb4ee2af0..5d768383bb1f52 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -6287,6 +6287,7 @@ bool CEEInfo::getReadyToRunHelper( CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_LOOKUP_KIND * pGenericLookupKind, CorInfoHelpFunc id, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP * pLookup ) { From 66e6dc34454502e414a09b043b6f3befb0d6996f Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 11 Mar 2024 12:59:46 +0100 Subject: [PATCH 23/40] add to getReadyToRunDelegateCtorHelper as well --- src/coreclr/inc/corinfo.h | 1 + src/coreclr/inc/icorjitinfoimpl_generated.h | 1 + src/coreclr/inc/jiteeversionguid.h | 10 +- .../jit/ICorJitInfo_wrapper_generated.hpp | 3 +- src/coreclr/jit/flowgraph.cpp | 7 +- .../JitInterface/CorInfoImpl_generated.cs | 6 +- .../ThunkGenerator/ThunkInput.txt | 2 +- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 2 +- .../JitInterface/CorInfoImpl.RyuJit.cs | 92 ++++++++----------- .../aot/jitinterface/jitinterface_generated.h | 5 +- .../tools/superpmi/superpmi-shared/agnostic.h | 1 + .../superpmi-shared/methodcontext.cpp | 4 + .../superpmi/superpmi-shared/methodcontext.h | 2 + .../superpmi-shim-collector/icorjitinfo.cpp | 5 +- .../icorjitinfo_generated.cpp | 3 +- .../icorjitinfo_generated.cpp | 3 +- .../tools/superpmi/superpmi/icorjitinfo.cpp | 3 +- src/coreclr/vm/jitinterface.cpp | 3 +- 18 files changed, 75 insertions(+), 78 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index d3561e04cc061e..40bf2c707c9837 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2646,6 +2646,7 @@ class ICorStaticInfo CORINFO_RESOLVED_TOKEN * pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_LOOKUP * pLookup ) = 0; diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index 1489c91c0935bd..5427ceed467400 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -305,6 +305,7 @@ void getReadyToRunDelegateCtorHelper( CORINFO_RESOLVED_TOKEN* pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_LOOKUP* pLookup) override; CorInfoInitClassResult initClass( diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index f9fed1212415d4..c5a0511ec6d463 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 = { /* 869120e3-3d61-42c3-bada-297da00f3044 */ - 0x869120e3, - 0x3d61, - 0x42c3, - {0xba, 0xda, 0x29, 0x7d, 0xa0, 0x0f, 0x30, 0x44} +constexpr GUID JITEEVersionIdentifier = { /* 288fe8da-6cd0-42a9-a45f-13bb9f8a0ecf */ + 0x288fe8da, + 0x6cd0, + 0x42a9, + {0xa4, 0x5f, 0x13, 0xbb, 0x9f, 0x8a, 0x0e, 0xcf} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index 57749ac645a0df..13edb8529cb9d9 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -701,10 +701,11 @@ void WrapICorJitInfo::getReadyToRunDelegateCtorHelper( CORINFO_RESOLVED_TOKEN* pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_LOOKUP* pLookup) { API_ENTER(getReadyToRunDelegateCtorHelper); - wrapHnd->getReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, pLookup); + wrapHnd->getReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, callerHandle, pLookup); API_LEAVE(getReadyToRunDelegateCtorHelper); } diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp index d414b5e17d75f3..b47b577d69c02e 100644 --- a/src/coreclr/jit/flowgraph.cpp +++ b/src/coreclr/jit/flowgraph.cpp @@ -1036,7 +1036,7 @@ GenTree* Compiler::fgOptimizeDelegateConstructor(GenTreeCall* call, GenTree* targetObjPointers = call->gtArgs.GetArgByIndex(1)->GetNode(); CORINFO_LOOKUP pLookup; info.compCompHnd->getReadyToRunDelegateCtorHelper(&ldftnToken->m_token, ldftnToken->m_tokenConstraint, - clsHnd, &pLookup); + clsHnd, info.compMethodHnd, &pLookup); if (!pLookup.lookupKind.needsRuntimeLookup) { call = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_DELEGATE_CTOR, TYP_VOID, thisPointer, @@ -1048,7 +1048,8 @@ GenTree* Compiler::fgOptimizeDelegateConstructor(GenTreeCall* call, assert(oper != GT_FTN_ADDR); CORINFO_CONST_LOOKUP genericLookup; info.compCompHnd->getReadyToRunHelper(&ldftnToken->m_token, &pLookup.lookupKind, - CORINFO_HELP_READYTORUN_GENERIC_HANDLE, info.compMethodHnd, &genericLookup); + CORINFO_HELP_READYTORUN_GENERIC_HANDLE, info.compMethodHnd, + &genericLookup); GenTree* ctxTree = getRuntimeContextTree(pLookup.lookupKind.runtimeLookupKind); call = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_DELEGATE_CTOR, TYP_VOID, thisPointer, targetObjPointers, ctxTree); @@ -1071,7 +1072,7 @@ GenTree* Compiler::fgOptimizeDelegateConstructor(GenTreeCall* call, CORINFO_LOOKUP entryPoint; info.compCompHnd->getReadyToRunDelegateCtorHelper(&ldftnToken->m_token, ldftnToken->m_tokenConstraint, - clsHnd, &entryPoint); + clsHnd, info.compMethodHnd, &entryPoint); assert(!entryPoint.lookupKind.needsRuntimeLookup); call->setEntryPoint(entryPoint.constLookup); } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index cc1f915974446c..9677863e7fc5f8 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -1048,12 +1048,12 @@ private static byte _getReadyToRunHelper(IntPtr thisHandle, IntPtr* ppException, } [UnmanagedCallersOnly] - private static void _getReadyToRunDelegateCtorHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_STRUCT_* delegateType, CORINFO_LOOKUP* pLookup) + private static void _getReadyToRunDelegateCtorHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_STRUCT_* delegateType, CORINFO_METHOD_STRUCT_* callerHandle, CORINFO_LOOKUP* pLookup) { var _this = GetThis(thisHandle); try { - _this.getReadyToRunDelegateCtorHelper(ref *pTargetMethod, targetConstraint, delegateType, ref *pLookup); + _this.getReadyToRunDelegateCtorHelper(ref *pTargetMethod, targetConstraint, delegateType, callerHandle, ref *pLookup); } catch (Exception ex) { @@ -2637,7 +2637,7 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[67] = (delegate* unmanaged)&_getStringChar; callbacks[68] = (delegate* unmanaged)&_getObjectType; callbacks[69] = (delegate* unmanaged)&_getReadyToRunHelper; - callbacks[70] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper; + callbacks[70] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper; callbacks[71] = (delegate* unmanaged)&_initClass; callbacks[72] = (delegate* unmanaged)&_classMustBeLoadedBeforeCodeIsRun; callbacks[73] = (delegate* unmanaged)&_getBuiltinClass; diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 13b812129a8a71..1fdad93abb0317 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -232,7 +232,7 @@ FUNCTIONS bool getStringChar(CORINFO_OBJECT_HANDLE strObj, int index, uint16_t* value); CORINFO_CLASS_HANDLE getObjectType(CORINFO_OBJECT_HANDLE objPtr) bool getReadyToRunHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_LOOKUP_KIND * pGenericLookupKind, CorInfoHelpFunc id, CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP *pLookup) - void getReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN * pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, CORINFO_LOOKUP *pLookup) + void getReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN * pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, CORINFO_METHOD_HANDLE callerHandle, CORINFO_LOOKUP *pLookup) CorInfoInitClassResult initClass(CORINFO_FIELD_HANDLE field, CORINFO_METHOD_HANDLE method, CORINFO_CONTEXT_HANDLE context) void classMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_HANDLE cls) CORINFO_CLASS_HANDLE getBuiltinClass(CorInfoClassId classId) 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 a6542690e1f453..c3e2bff274d2ec 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -928,7 +928,7 @@ private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref return true; } - private void getReadyToRunDelegateCtorHelper(ref CORINFO_RESOLVED_TOKEN pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_STRUCT_* delegateType, ref CORINFO_LOOKUP pLookup) + private void getReadyToRunDelegateCtorHelper(ref CORINFO_RESOLVED_TOKEN pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_STRUCT_* delegateType, CORINFO_METHOD_STRUCT_* callerHandle, ref CORINFO_LOOKUP pLookup) { #if DEBUG // In debug, write some bogus data to the struct to ensure we have filled everything 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 968f2294849be1..17b58e616a5e52 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -338,7 +338,7 @@ private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref Debug.Assert(pResolvedToken.token == 0 && pResolvedToken.tokenScope == null); Debug.Assert(pGenericLookupKind.needsRuntimeLookup); - DefType typeToInitialize = (DefType)MethodBeingCompiled.OwningType; + DefType typeToInitialize = (DefType)HandleToObject(callerHandle).OwningType; Debug.Assert(typeToInitialize.IsCanonicalSubtype(CanonicalFormKind.Any)); DefType helperArg = typeToInitialize.ConvertToSharedRuntimeDeterminedForm(); @@ -362,7 +362,7 @@ private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref return true; } - private void getReadyToRunDelegateCtorHelper(ref CORINFO_RESOLVED_TOKEN pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_STRUCT_* delegateType, ref CORINFO_LOOKUP pLookup) + private void getReadyToRunDelegateCtorHelper(ref CORINFO_RESOLVED_TOKEN pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_STRUCT_* delegateType, CORINFO_METHOD_STRUCT_* callerHandle, ref CORINFO_LOOKUP pLookup) { #if DEBUG // In debug, write some bogus data to the struct to ensure we have filled everything @@ -441,11 +441,7 @@ private void getReadyToRunDelegateCtorHelper(ref CORINFO_RESOLVED_TOKEN pTargetM { pLookup.lookupKind.needsRuntimeLookup = true; - MethodDesc contextMethod = methodFromContext(pTargetMethod.tokenContext); - - // We should not be inlining these. RyuJIT should have aborted inlining already. - Debug.Assert(contextMethod == MethodBeingCompiled); - + MethodDesc contextMethod = HandleToObject(callerHandle); pLookup.lookupKind.runtimeLookupKind = GetGenericRuntimeLookupKind(contextMethod); pLookup.lookupKind.runtimeLookupFlags = (ushort)ReadyToRunHelperId.DelegateCtor; pLookup.lookupKind.runtimeLookupArgs = (void*)ObjectToHandle(delegateInfo); @@ -1444,20 +1440,9 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO pResult->codePointerOrStubLookup.lookupKind.needsRuntimeLookup = true; pResult->codePointerOrStubLookup.lookupKind.runtimeLookupFlags = 0; pResult->codePointerOrStubLookup.runtimeLookup.indirections = CORINFO.USEHELPER; - - // Do not bother computing the runtime lookup if we are inlining. The JIT is going - // to abort the inlining attempt anyway. - if (pResolvedToken.tokenContext == contextFromMethodBeingCompiled()) - { - MethodDesc contextMethod = methodFromContext(pResolvedToken.tokenContext); - pResult->codePointerOrStubLookup.lookupKind.runtimeLookupKind = GetGenericRuntimeLookupKind(contextMethod); - pResult->codePointerOrStubLookup.lookupKind.runtimeLookupFlags = (ushort)ReadyToRunHelperId.MethodEntry; - pResult->codePointerOrStubLookup.lookupKind.runtimeLookupArgs = (void*)ObjectToHandle(GetRuntimeDeterminedObjectForToken(ref pResolvedToken)); - } - else - { - pResult->codePointerOrStubLookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_NOT_SUPPORTED; - } + pResult->codePointerOrStubLookup.lookupKind.runtimeLookupKind = GetGenericRuntimeLookupKind(HandleToObject(callerHandle)); + pResult->codePointerOrStubLookup.lookupKind.runtimeLookupFlags = (ushort)ReadyToRunHelperId.MethodEntry; + pResult->codePointerOrStubLookup.lookupKind.runtimeLookupArgs = (void*)ObjectToHandle(GetRuntimeDeterminedObjectForToken(ref pResolvedToken)); } else { @@ -2140,46 +2125,41 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET fieldAccessor = CORINFO_FIELD_ACCESSOR.CORINFO_FIELD_STATIC_READYTORUN_HELPER; pResult->helper = CorInfoHelpFunc.CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE; - // Don't try to compute the runtime lookup if we're inlining. The JIT is going to abort the inlining - // attempt anyway. - if (pResolvedToken.tokenContext == contextFromMethodBeingCompiled()) - { - MethodDesc contextMethod = methodFromContext(pResolvedToken.tokenContext); - - FieldDesc runtimeDeterminedField = (FieldDesc)GetRuntimeDeterminedObjectForToken(ref pResolvedToken); + MethodDesc contextMethod = HandleToObject(callerHandle); - ReadyToRunHelperId helperId; + FieldDesc runtimeDeterminedField = (FieldDesc)GetRuntimeDeterminedObjectForToken(ref pResolvedToken); - // Find out what kind of base do we need to look up. - if (field.IsThreadStatic) - { - helperId = ReadyToRunHelperId.GetThreadStaticBase; - } - else if (field.HasGCStaticBase) - { - helperId = ReadyToRunHelperId.GetGCStaticBase; - } - else - { - helperId = ReadyToRunHelperId.GetNonGCStaticBase; - } + ReadyToRunHelperId helperId; - // What generic context do we look up the base from. - ISymbolNode helper; - if (contextMethod.AcquiresInstMethodTableFromThis() || contextMethod.RequiresInstMethodTableArg()) - { - helper = _compilation.NodeFactory.ReadyToRunHelperFromTypeLookup( - helperId, runtimeDeterminedField.OwningType, contextMethod.OwningType); - } - else - { - Debug.Assert(contextMethod.RequiresInstMethodDescArg()); - helper = _compilation.NodeFactory.ReadyToRunHelperFromDictionaryLookup( - helperId, runtimeDeterminedField.OwningType, contextMethod); - } + // Find out what kind of base do we need to look up. + if (field.IsThreadStatic) + { + helperId = ReadyToRunHelperId.GetThreadStaticBase; + } + else if (field.HasGCStaticBase) + { + helperId = ReadyToRunHelperId.GetGCStaticBase; + } + else + { + helperId = ReadyToRunHelperId.GetNonGCStaticBase; + } - pResult->fieldLookup = CreateConstLookupToSymbol(helper); + // What generic context do we look up the base from. + ISymbolNode helper; + if (contextMethod.AcquiresInstMethodTableFromThis() || contextMethod.RequiresInstMethodTableArg()) + { + helper = _compilation.NodeFactory.ReadyToRunHelperFromTypeLookup( + helperId, runtimeDeterminedField.OwningType, contextMethod.OwningType); } + else + { + Debug.Assert(contextMethod.RequiresInstMethodDescArg()); + helper = _compilation.NodeFactory.ReadyToRunHelperFromDictionaryLookup( + helperId, runtimeDeterminedField.OwningType, contextMethod); + } + + pResult->fieldLookup = CreateConstLookupToSymbol(helper); } else { diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index a150fec736da44..2f79cdab14c7ef 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -81,7 +81,7 @@ struct JitInterfaceCallbacks bool (* getStringChar)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_OBJECT_HANDLE strObj, int index, uint16_t* value); CORINFO_CLASS_HANDLE (* getObjectType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_OBJECT_HANDLE objPtr); bool (* getReadyToRunHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, CORINFO_METHOD_HANDLE callerHandle, CORINFO_CONST_LOOKUP* pLookup); - void (* getReadyToRunDelegateCtorHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pTargetMethod, unsigned int targetConstraint, CORINFO_CLASS_HANDLE delegateType, CORINFO_LOOKUP* pLookup); + void (* getReadyToRunDelegateCtorHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pTargetMethod, unsigned int targetConstraint, CORINFO_CLASS_HANDLE delegateType, CORINFO_METHOD_HANDLE callerHandle, CORINFO_LOOKUP* pLookup); CorInfoInitClassResult (* initClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, CORINFO_METHOD_HANDLE method, CORINFO_CONTEXT_HANDLE context); void (* classMustBeLoadedBeforeCodeIsRun)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); CORINFO_CLASS_HANDLE (* getBuiltinClass)(void * thisHandle, CorInfoExceptionClass** ppException, CorInfoClassId classId); @@ -888,10 +888,11 @@ class JitInterfaceWrapper : public ICorJitInfo CORINFO_RESOLVED_TOKEN* pTargetMethod, unsigned int targetConstraint, CORINFO_CLASS_HANDLE delegateType, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_LOOKUP* pLookup) { CorInfoExceptionClass* pException = nullptr; - _callbacks->getReadyToRunDelegateCtorHelper(_thisHandle, &pException, pTargetMethod, targetConstraint, delegateType, pLookup); + _callbacks->getReadyToRunDelegateCtorHelper(_thisHandle, &pException, pTargetMethod, targetConstraint, delegateType, callerHandle, pLookup); if (pException != nullptr) throw pException; } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h index 198ec25e981904..f3a8c3f9141c62 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h @@ -700,6 +700,7 @@ struct GetReadyToRunDelegateCtorHelper_TOKENIn Agnostic_CORINFO_RESOLVED_TOKEN TargetMethod; mdToken targetConstraint; DWORDLONG delegateType; + DWORDLONG callerHandle; }; struct Agnostic_RecordRelocation diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 5e4e14dced7c5e..db7473e14d99df 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -2332,6 +2332,7 @@ bool MethodContext::repGetReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToke void MethodContext::recGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_LOOKUP* pLookup) { if (GetReadyToRunDelegateCtorHelper == nullptr) @@ -2344,6 +2345,7 @@ void MethodContext::recGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* p SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pTargetMethod, GetReadyToRunDelegateCtorHelper); key.targetConstraint = targetConstraint; key.delegateType = CastHandle(delegateType); + key.callerHandle = CastHandle(callerHandle); Agnostic_CORINFO_LOOKUP value = SpmiRecordsHelper::StoreAgnostic_CORINFO_LOOKUP(pLookup); GetReadyToRunDelegateCtorHelper->Add(key, value); DEBUG_REC(dmpGetReadyToRunDelegateCtorHelper(key, value)); @@ -2360,6 +2362,7 @@ void MethodContext::dmpGetReadyToRunDelegateCtorHelper(GetReadyToRunDelegateCtor void MethodContext::repGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_LOOKUP* pLookup) { AssertMapExistsNoMessage(GetReadyToRunDelegateCtorHelper); @@ -2370,6 +2373,7 @@ void MethodContext::repGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* p SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pTargetMethod, GetReadyToRunDelegateCtorHelper); key.targetConstraint = targetConstraint; key.delegateType = CastHandle(delegateType); + key.callerHandle = CastHandle(callerHandle); Agnostic_CORINFO_LOOKUP value = LookupByKeyOrMissNoMessage(GetReadyToRunDelegateCtorHelper, key); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index c5178d7f9a3335..72252a99495429 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -328,12 +328,14 @@ class MethodContext void recGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_LOOKUP* pLookup); void dmpGetReadyToRunDelegateCtorHelper(GetReadyToRunDelegateCtorHelper_TOKENIn key, Agnostic_CORINFO_LOOKUP pLookup); void repGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_LOOKUP* pLookup); void recGetHelperFtn(CorInfoHelpFunc ftnNum, void** ppIndirection, void* result); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index d9d02ea621a91e..ba2acbfc0bf645 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -793,11 +793,12 @@ bool interceptor_ICJI::getReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToke void interceptor_ICJI::getReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_LOOKUP* pLookup) { mc->cr->AddCall("getReadyToRunDelegateCtorHelper"); - original_ICorJitInfo->getReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, pLookup); - mc->recGetReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, pLookup); + original_ICorJitInfo->getReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, callerHandle, pLookup); + mc->recGetReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, callerHandle, pLookup); } // This function tries to initialize the class (run the class constructor). 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 3a46964ae28d40..0259e75d1d4e0f 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -576,10 +576,11 @@ void interceptor_ICJI::getReadyToRunDelegateCtorHelper( CORINFO_RESOLVED_TOKEN* pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_LOOKUP* pLookup) { mcs->AddCall("getReadyToRunDelegateCtorHelper"); - original_ICorJitInfo->getReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, pLookup); + original_ICorJitInfo->getReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, callerHandle, pLookup); } CorInfoInitClassResult interceptor_ICJI::initClass( 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 1c1e39cf4d988c..309aa289da10af 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -506,9 +506,10 @@ void interceptor_ICJI::getReadyToRunDelegateCtorHelper( CORINFO_RESOLVED_TOKEN* pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_LOOKUP* pLookup) { - original_ICorJitInfo->getReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, pLookup); + original_ICorJitInfo->getReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, callerHandle, pLookup); } CorInfoInitClassResult interceptor_ICJI::initClass( diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index c35cc73879044d..d6f34a01beaab4 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -663,10 +663,11 @@ bool MyICJI::getReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, void MyICJI::getReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, + CORINFO_METHOD_HANDLE callerHandle, CORINFO_LOOKUP* pLookup) { jitInstance->mc->cr->AddCall("getReadyToRunDelegateCtorHelper"); - jitInstance->mc->repGetReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, pLookup); + jitInstance->mc->repGetReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, callerHandle, pLookup); } // This function tries to initialize the class (run the class constructor). diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 5d768383bb1f52..dc0a952e6daebd 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -6300,7 +6300,8 @@ void CEEInfo::getReadyToRunDelegateCtorHelper( CORINFO_RESOLVED_TOKEN * pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, - CORINFO_LOOKUP * pLookup + CORINFO_METHOD_HANDLE callerHandle, + CORINFO_LOOKUP * pLookup ) { LIMITED_METHOD_CONTRACT; From 369f763c69559f5ca0bb878883cdb8e8a89632c1 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 11 Mar 2024 13:03:16 +0100 Subject: [PATCH 24/40] formatting --- src/coreclr/jit/gentree.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index b8fdeeb8c91521..4c924b3984787b 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -9092,7 +9092,9 @@ GenTree* Compiler::gtNewBitCastNode(var_types type, GenTree* arg) // can't be represented in jitted code. If this happens, this method will return // nullptr. // -GenTreeAllocObj* Compiler::gtNewAllocObjNode(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, bool useParent) +GenTreeAllocObj* Compiler::gtNewAllocObjNode(CORINFO_RESOLVED_TOKEN* pResolvedToken, + CORINFO_METHOD_HANDLE callerHandle, + bool useParent) { const bool mustRestoreHandle = true; bool* const pRuntimeLookup = nullptr; From 478ef857655d78b3a99bb861a6522954f06c34e8 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 12 Mar 2024 03:15:38 +0100 Subject: [PATCH 25/40] Like this (it currently fails) --- .../Common/Compiler/CompilationBuilder.cs | 7 ++++ .../ShadowConcreteMethodNode.cs | 13 +++++++ .../Compiler/RyuJitCompilation.cs | 9 +++-- .../Compiler/RyuJitCompilationBuilder.cs | 2 +- .../JitInterface/CorInfoImpl.RyuJit.cs | 34 +++++++++---------- src/coreclr/tools/aot/ILCompiler/Program.cs | 1 + 6 files changed, 45 insertions(+), 21 deletions(-) diff --git a/src/coreclr/tools/Common/Compiler/CompilationBuilder.cs b/src/coreclr/tools/Common/Compiler/CompilationBuilder.cs index 5357e2f68234ba..e7ced3418e3c81 100644 --- a/src/coreclr/tools/Common/Compiler/CompilationBuilder.cs +++ b/src/coreclr/tools/Common/Compiler/CompilationBuilder.cs @@ -23,6 +23,7 @@ public abstract partial class CompilationBuilder private DependencyTrackingLevel _dependencyTrackingLevel = DependencyTrackingLevel.None; protected IEnumerable _compilationRoots = Array.Empty(); protected OptimizationMode _optimizationMode = OptimizationMode.None; + protected bool _canInlineMethodWithRuntimeLookups; protected int _parallelism = -1; protected bool _resilient; @@ -73,6 +74,12 @@ public CompilationBuilder UseOptimizationMode(OptimizationMode mode) return this; } + public CompilationBuilder UseInliningForMethodsWithRuntimeLookups(bool enable) + { + _canInlineMethodWithRuntimeLookups = enable; + return this; + } + public CompilationBuilder UseResilience(bool resilient) { _resilient = resilient; diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs index 140a97f70924ee..d016c638557b50 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs @@ -75,6 +75,19 @@ public override IEnumerable GetStaticDependencies(NodeFacto foreach (DependencyListEntry canonDep in staticDependencies) { var runtimeDep = canonDep.Node as INodeWithRuntimeDeterminedDependencies; + + // ??? + var canonMethod = Method.GetCanonMethodTarget(CanonicalFormKind.Specific); + + if (runtimeDep is ReadyToRunGenericLookupFromDictionaryNode lookupFromMethod + && (!canonMethod.RequiresInstMethodDescArg() || lookupFromMethod.DictionaryOwner != canonMethod)) + continue; + + if (runtimeDep is ReadyToRunGenericLookupFromTypeNode lookupFromType + && (!canonMethod.RequiresInstMethodTableArg() || (TypeDesc)lookupFromType.DictionaryOwner != canonMethod.OwningType)) + continue; + + if (runtimeDep != null) { dependencies.AddRange(runtimeDep.InstantiateDependencies(factory, typeInst, methodInst)); diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs index a0dd7850ae8806..bcf69455c704cb 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs @@ -30,9 +30,9 @@ public sealed class RyuJitCompilation : Compilation private readonly int _parallelism; public InstructionSetSupport InstructionSetSupport { get; } + public bool CanInlineMethodWithRuntimeLookups { get; } - internal RyuJitCompilation( - DependencyAnalyzerBase dependencyGraph, + internal RyuJitCompilation(DependencyAnalyzerBase dependencyGraph, NodeFactory nodeFactory, IEnumerable roots, ILProvider ilProvider, @@ -44,7 +44,8 @@ internal RyuJitCompilation( MethodImportationErrorProvider errorProvider, ReadOnlyFieldPolicy readOnlyFieldPolicy, RyuJitCompilationOptions options, - int parallelism) + int parallelism, + bool canInlineMethodWithRuntimeLookups) : base(dependencyGraph, nodeFactory, roots, ilProvider, debugInformationProvider, inliningPolicy, logger) { _compilationOptions = options; @@ -57,6 +58,8 @@ internal RyuJitCompilation( _readOnlyFieldPolicy = readOnlyFieldPolicy; _parallelism = parallelism; + + CanInlineMethodWithRuntimeLookups = canInlineMethodWithRuntimeLookups; } public ProfileDataManager ProfileData => _profileDataManager; diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs index 37c2eba50195e0..cf04be048162b0 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs @@ -127,7 +127,7 @@ public override ICompilation ToCompilation() JitConfigProvider.Initialize(_context.Target, jitFlagBuilder.ToArray(), _ryujitOptions, _jitPath); DependencyAnalyzerBase graph = CreateDependencyGraph(factory, new ObjectNode.ObjectNodeComparer(CompilerComparer.Instance)); - return new RyuJitCompilation(graph, factory, _compilationRoots, _ilProvider, _debugInformationProvider, _logger, _inliningPolicy ?? _compilationGroup, _instructionSetSupport, _profileDataManager, _methodImportationErrorProvider, _readOnlyFieldPolicy, options, _parallelism); + return new RyuJitCompilation(graph, factory, _compilationRoots, _ilProvider, _debugInformationProvider, _logger, _inliningPolicy ?? _compilationGroup, _instructionSetSupport, _profileDataManager, _methodImportationErrorProvider, _readOnlyFieldPolicy, options, _parallelism, _canInlineMethodWithRuntimeLookups); } } } 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 17b58e616a5e52..42bd11d5e78bbc 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -248,22 +248,13 @@ private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object ent lookup.lookupKind.needsRuntimeLookup = true; lookup.runtimeLookup.signature = null; - // Are we inlining a method that requires a runtime lookup? - if (pResolvedToken.tokenContext != contextFromMethodBeingCompiled()) + // Are we allowed to inline methods with runtime lookups? + if (!_compilation.CanInlineMethodWithRuntimeLookups && pResolvedToken.tokenContext != contextFromMethodBeingCompiled()) { - // REPRO: if it's not the problematic method - give up. - if (MethodBeingCompiled.GetDisplayName() != "System.Buffers.SharedArrayPool`1<__Canon>.Rent(Int32)") - { - lookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_NOT_SUPPORTED; - return; - } - - Console.WriteLine("Root method: " + MethodBeingCompiled); - Console.WriteLine("Inlinee with a runtime lookup: " + callerHandle); - Console.WriteLine("Context kind: " + (CorInfoContextFlags)((nuint)pResolvedToken.tokenContext & (nuint)CorInfoContextFlags.CORINFO_CONTEXTFLAGS_MASK)); - Console.WriteLine("Token type: " + pResolvedToken.tokenType); - Console.WriteLine("-----"); + lookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_NOT_SUPPORTED; + return; } + GenericDictionaryLookup genericLookup = _compilation.ComputeGenericLookup(callerHandle, helperId, entity); if (genericLookup.UseHelper) @@ -1440,9 +1431,18 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO pResult->codePointerOrStubLookup.lookupKind.needsRuntimeLookup = true; pResult->codePointerOrStubLookup.lookupKind.runtimeLookupFlags = 0; pResult->codePointerOrStubLookup.runtimeLookup.indirections = CORINFO.USEHELPER; - pResult->codePointerOrStubLookup.lookupKind.runtimeLookupKind = GetGenericRuntimeLookupKind(HandleToObject(callerHandle)); - pResult->codePointerOrStubLookup.lookupKind.runtimeLookupFlags = (ushort)ReadyToRunHelperId.MethodEntry; - pResult->codePointerOrStubLookup.lookupKind.runtimeLookupArgs = (void*)ObjectToHandle(GetRuntimeDeterminedObjectForToken(ref pResolvedToken)); + + // Are we allowed to inline methods with runtime lookups? + if (!_compilation.CanInlineMethodWithRuntimeLookups && pResolvedToken.tokenContext != contextFromMethodBeingCompiled()) + { + pResult->codePointerOrStubLookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_NOT_SUPPORTED; + } + else + { + pResult->codePointerOrStubLookup.lookupKind.runtimeLookupKind = GetGenericRuntimeLookupKind(HandleToObject(callerHandle)); + pResult->codePointerOrStubLookup.lookupKind.runtimeLookupFlags = (ushort)ReadyToRunHelperId.MethodEntry; + pResult->codePointerOrStubLookup.lookupKind.runtimeLookupArgs = (void*)ObjectToHandle(GetRuntimeDeterminedObjectForToken(ref pResolvedToken)); + } } else { diff --git a/src/coreclr/tools/aot/ILCompiler/Program.cs b/src/coreclr/tools/aot/ILCompiler/Program.cs index 2cf88e34a65e0f..e8a61050e5b60c 100644 --- a/src/coreclr/tools/aot/ILCompiler/Program.cs +++ b/src/coreclr/tools/aot/ILCompiler/Program.cs @@ -564,6 +564,7 @@ void RunScanner() .UseDependencyTracking(trackingLevel) .UseCompilationRoots(compilationRoots) .UseOptimizationMode(_command.OptimizationMode) + .UseInliningForMethodsWithRuntimeLookups(_command.OptimizationMode != OptimizationMode.None && Get(_command.NoScanner)) .UseSecurityMitigationOptions(securityMitigationOptions) .UseDebugInfoProvider(debugInfoProvider) .UseDwarf5(Get(_command.UseDwarf5)) From 44186cb5ff0533ec86df383237ea991208815b62 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Tue, 12 Mar 2024 03:17:57 +0100 Subject: [PATCH 26/40] Update src/coreclr/jit/importer.cpp Co-authored-by: Jakob Botsch Nielsen --- 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 e1b78d72680b8b..1fa20e132b4c93 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -12807,8 +12807,7 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo) continue; case WellKnownArg::InstParam: { - InlArgInfo* ctxInfo = getAllocator(CMK_Unknown).allocate(1); - memset(ctxInfo, 0, sizeof(*ctxInfo)); + InlArgInfo* ctxInfo = new (this, CMK_Inlining) InlArgInfo {}; ctxInfo->arg = &arg; ctxInfo->argIsInvariant = true; ctxInfo->argIsLclVar = arg.GetNode()->OperIs(GT_LCL_VAR); From 4fb9a13ede2d43a6cdbcefa2ed8e3459cbf78ffc Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 12 Mar 2024 03:53:53 +0100 Subject: [PATCH 27/40] fix build --- src/coreclr/jit/importer.cpp | 2 +- .../Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 1fa20e132b4c93..e74c124f24d006 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -12807,7 +12807,7 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo) continue; case WellKnownArg::InstParam: { - InlArgInfo* ctxInfo = new (this, CMK_Inlining) InlArgInfo {}; + InlArgInfo* ctxInfo = new (this, CMK_Inlining) InlArgInfo{}; ctxInfo->arg = &arg; ctxInfo->argIsInvariant = true; ctxInfo->argIsLclVar = arg.GetNode()->OperIs(GT_LCL_VAR); diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs index d016c638557b50..5f5942ce8c0885 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs @@ -79,6 +79,7 @@ public override IEnumerable GetStaticDependencies(NodeFacto // ??? var canonMethod = Method.GetCanonMethodTarget(CanonicalFormKind.Specific); +#if !READYTORUN if (runtimeDep is ReadyToRunGenericLookupFromDictionaryNode lookupFromMethod && (!canonMethod.RequiresInstMethodDescArg() || lookupFromMethod.DictionaryOwner != canonMethod)) continue; @@ -86,7 +87,7 @@ public override IEnumerable GetStaticDependencies(NodeFacto if (runtimeDep is ReadyToRunGenericLookupFromTypeNode lookupFromType && (!canonMethod.RequiresInstMethodTableArg() || (TypeDesc)lookupFromType.DictionaryOwner != canonMethod.OwningType)) continue; - +#endif if (runtimeDep != null) { From 893172c143fb2b0c146d71821c166438a4acec84 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 12 Mar 2024 04:12:36 +0100 Subject: [PATCH 28/40] Fix build --- .../ShadowConcreteMethodNode.cs | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs index 5f5942ce8c0885..3a96c5edb38e50 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs @@ -75,23 +75,19 @@ public override IEnumerable GetStaticDependencies(NodeFacto foreach (DependencyListEntry canonDep in staticDependencies) { var runtimeDep = canonDep.Node as INodeWithRuntimeDeterminedDependencies; - - // ??? - var canonMethod = Method.GetCanonMethodTarget(CanonicalFormKind.Specific); - -#if !READYTORUN - if (runtimeDep is ReadyToRunGenericLookupFromDictionaryNode lookupFromMethod - && (!canonMethod.RequiresInstMethodDescArg() || lookupFromMethod.DictionaryOwner != canonMethod)) - continue; - - if (runtimeDep is ReadyToRunGenericLookupFromTypeNode lookupFromType - && (!canonMethod.RequiresInstMethodTableArg() || (TypeDesc)lookupFromType.DictionaryOwner != canonMethod.OwningType)) - continue; -#endif - if (runtimeDep != null) { dependencies.AddRange(runtimeDep.InstantiateDependencies(factory, typeInst, methodInst)); +#if !READYTORUN + MethodDesc canonMethod = Method.GetCanonMethodTarget(CanonicalFormKind.Specific); + if (runtimeDep is ReadyToRunGenericLookupFromDictionaryNode lookupFromMethod + && (!canonMethod.RequiresInstMethodDescArg() || lookupFromMethod.DictionaryOwner != canonMethod)) + continue; + + if (runtimeDep is ReadyToRunGenericLookupFromTypeNode lookupFromType + && (!canonMethod.RequiresInstMethodTableArg() || (TypeDesc)lookupFromType.DictionaryOwner != canonMethod.OwningType)) + continue; +#endif } } } From a4a1aa51f84c7f42278b6b6e89c80e4b5ef6dc4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Tue, 12 Mar 2024 05:16:39 +0100 Subject: [PATCH 29/40] Revert "Fix build" This reverts commit 893172c143fb2b0c146d71821c166438a4acec84. --- .../ShadowConcreteMethodNode.cs | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs index 3a96c5edb38e50..5f5942ce8c0885 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs @@ -75,19 +75,23 @@ public override IEnumerable GetStaticDependencies(NodeFacto foreach (DependencyListEntry canonDep in staticDependencies) { var runtimeDep = canonDep.Node as INodeWithRuntimeDeterminedDependencies; + + // ??? + var canonMethod = Method.GetCanonMethodTarget(CanonicalFormKind.Specific); + +#if !READYTORUN + if (runtimeDep is ReadyToRunGenericLookupFromDictionaryNode lookupFromMethod + && (!canonMethod.RequiresInstMethodDescArg() || lookupFromMethod.DictionaryOwner != canonMethod)) + continue; + + if (runtimeDep is ReadyToRunGenericLookupFromTypeNode lookupFromType + && (!canonMethod.RequiresInstMethodTableArg() || (TypeDesc)lookupFromType.DictionaryOwner != canonMethod.OwningType)) + continue; +#endif + if (runtimeDep != null) { dependencies.AddRange(runtimeDep.InstantiateDependencies(factory, typeInst, methodInst)); -#if !READYTORUN - MethodDesc canonMethod = Method.GetCanonMethodTarget(CanonicalFormKind.Specific); - if (runtimeDep is ReadyToRunGenericLookupFromDictionaryNode lookupFromMethod - && (!canonMethod.RequiresInstMethodDescArg() || lookupFromMethod.DictionaryOwner != canonMethod)) - continue; - - if (runtimeDep is ReadyToRunGenericLookupFromTypeNode lookupFromType - && (!canonMethod.RequiresInstMethodTableArg() || (TypeDesc)lookupFromType.DictionaryOwner != canonMethod.OwningType)) - continue; -#endif } } } From 18c03d01e499b4b19a1f4a4ed908c2e744df5997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Tue, 12 Mar 2024 05:18:09 +0100 Subject: [PATCH 30/40] Revert "fix build" --- .../Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs index 5f5942ce8c0885..d016c638557b50 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs @@ -79,7 +79,6 @@ public override IEnumerable GetStaticDependencies(NodeFacto // ??? var canonMethod = Method.GetCanonMethodTarget(CanonicalFormKind.Specific); -#if !READYTORUN if (runtimeDep is ReadyToRunGenericLookupFromDictionaryNode lookupFromMethod && (!canonMethod.RequiresInstMethodDescArg() || lookupFromMethod.DictionaryOwner != canonMethod)) continue; @@ -87,7 +86,7 @@ public override IEnumerable GetStaticDependencies(NodeFacto if (runtimeDep is ReadyToRunGenericLookupFromTypeNode lookupFromType && (!canonMethod.RequiresInstMethodTableArg() || (TypeDesc)lookupFromType.DictionaryOwner != canonMethod.OwningType)) continue; -#endif + if (runtimeDep != null) { From 32828c4b01a1b3b33fdb2bf95aad4c6c0960f991 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Tue, 12 Mar 2024 05:19:00 +0100 Subject: [PATCH 31/40] Revert "Like this (it currently fails)" This reverts commit 478ef857655d78b3a99bb861a6522954f06c34e8. --- .../Common/Compiler/CompilationBuilder.cs | 7 ---- .../ShadowConcreteMethodNode.cs | 13 ------- .../Compiler/RyuJitCompilation.cs | 9 ++--- .../Compiler/RyuJitCompilationBuilder.cs | 2 +- .../JitInterface/CorInfoImpl.RyuJit.cs | 34 +++++++++---------- src/coreclr/tools/aot/ILCompiler/Program.cs | 1 - 6 files changed, 21 insertions(+), 45 deletions(-) diff --git a/src/coreclr/tools/Common/Compiler/CompilationBuilder.cs b/src/coreclr/tools/Common/Compiler/CompilationBuilder.cs index e7ced3418e3c81..5357e2f68234ba 100644 --- a/src/coreclr/tools/Common/Compiler/CompilationBuilder.cs +++ b/src/coreclr/tools/Common/Compiler/CompilationBuilder.cs @@ -23,7 +23,6 @@ public abstract partial class CompilationBuilder private DependencyTrackingLevel _dependencyTrackingLevel = DependencyTrackingLevel.None; protected IEnumerable _compilationRoots = Array.Empty(); protected OptimizationMode _optimizationMode = OptimizationMode.None; - protected bool _canInlineMethodWithRuntimeLookups; protected int _parallelism = -1; protected bool _resilient; @@ -74,12 +73,6 @@ public CompilationBuilder UseOptimizationMode(OptimizationMode mode) return this; } - public CompilationBuilder UseInliningForMethodsWithRuntimeLookups(bool enable) - { - _canInlineMethodWithRuntimeLookups = enable; - return this; - } - public CompilationBuilder UseResilience(bool resilient) { _resilient = resilient; diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs index d016c638557b50..140a97f70924ee 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs @@ -75,19 +75,6 @@ public override IEnumerable GetStaticDependencies(NodeFacto foreach (DependencyListEntry canonDep in staticDependencies) { var runtimeDep = canonDep.Node as INodeWithRuntimeDeterminedDependencies; - - // ??? - var canonMethod = Method.GetCanonMethodTarget(CanonicalFormKind.Specific); - - if (runtimeDep is ReadyToRunGenericLookupFromDictionaryNode lookupFromMethod - && (!canonMethod.RequiresInstMethodDescArg() || lookupFromMethod.DictionaryOwner != canonMethod)) - continue; - - if (runtimeDep is ReadyToRunGenericLookupFromTypeNode lookupFromType - && (!canonMethod.RequiresInstMethodTableArg() || (TypeDesc)lookupFromType.DictionaryOwner != canonMethod.OwningType)) - continue; - - if (runtimeDep != null) { dependencies.AddRange(runtimeDep.InstantiateDependencies(factory, typeInst, methodInst)); diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs index bcf69455c704cb..a0dd7850ae8806 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs @@ -30,9 +30,9 @@ public sealed class RyuJitCompilation : Compilation private readonly int _parallelism; public InstructionSetSupport InstructionSetSupport { get; } - public bool CanInlineMethodWithRuntimeLookups { get; } - internal RyuJitCompilation(DependencyAnalyzerBase dependencyGraph, + internal RyuJitCompilation( + DependencyAnalyzerBase dependencyGraph, NodeFactory nodeFactory, IEnumerable roots, ILProvider ilProvider, @@ -44,8 +44,7 @@ internal RyuJitCompilation(DependencyAnalyzerBase dependencyGraph, MethodImportationErrorProvider errorProvider, ReadOnlyFieldPolicy readOnlyFieldPolicy, RyuJitCompilationOptions options, - int parallelism, - bool canInlineMethodWithRuntimeLookups) + int parallelism) : base(dependencyGraph, nodeFactory, roots, ilProvider, debugInformationProvider, inliningPolicy, logger) { _compilationOptions = options; @@ -58,8 +57,6 @@ internal RyuJitCompilation(DependencyAnalyzerBase dependencyGraph, _readOnlyFieldPolicy = readOnlyFieldPolicy; _parallelism = parallelism; - - CanInlineMethodWithRuntimeLookups = canInlineMethodWithRuntimeLookups; } public ProfileDataManager ProfileData => _profileDataManager; diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs index cf04be048162b0..37c2eba50195e0 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs @@ -127,7 +127,7 @@ public override ICompilation ToCompilation() JitConfigProvider.Initialize(_context.Target, jitFlagBuilder.ToArray(), _ryujitOptions, _jitPath); DependencyAnalyzerBase graph = CreateDependencyGraph(factory, new ObjectNode.ObjectNodeComparer(CompilerComparer.Instance)); - return new RyuJitCompilation(graph, factory, _compilationRoots, _ilProvider, _debugInformationProvider, _logger, _inliningPolicy ?? _compilationGroup, _instructionSetSupport, _profileDataManager, _methodImportationErrorProvider, _readOnlyFieldPolicy, options, _parallelism, _canInlineMethodWithRuntimeLookups); + return new RyuJitCompilation(graph, factory, _compilationRoots, _ilProvider, _debugInformationProvider, _logger, _inliningPolicy ?? _compilationGroup, _instructionSetSupport, _profileDataManager, _methodImportationErrorProvider, _readOnlyFieldPolicy, options, _parallelism); } } } 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 42bd11d5e78bbc..17b58e616a5e52 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -248,13 +248,22 @@ private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object ent lookup.lookupKind.needsRuntimeLookup = true; lookup.runtimeLookup.signature = null; - // Are we allowed to inline methods with runtime lookups? - if (!_compilation.CanInlineMethodWithRuntimeLookups && pResolvedToken.tokenContext != contextFromMethodBeingCompiled()) + // Are we inlining a method that requires a runtime lookup? + if (pResolvedToken.tokenContext != contextFromMethodBeingCompiled()) { - lookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_NOT_SUPPORTED; - return; - } + // REPRO: if it's not the problematic method - give up. + if (MethodBeingCompiled.GetDisplayName() != "System.Buffers.SharedArrayPool`1<__Canon>.Rent(Int32)") + { + lookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_NOT_SUPPORTED; + return; + } + Console.WriteLine("Root method: " + MethodBeingCompiled); + Console.WriteLine("Inlinee with a runtime lookup: " + callerHandle); + Console.WriteLine("Context kind: " + (CorInfoContextFlags)((nuint)pResolvedToken.tokenContext & (nuint)CorInfoContextFlags.CORINFO_CONTEXTFLAGS_MASK)); + Console.WriteLine("Token type: " + pResolvedToken.tokenType); + Console.WriteLine("-----"); + } GenericDictionaryLookup genericLookup = _compilation.ComputeGenericLookup(callerHandle, helperId, entity); if (genericLookup.UseHelper) @@ -1431,18 +1440,9 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO pResult->codePointerOrStubLookup.lookupKind.needsRuntimeLookup = true; pResult->codePointerOrStubLookup.lookupKind.runtimeLookupFlags = 0; pResult->codePointerOrStubLookup.runtimeLookup.indirections = CORINFO.USEHELPER; - - // Are we allowed to inline methods with runtime lookups? - if (!_compilation.CanInlineMethodWithRuntimeLookups && pResolvedToken.tokenContext != contextFromMethodBeingCompiled()) - { - pResult->codePointerOrStubLookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_NOT_SUPPORTED; - } - else - { - pResult->codePointerOrStubLookup.lookupKind.runtimeLookupKind = GetGenericRuntimeLookupKind(HandleToObject(callerHandle)); - pResult->codePointerOrStubLookup.lookupKind.runtimeLookupFlags = (ushort)ReadyToRunHelperId.MethodEntry; - pResult->codePointerOrStubLookup.lookupKind.runtimeLookupArgs = (void*)ObjectToHandle(GetRuntimeDeterminedObjectForToken(ref pResolvedToken)); - } + pResult->codePointerOrStubLookup.lookupKind.runtimeLookupKind = GetGenericRuntimeLookupKind(HandleToObject(callerHandle)); + pResult->codePointerOrStubLookup.lookupKind.runtimeLookupFlags = (ushort)ReadyToRunHelperId.MethodEntry; + pResult->codePointerOrStubLookup.lookupKind.runtimeLookupArgs = (void*)ObjectToHandle(GetRuntimeDeterminedObjectForToken(ref pResolvedToken)); } else { diff --git a/src/coreclr/tools/aot/ILCompiler/Program.cs b/src/coreclr/tools/aot/ILCompiler/Program.cs index e8a61050e5b60c..2cf88e34a65e0f 100644 --- a/src/coreclr/tools/aot/ILCompiler/Program.cs +++ b/src/coreclr/tools/aot/ILCompiler/Program.cs @@ -564,7 +564,6 @@ void RunScanner() .UseDependencyTracking(trackingLevel) .UseCompilationRoots(compilationRoots) .UseOptimizationMode(_command.OptimizationMode) - .UseInliningForMethodsWithRuntimeLookups(_command.OptimizationMode != OptimizationMode.None && Get(_command.NoScanner)) .UseSecurityMitigationOptions(securityMitigationOptions) .UseDebugInfoProvider(debugInfoProvider) .UseDwarf5(Get(_command.UseDwarf5)) From e9d7e87e66d866b0aaf629460f5effd7d24a398e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Tue, 12 Mar 2024 05:19:16 +0100 Subject: [PATCH 32/40] Revert "fix repro" This reverts commit 410ce12d0dd576623e71fb3563793645fa94adeb. --- .../aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 17b58e616a5e52..33d2c138a61589 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -252,7 +252,8 @@ private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object ent if (pResolvedToken.tokenContext != contextFromMethodBeingCompiled()) { // REPRO: if it's not the problematic method - give up. - if (MethodBeingCompiled.GetDisplayName() != "System.Buffers.SharedArrayPool`1<__Canon>.Rent(Int32)") + if (MethodBeingCompiled.GetDisplayName() != "System.Buffers.SharedArrayPool`1<__Canon>.Rent(Int32)" || + pResolvedToken.tokenType != CorInfoTokenKind.CORINFO_TOKENKIND_Method) { lookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_NOT_SUPPORTED; return; From 874c339ce8510cce4d56fed0ab65dbec8da62335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Tue, 12 Mar 2024 05:19:24 +0100 Subject: [PATCH 33/40] Revert "repro" This reverts commit 550f8ffa20e20f89edae5b02d7481c5f603bad45. --- .../JitInterface/CorInfoImpl.RyuJit.cs | 17 ----------------- 1 file changed, 17 deletions(-) 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 33d2c138a61589..0bac8f1a69e85d 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -248,23 +248,6 @@ private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object ent lookup.lookupKind.needsRuntimeLookup = true; lookup.runtimeLookup.signature = null; - // Are we inlining a method that requires a runtime lookup? - if (pResolvedToken.tokenContext != contextFromMethodBeingCompiled()) - { - // REPRO: if it's not the problematic method - give up. - if (MethodBeingCompiled.GetDisplayName() != "System.Buffers.SharedArrayPool`1<__Canon>.Rent(Int32)" || - pResolvedToken.tokenType != CorInfoTokenKind.CORINFO_TOKENKIND_Method) - { - lookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_NOT_SUPPORTED; - return; - } - - Console.WriteLine("Root method: " + MethodBeingCompiled); - Console.WriteLine("Inlinee with a runtime lookup: " + callerHandle); - Console.WriteLine("Context kind: " + (CorInfoContextFlags)((nuint)pResolvedToken.tokenContext & (nuint)CorInfoContextFlags.CORINFO_CONTEXTFLAGS_MASK)); - Console.WriteLine("Token type: " + pResolvedToken.tokenType); - Console.WriteLine("-----"); - } GenericDictionaryLookup genericLookup = _compilation.ComputeGenericLookup(callerHandle, helperId, entity); if (genericLookup.UseHelper) From 0f45539a53618ceb13d4169a4fa6674250a568d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Tue, 12 Mar 2024 07:22:04 +0100 Subject: [PATCH 34/40] Better fix --- .../JitInterface/CorInfoImpl.RyuJit.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) 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 0bac8f1a69e85d..1e72961928078d 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -252,6 +252,17 @@ private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object ent if (genericLookup.UseHelper) { + // If this is from a different context and we need a ReadyToRun helper, abort. + // The ReadyToRun helpers need to be able to declare the dependencies and we can't + // currently do it for an inline. This is not a big issue because ReadyToRun helpers + // in optimized code only happen in special build configurations (such as + // `-O --noscan` or multimodule build). + if (pResolvedToken.tokenContext != contextFromMethodBeingCompiled()) + { + lookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_NOT_SUPPORTED; + return; + } + lookup.runtimeLookup.indirections = CORINFO.USEHELPER; lookup.lookupKind.runtimeLookupFlags = (ushort)genericLookup.HelperId; lookup.lookupKind.runtimeLookupArgs = (void*)ObjectToHandle(genericLookup.HelperObject); From 0fb02aaa2c93b847e067a78297c4bb00d14d7e79 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 12 Mar 2024 16:46:03 +0100 Subject: [PATCH 35/40] Address Jakob's feedback --- src/coreclr/jit/compiler.h | 1 + src/coreclr/jit/fginline.cpp | 363 +++++++++++++++++------------------ src/coreclr/jit/importer.cpp | 18 +- 3 files changed, 190 insertions(+), 192 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index ced464500a6a01..54491dc3ef66db 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -6629,6 +6629,7 @@ class Compiler void fgInvokeInlineeCompiler(GenTreeCall* call, InlineResult* result, InlineContext** createdContext); void fgInsertInlineeBlocks(InlineInfo* pInlineInfo); + void fgInsertInlineeArgument(const InlArgInfo& argInfo, BasicBlock* block, Statement** afterStmt, Statement** newStmt, const DebugInfo& callDI); Statement* fgInlinePrependStatements(InlineInfo* inlineInfo); void fgInlineAppendStatements(InlineInfo* inlineInfo, BasicBlock* block, Statement* stmt); diff --git a/src/coreclr/jit/fginline.cpp b/src/coreclr/jit/fginline.cpp index 2885307e94b5c6..b72b99228fbc70 100644 --- a/src/coreclr/jit/fginline.cpp +++ b/src/coreclr/jit/fginline.cpp @@ -1665,6 +1665,175 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo) iciStmt->SetRootNode(gtNewNothingNode()); } +//------------------------------------------------------------------------ +// fgInsertInlineeArgument: wire up the given argument from the callsite with the inlinee +// +// Arguments: +// argInfo - information about the argument +// block - block to insert the argument into +// afterStmt - statement to insert the argument after +// newStmt - updated with the new statement +// callDI - debug info for the call +// +void Compiler::fgInsertInlineeArgument( + const InlArgInfo& argInfo, BasicBlock* block, Statement** afterStmt, Statement** newStmt, const DebugInfo& callDI) +{ + const bool argIsSingleDef = !argInfo.argHasLdargaOp && !argInfo.argHasStargOp; + CallArg* arg = argInfo.arg; + GenTree* argNode = arg->GetNode(); + + assert(!argNode->OperIs(GT_RET_EXPR)); + + if (argInfo.argHasTmp) + { + noway_assert(argInfo.argIsUsed); + + /* argBashTmpNode is non-NULL iff the argument's value was + referenced exactly once by the original IL. This offers an + opportunity to avoid an intermediate temp and just insert + the original argument tree. + + However, if the temp node has been cloned somewhere while + importing (e.g. when handling isinst or dup), or if the IL + took the address of the argument, then argBashTmpNode will + be set (because the value was only explicitly retrieved + once) but the optimization cannot be applied. + */ + + GenTree* argSingleUseNode = argInfo.argBashTmpNode; + + if ((argSingleUseNode != nullptr) && !(argSingleUseNode->gtFlags & GTF_VAR_MOREUSES) && argIsSingleDef) + { + // Change the temp in-place to the actual argument. + // We currently do not support this for struct arguments, so it must not be a GT_BLK. + assert(argNode->gtOper != GT_BLK); + argSingleUseNode->ReplaceWith(argNode, this); + return; + } + else + { + // We're going to assign the argument value to the temp we use for it in the inline body. + GenTree* store = gtNewTempStore(argInfo.argTmpNum, argNode); + + *newStmt = gtNewStmt(store, callDI); + fgInsertStmtAfter(block, *afterStmt, *newStmt); + *afterStmt = *newStmt; + DISPSTMT(*afterStmt); + } + } + else if (argInfo.argIsByRefToStructLocal) + { + // Do nothing. Arg was directly substituted as we read + // the inlinee. + } + else + { + // The argument is either not used or a const or lcl var + noway_assert(!argInfo.argIsUsed || argInfo.argIsInvariant || argInfo.argIsLclVar); + noway_assert((argInfo.argIsLclVar == 0) == + (argNode->gtOper != GT_LCL_VAR || (argNode->gtFlags & GTF_GLOB_REF))); + + // If the argument has side effects, append it + if (argInfo.argHasSideEff) + { + noway_assert(argInfo.argIsUsed == false); + *newStmt = nullptr; + bool append = true; + + if (argNode->gtOper == GT_BLK || argNode->gtOper == GT_MKREFANY) + { + // Don't put GT_BLK node under a GT_COMMA. + // Codegen can't deal with it. + // Just hang the address here in case there are side-effect. + *newStmt = gtNewStmt(gtUnusedValNode(argNode->AsOp()->gtOp1), callDI); + } + else + { + // In some special cases, unused args with side effects can + // trigger further changes. + // + // (1) If the arg is a static field access and the field access + // was produced by a call to EqualityComparer.get_Default, the + // helper call to ensure the field has a value can be suppressed. + // This helper call is marked as a "Special DCE" helper during + // importation, over in fgGetStaticsCCtorHelper. + // + // (2) NYI. If we find that the actual arg expression + // has no side effects, we can skip appending all + // together. This will help jit TP a bit. + // + assert(!argNode->OperIs(GT_RET_EXPR)); + + // For case (1) + // + // Look for the following tree shapes + // prejit: (IND (ADD (CONST, CALL(special dce helper...)))) + // jit : (COMMA (CALL(special dce helper...), (FIELD ...))) + if (argNode->gtOper == GT_COMMA) + { + // Look for (COMMA (CALL(special dce helper...), (FIELD ...))) + GenTree* op1 = argNode->AsOp()->gtOp1; + GenTree* op2 = argNode->AsOp()->gtOp2; + if (op1->IsCall() && ((op1->AsCall()->gtCallMoreFlags & GTF_CALL_M_HELPER_SPECIAL_DCE) != 0) && + op2->OperIs(GT_IND) && op2->gtGetOp1()->IsIconHandle() && ((op2->gtFlags & GTF_EXCEPT) == 0)) + { + JITDUMP("\nPerforming special dce on unused arg [%06u]:" + " actual arg [%06u] helper call [%06u]\n", + argNode->gtTreeID, argNode->gtTreeID, op1->gtTreeID); + // Drop the whole tree + append = false; + } + } + else if (argNode->gtOper == GT_IND) + { + // Look for (IND (ADD (CONST, CALL(special dce helper...)))) + GenTree* addr = argNode->AsOp()->gtOp1; + + if (addr->gtOper == GT_ADD) + { + GenTree* op1 = addr->AsOp()->gtOp1; + GenTree* op2 = addr->AsOp()->gtOp2; + if (op1->IsCall() && ((op1->AsCall()->gtCallMoreFlags & GTF_CALL_M_HELPER_SPECIAL_DCE) != 0) && + op2->IsCnsIntOrI()) + { + // Drop the whole tree + JITDUMP("\nPerforming special dce on unused arg [%06u]:" + " actual arg [%06u] helper call [%06u]\n", + argNode->gtTreeID, argNode->gtTreeID, op1->gtTreeID); + append = false; + } + } + } + } + + if (!append) + { + assert(*newStmt == nullptr); + JITDUMP("Arg tree side effects were discardable, not appending anything for arg\n"); + } + else + { + // If we don't have something custom to append, + // just append the arg node as an unused value. + if (*newStmt == nullptr) + { + *newStmt = gtNewStmt(gtUnusedValNode(argNode), callDI); + } + + fgInsertStmtAfter(block, *afterStmt, *newStmt); + *afterStmt = *newStmt; + DISPSTMT(*afterStmt); + } + } + else if (argNode->IsBoxedValue()) + { + // Try to clean up any unnecessary boxing side effects + // since the box itself will be ignored. + gtTryRemoveBoxUpstreamEffects(argNode); + } + } +} + //------------------------------------------------------------------------ // fgInlinePrependStatements: prepend statements needed to match up // caller and inlined callee @@ -1686,28 +1855,18 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo) // Newly added statements are placed just after the original call // and are are given the same inline context as the call any calls // added here will appear to have been part of the immediate caller. - +// Statement* Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo) { BasicBlock* block = inlineInfo->iciBlock; Statement* callStmt = inlineInfo->iciStmt; const DebugInfo& callDI = callStmt->GetDebugInfo(); - Statement* postStmt = callStmt->GetNextStmt(); Statement* afterStmt = callStmt; // afterStmt is the place where the new statements should be inserted after. Statement* newStmt = nullptr; GenTreeCall* call = inlineInfo->iciCall->AsCall(); noway_assert(call->gtOper == GT_CALL); -#ifdef DEBUG - if (0 && verbose) - { - printf("\nfgInlinePrependStatements for iciCall= "); - printTreeID(call); - printf(":\n"); - } -#endif - // Prepend statements for any initialization / side effects InlArgInfo* inlArgInfo = inlineInfo->inlArgInfo; @@ -1737,183 +1896,19 @@ Statement* Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo) } } - /* Treat arguments that had to be assigned to temps */ - if (inlineInfo->argCnt) + // Append the InstParam + if (inlineInfo->inlInstParamArgInfo != nullptr) { + fgInsertInlineeArgument(*inlineInfo->inlInstParamArgInfo, block, &afterStmt, &newStmt, callDI); + } -#ifdef DEBUG - if (verbose) - { - printf("\nArguments setup:\n"); - } -#endif // DEBUG - + // Treat arguments that had to be assigned to temps + if (inlineInfo->argCnt) + { + JITDUMP("\nArguments setup:\n"); for (unsigned argNum = 0; argNum < inlineInfo->argCnt; argNum++) { - const InlArgInfo& argInfo = inlArgInfo[argNum]; - const bool argIsSingleDef = !argInfo.argHasLdargaOp && !argInfo.argHasStargOp; - CallArg* arg = argInfo.arg; - GenTree* argNode = arg->GetNode(); - - assert(!argNode->OperIs(GT_RET_EXPR)); - - if (argInfo.argHasTmp) - { - noway_assert(argInfo.argIsUsed); - - /* argBashTmpNode is non-NULL iff the argument's value was - referenced exactly once by the original IL. This offers an - opportunity to avoid an intermediate temp and just insert - the original argument tree. - - However, if the temp node has been cloned somewhere while - importing (e.g. when handling isinst or dup), or if the IL - took the address of the argument, then argBashTmpNode will - be set (because the value was only explicitly retrieved - once) but the optimization cannot be applied. - */ - - GenTree* argSingleUseNode = argInfo.argBashTmpNode; - - if ((argSingleUseNode != nullptr) && !(argSingleUseNode->gtFlags & GTF_VAR_MOREUSES) && argIsSingleDef) - { - // Change the temp in-place to the actual argument. - // We currently do not support this for struct arguments, so it must not be a GT_BLK. - assert(argNode->gtOper != GT_BLK); - argSingleUseNode->ReplaceWith(argNode, this); - continue; - } - else - { - // We're going to assign the argument value to the temp we use for it in the inline body. - GenTree* store = gtNewTempStore(argInfo.argTmpNum, argNode); - - newStmt = gtNewStmt(store, callDI); - fgInsertStmtAfter(block, afterStmt, newStmt); - afterStmt = newStmt; - - DISPSTMT(afterStmt); - } - } - else if (argInfo.argIsByRefToStructLocal) - { - // Do nothing. Arg was directly substituted as we read - // the inlinee. - } - else - { - // The argument is either not used or a const or lcl var - noway_assert(!argInfo.argIsUsed || argInfo.argIsInvariant || argInfo.argIsLclVar); - noway_assert((argInfo.argIsLclVar == 0) == - (argNode->gtOper != GT_LCL_VAR || (argNode->gtFlags & GTF_GLOB_REF))); - - // If the argument has side effects, append it - if (argInfo.argHasSideEff) - { - noway_assert(argInfo.argIsUsed == false); - newStmt = nullptr; - bool append = true; - - if (argNode->gtOper == GT_BLK || argNode->gtOper == GT_MKREFANY) - { - // Don't put GT_BLK node under a GT_COMMA. - // Codegen can't deal with it. - // Just hang the address here in case there are side-effect. - newStmt = gtNewStmt(gtUnusedValNode(argNode->AsOp()->gtOp1), callDI); - } - else - { - // In some special cases, unused args with side effects can - // trigger further changes. - // - // (1) If the arg is a static field access and the field access - // was produced by a call to EqualityComparer.get_Default, the - // helper call to ensure the field has a value can be suppressed. - // This helper call is marked as a "Special DCE" helper during - // importation, over in fgGetStaticsCCtorHelper. - // - // (2) NYI. If we find that the actual arg expression - // has no side effects, we can skip appending all - // together. This will help jit TP a bit. - // - assert(!argNode->OperIs(GT_RET_EXPR)); - - // For case (1) - // - // Look for the following tree shapes - // prejit: (IND (ADD (CONST, CALL(special dce helper...)))) - // jit : (COMMA (CALL(special dce helper...), (FIELD ...))) - if (argNode->gtOper == GT_COMMA) - { - // Look for (COMMA (CALL(special dce helper...), (FIELD ...))) - GenTree* op1 = argNode->AsOp()->gtOp1; - GenTree* op2 = argNode->AsOp()->gtOp2; - if (op1->IsCall() && - ((op1->AsCall()->gtCallMoreFlags & GTF_CALL_M_HELPER_SPECIAL_DCE) != 0) && - op2->OperIs(GT_IND) && op2->gtGetOp1()->IsIconHandle() && - ((op2->gtFlags & GTF_EXCEPT) == 0)) - { - JITDUMP("\nPerforming special dce on unused arg [%06u]:" - " actual arg [%06u] helper call [%06u]\n", - argNode->gtTreeID, argNode->gtTreeID, op1->gtTreeID); - // Drop the whole tree - append = false; - } - } - else if (argNode->gtOper == GT_IND) - { - // Look for (IND (ADD (CONST, CALL(special dce helper...)))) - GenTree* addr = argNode->AsOp()->gtOp1; - - if (addr->gtOper == GT_ADD) - { - GenTree* op1 = addr->AsOp()->gtOp1; - GenTree* op2 = addr->AsOp()->gtOp2; - if (op1->IsCall() && - ((op1->AsCall()->gtCallMoreFlags & GTF_CALL_M_HELPER_SPECIAL_DCE) != 0) && - op2->IsCnsIntOrI()) - { - // Drop the whole tree - JITDUMP("\nPerforming special dce on unused arg [%06u]:" - " actual arg [%06u] helper call [%06u]\n", - argNode->gtTreeID, argNode->gtTreeID, op1->gtTreeID); - append = false; - } - } - } - } - - if (!append) - { - assert(newStmt == nullptr); - JITDUMP("Arg tree side effects were discardable, not appending anything for arg\n"); - } - else - { - // If we don't have something custom to append, - // just append the arg node as an unused value. - if (newStmt == nullptr) - { - newStmt = gtNewStmt(gtUnusedValNode(argNode), callDI); - } - - fgInsertStmtAfter(block, afterStmt, newStmt); - afterStmt = newStmt; -#ifdef DEBUG - if (verbose) - { - gtDispStmt(afterStmt); - } -#endif // DEBUG - } - } - else if (argNode->IsBoxedValue()) - { - // Try to clean up any unnecessary boxing side effects - // since the box itself will be ignored. - gtTryRemoveBoxUpstreamEffects(argNode); - } - } + fgInsertInlineeArgument(inlArgInfo[argNum], block, &afterStmt, &newStmt, callDI); } } diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index e74c124f24d006..19d40b1f2bad63 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1558,10 +1558,11 @@ GenTree* Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind) // Always use generic context from the callsite if we're inlining and it's available. if (compIsForInlining() && (impInlineInfo->inlInstParamArgInfo != nullptr)) { + // Create a dummy lclInfo node, we know that nobody's going to do stloc or take address + // of the generic context, so we don't need to scan IL for it. InlLclVarInfo lclInfo = {}; lclInfo.lclTypeInfo = TYP_I_IMPL; - - ctxTree = impInlineFetchArg(*impInlineInfo->inlInstParamArgInfo, lclInfo); + ctxTree = impInlineFetchArg(*impInlineInfo->inlInstParamArgInfo, lclInfo); assert(ctxTree != nullptr); assert(ctxTree->TypeIs(TYP_I_IMPL)); // We don't need to worry about GTF_VAR_CONTEXT here, it should be set on the callsite anyway. @@ -1668,6 +1669,7 @@ GenTree* Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken GenTree* slotPtrTree = ctxTree; GenTree* indOffTree = nullptr; + // TODO-CQ: consider relaxing where it's safe to do so const bool ctxTreeIsInvariant = !compIsForInlining(); // Applied repeated indirections @@ -12807,13 +12809,13 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo) continue; case WellKnownArg::InstParam: { - InlArgInfo* ctxInfo = new (this, CMK_Inlining) InlArgInfo{}; - ctxInfo->arg = &arg; - ctxInfo->argIsInvariant = true; - ctxInfo->argIsLclVar = arg.GetNode()->OperIs(GT_LCL_VAR); - pInlineInfo->inlInstParamArgInfo = ctxInfo; + InlArgInfo* ctxInfo = new (this, CMK_Inlining) InlArgInfo{}; + ctxInfo->arg = &arg; + ctxInfo->argTmpNum = BAD_VAR_NUM; + ctxInfo->argIsLclVar = arg.GetNode()->OperIs(GT_LCL_VAR); + ctxInfo->argIsInvariant = arg.GetNode()->IsInvariant(); // TODO-CQ: consider other trivial cases - // This one does not appear in the table of inline arg info too. + pInlineInfo->inlInstParamArgInfo = ctxInfo; continue; } default: From d63513362beb19b9e053936f3578a50992c5da9f Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 12 Mar 2024 17:16:00 +0100 Subject: [PATCH 36/40] conservative version --- src/coreclr/jit/importer.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 19d40b1f2bad63..7cc0cb87061b1e 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -12813,8 +12813,16 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo) ctxInfo->arg = &arg; ctxInfo->argTmpNum = BAD_VAR_NUM; ctxInfo->argIsLclVar = arg.GetNode()->OperIs(GT_LCL_VAR); - ctxInfo->argIsInvariant = arg.GetNode()->IsInvariant(); // TODO-CQ: consider other trivial cases - + if (arg.GetNode()->IsCnsIntOrI()) + { + ctxInfo->argIsInvariant = true; + } + else + { + // Conservative approach + ctxInfo->argHasSideEff = true; + ctxInfo->argHasGlobRef = true; + } pInlineInfo->inlInstParamArgInfo = ctxInfo; continue; } From 10492e36ed779f74cc65fec4018cfed47db0f8b9 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 12 Mar 2024 17:22:11 +0100 Subject: [PATCH 37/40] make formatter happy --- src/coreclr/jit/importer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 7cc0cb87061b1e..c680ee6a062501 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -12809,10 +12809,10 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo) continue; case WellKnownArg::InstParam: { - InlArgInfo* ctxInfo = new (this, CMK_Inlining) InlArgInfo{}; - ctxInfo->arg = &arg; - ctxInfo->argTmpNum = BAD_VAR_NUM; - ctxInfo->argIsLclVar = arg.GetNode()->OperIs(GT_LCL_VAR); + InlArgInfo* ctxInfo = new (this, CMK_Inlining) InlArgInfo{}; + ctxInfo->arg = &arg; + ctxInfo->argTmpNum = BAD_VAR_NUM; + ctxInfo->argIsLclVar = arg.GetNode()->OperIs(GT_LCL_VAR); if (arg.GetNode()->IsCnsIntOrI()) { ctxInfo->argIsInvariant = true; From ad38ae11609cfa4032faefc5936b88e80fbfb91f Mon Sep 17 00:00:00 2001 From: EgorBo Date: Wed, 13 Mar 2024 14:25:40 +0100 Subject: [PATCH 38/40] use GetMethod --- src/coreclr/vm/jitinterface.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index dc0a952e6daebd..40a05fd0280a73 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -2895,7 +2895,7 @@ void CEEInfo::embedGenericHandle( pResolvedToken, NULL, pTemplateMD, - (MethodDesc*)callerHandle, + GetMethod(callerHandle), &pResult->lookup); } else @@ -2993,7 +2993,7 @@ MethodDesc * CEEInfo::GetMethodForSecurity(CORINFO_METHOD_HANDLE callerHandle) return m_pMethodForSecurity_Value; } - MethodDesc * pCallerMethod = (MethodDesc *)callerHandle; + MethodDesc * pCallerMethod = GetMethod(callerHandle); //If the caller is generic, load the open type and then load the field again, This allows us to //differentiate between BadGeneric containing a memberRef for a field of type InaccessibleClass and @@ -5419,7 +5419,7 @@ void CEEInfo::getCallInfo( pResolvedToken, pConstrainedResolvedToken, pMD, - (MethodDesc*)callerHandle, + GetMethod(callerHandle), &pResult->codePointerLookup); } else @@ -5471,7 +5471,7 @@ void CEEInfo::getCallInfo( pResolvedToken, pConstrainedResolvedToken, pMD, - (MethodDesc*)callerHandle, + GetMethod(callerHandle), &pResult->stubLookup); } else @@ -5513,7 +5513,7 @@ void CEEInfo::getCallInfo( pResult->hMethod = CORINFO_METHOD_HANDLE(pTargetMD); pResult->accessAllowed = CORINFO_ACCESS_ALLOWED; - MethodDesc* callerMethod = (MethodDesc*)callerHandle; + MethodDesc* callerMethod = GetMethod(callerHandle); if ((flags & CORINFO_CALLINFO_SECURITYCHECKS) && RequiresAccessCheck(pResolvedToken->tokenScope)) { From 09efb81a08aefdc41444a9d91ada4916ec37b3eb Mon Sep 17 00:00:00 2001 From: EgorBo Date: Wed, 13 Mar 2024 14:50:55 +0100 Subject: [PATCH 39/40] Address feedback --- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 c3e2bff274d2ec..aba1e6bbd36080 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -913,7 +913,7 @@ private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref helperArg = new FieldWithToken(fieldDesc, HandleToModuleToken(ref pResolvedToken)); } - GenericContext methodContext = new GenericContext(entityFromContext(pResolvedToken.tokenContext)); + var methodContext = new GenericContext(HandleToObject(callerHandle)); ISymbolNode helper = _compilation.SymbolNodeFactory.GenericLookupHelper( pGenericLookupKind.runtimeLookupKind, helperId, @@ -958,6 +958,7 @@ private void getReadyToRunDelegateCtorHelper(ref CORINFO_RESOLVED_TOKEN pTargetM unboxing: false, context: typeOrMethodContext); + // runtime lookup is not needed, callerHandle is unused pLookup.lookupKind.needsRuntimeLookup = false; pLookup.constLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.DelegateCtor(delegateTypeDesc, targetMethod)); } From 467cc06b2d8c2cabfe14c5d8461bdeab22f2efe0 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Wed, 13 Mar 2024 16:08:54 +0100 Subject: [PATCH 40/40] Address Jan's feedback --- src/coreclr/vm/jitinterface.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index c8bbc939961c7d..05d9365e967964 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -5286,19 +5286,6 @@ void CEEInfo::getCallInfo( { pResult->exactContextNeedsRuntimeLookup = TRUE; } - - // Use main method as the context as long as the methods are called on the same type - if (pResult->exactContextNeedsRuntimeLookup && - pResolvedToken->tokenContext == METHOD_BEING_COMPILED_CONTEXT() && - constrainedType.IsNull() && - exactType == m_pMethodBeingCompiled->GetMethodTable() && - ((pResolvedToken->cbTypeSpec == 0) || IsTypeSpecForTypicalInstantiation(SigPointer(pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec)))) - { - // The typespec signature should be only missing for dynamic methods - _ASSERTE((pResolvedToken->cbTypeSpec != 0) || m_pMethodBeingCompiled->IsDynamicMethod()); - - pResult->contextHandle = METHOD_BEING_COMPILED_CONTEXT(); - } } //