CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER, // Transition to cooperative mode in reverse P/Invoke prolog, frame is the first argument
CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT, // Transition to preemptive mode in reverse P/Invoke epilog, frame is the first argument
+
+ CORINFO_HELP_GVMLOOKUP_FOR_SLOT, // Resolve a generic virtual method target from this pointer and runtime method handle
#endif
CORINFO_HELP_COUNT,
JITHELPER(CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER, NULL, CORINFO_HELP_SIG_UNDEF)
JITHELPER(CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT, NULL, CORINFO_HELP_SIG_UNDEF)
+ JITHELPER(CORINFO_HELP_GVMLOOKUP_FOR_SLOT, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
+
#endif // COR_JIT_EE_VERSION
#undef JITHELPER
bool managedCall = (calliSig.callConv & GTF_CALL_UNMANAGED) == 0;
if (managedCall)
{
- call->AsCall()->SetFatPointerCandidate();
- setMethodHasFatPointer();
+ addFatPointerCandidate(call->AsCall());
}
}
}
thisPtr = impCloneExpr(thisPtr, &thisPtrCopy, NO_CLASS_HANDLE, (unsigned)CHECK_SPILL_ALL,
nullptr DEBUGARG("LDVIRTFTN this pointer"));
- GenTreePtr fptr = impImportLdvirtftn(thisPtr, pResolvedToken, callInfo);
+ GenTreePtr fptr = nullptr;
+ bool coreRTGenericVirtualMethod =
+ ((sig->callConv & CORINFO_CALLCONV_GENERIC) != 0) && IsTargetAbi(CORINFO_CORERT_ABI);
+#if COR_JIT_EE_VERSION > 460
+ if (coreRTGenericVirtualMethod)
+ {
+ GenTreePtr runtimeMethodHandle = nullptr;
+ if (callInfo->exactContextNeedsRuntimeLookup)
+ {
+ runtimeMethodHandle =
+ impRuntimeLookupToTree(pResolvedToken, &callInfo->codePointerLookup, methHnd);
+ }
+ else
+ {
+ runtimeMethodHandle = gtNewIconEmbMethHndNode(pResolvedToken->hMethod);
+ }
+ fptr = gtNewHelperCallNode(CORINFO_HELP_GVMLOOKUP_FOR_SLOT, TYP_I_IMPL, GTF_EXCEPT,
+ gtNewArgList(thisPtr, runtimeMethodHandle));
+ }
+ else
+#endif // COR_JIT_EE_VERSION
+ {
+ fptr = impImportLdvirtftn(thisPtr, pResolvedToken, callInfo);
+ }
+
if (compDonotInline())
{
return callRetTyp;
call->gtCall.gtCallObjp = thisPtrCopy;
call->gtFlags |= GTF_EXCEPT | (fptr->gtFlags & GTF_GLOB_EFFECT);
+ if (coreRTGenericVirtualMethod)
+ {
+ addFatPointerCandidate(call->AsCall());
+ }
#ifdef FEATURE_READYTORUN_COMPILER
if (opts.IsReadyToRun())
{