Merge pull request #9522 from sandreenko/GVM-for-corert
authorSergey Andreenko <seandree@microsoft.com>
Tue, 14 Feb 2017 22:55:30 +0000 (14:55 -0800)
committerGitHub <noreply@github.com>
Tue, 14 Feb 2017 22:55:30 +0000 (14:55 -0800)
Generic Virtual methods  for CoreRT

src/inc/corinfo.h
src/inc/jithelpers.h
src/jit/compiler.h
src/jit/importer.cpp

index f515fcb..492dbec 100644 (file)
@@ -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,
index f84db91..c9726cd 100644 (file)
     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
index c2cc278..b9bace4 100644 (file)
@@ -5575,6 +5575,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.
index 1849a57..7b73391 100644 (file)
@@ -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())
                 {