From 7a547bc9cd166c6f3c91c1f1cc13dfa549fb5c7a Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Fri, 10 Feb 2017 18:35:00 -0800 Subject: [PATCH] Generic Virtual calls for CoreRT --- src/inc/corinfo.h | 2 ++ src/inc/jithelpers.h | 2 ++ src/jit/compiler.h | 6 ++++++ src/jit/importer.cpp | 33 ++++++++++++++++++++++++++++++--- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h index f515fcb..492dbec 100644 --- a/src/inc/corinfo.h +++ b/src/inc/corinfo.h @@ -691,6 +691,8 @@ enum CorInfoHelpFunc 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, diff --git a/src/inc/jithelpers.h b/src/inc/jithelpers.h index f84db91..c9726cd 100644 --- a/src/inc/jithelpers.h +++ b/src/inc/jithelpers.h @@ -389,6 +389,8 @@ 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 diff --git a/src/jit/compiler.h b/src/jit/compiler.h index 4239cf6..6a5872a 100644 --- a/src/jit/compiler.h +++ b/src/jit/compiler.h @@ -5568,6 +5568,12 @@ public: optMethodFlags &= ~OMF_HAS_FATPOINTER; } + void addFatPointerCandidate(GenTreeCall* call) + { + setMethodHasFatPointer(); + call->SetFatPointerCandidate(); + } + unsigned optMethodFlags; // Recursion bound controls how far we can go backwards tracking for a SSA value. diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index 7a48933..e0f8f19 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -6467,8 +6467,7 @@ var_types Compiler::impImportCall(OPCODE opcode, bool managedCall = (calliSig.callConv & GTF_CALL_UNMANAGED) == 0; if (managedCall) { - call->AsCall()->SetFatPointerCandidate(); - setMethodHasFatPointer(); + addFatPointerCandidate(call->AsCall()); } } } @@ -6772,7 +6771,31 @@ var_types Compiler::impImportCall(OPCODE opcode, 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; @@ -6792,6 +6815,10 @@ var_types Compiler::impImportCall(OPCODE opcode, 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()) { -- 2.7.4