Performance fix for R2R: vtable calls (#20061)
authorFadi Hanna <fadim@microsoft.com>
Fri, 21 Sep 2018 05:06:48 +0000 (22:06 -0700)
committerJan Kotas <jkotas@microsoft.com>
Fri, 21 Sep 2018 05:06:48 +0000 (22:06 -0700)
* Performance fix for R2R: use vtable-based codegen for virtual calls within the System.Private.CoreLib version bubble, avoiding the use of the VSD, or in the generics case, a dictionary lookup.
The CoreLib assembly will always be serviced along side the coreclr runtime, so special casing CoreLib to using vtable-based calls like the fragile NI case is ok.

src/vm/jitinterface.cpp
src/zap/zapinfo.cpp

index 4b12384..4bb52a7 100644 (file)
@@ -713,6 +713,18 @@ static bool IsInSameVersionBubble(MethodDesc* pCurMD, MethodDesc *pTargetMD)
 
 #endif // FEATURE_READYTORUN_COMPILER
 
+static bool CallerAndCalleeInSystemVersionBubble(MethodDesc* pCaller, MethodDesc* pCallee)
+{
+    LIMITED_METHOD_CONTRACT;
+
+#ifdef FEATURE_READYTORUN_COMPILER
+    if (IsReadyToRunCompilation())
+        return pCallee->GetModule()->IsSystem() && IsInSameVersionBubble(pCaller, pCallee);
+#endif
+
+    return false;
+}
+
 
 /*********************************************************************/
 CorInfoCanSkipVerificationResult CEEInfo::canSkipVerification(
@@ -5158,8 +5170,6 @@ void CEEInfo::getCallInfo(
         EX_THROW(EEMessageException, (kMissingMethodException, IDS_EE_MISSING_METHOD, W("?")));
     }
 
-
-
     TypeHandle exactType = TypeHandle(pResolvedToken->hClass);
 
     TypeHandle constrainedType;
@@ -5459,8 +5469,11 @@ void CEEInfo::getCallInfo(
         pResult->kind = CORINFO_VIRTUALCALL_LDVIRTFTN;  // stub dispatch can't handle generic method calls yet
         pResult->nullInstanceCheck = TRUE;
     }
-    // Non-interface dispatches go through the vtable
-    else if (!pTargetMD->IsInterface() && !IsReadyToRunCompilation())
+    // Non-interface dispatches go through the vtable.
+    // We'll special virtual calls to target methods in the corelib assembly when compiling in R2R mode and generate fragile-NI-like callsites for improved performance. We
+    // can do that because today we'll always service the corelib assembly and the runtime in one bundle. Any caller in the corelib version bubble can benefit from this
+    // performance optimization.
+    else if (!pTargetMD->IsInterface() && (!IsReadyToRunCompilation() || CallerAndCalleeInSystemVersionBubble((MethodDesc*)callerHandle, pTargetMD)))
     {
         pResult->kind = CORINFO_VIRTUALCALL_VTABLE;
         pResult->nullInstanceCheck = TRUE;
index 40ab579..7320729 100644 (file)
@@ -2203,7 +2203,8 @@ void ZapInfo::getCallInfo(CORINFO_RESOLVED_TOKEN * pResolvedToken,
         break;
 
     case CORINFO_VIRTUALCALL_VTABLE:
-        _ASSERTE(!IsReadyToRunCompilation());
+        // READYTORUN: FUTURE: support for vtable-based calls (currently, only calls within the CoreLib version bubble is supported, and the codegen we generate
+        // is the same as the fragile NI (because CoreLib and the runtime will always be updated together anyways - this is a special case)
         break;
 
     case CORINFO_VIRTUALCALL_LDVIRTFTN: