@@ -8700,6 +8700,80 @@ void CEEInfo::getMethodVTableOffset (CORINFO_METHOD_HANDLE methodHnd,
8700
8700
EE_TO_JIT_TRANSITION_LEAF ();
8701
8701
}
8702
8702
8703
+ /* ********************************************************************/
8704
+ CORINFO_METHOD_HANDLE CEEInfo::resolveVirtualMethod (CORINFO_METHOD_HANDLE methodHnd,
8705
+ CORINFO_CLASS_HANDLE derivedClass)
8706
+ {
8707
+ CONTRACTL {
8708
+ SO_TOLERANT;
8709
+ NOTHROW;
8710
+ GC_NOTRIGGER;
8711
+ MODE_PREEMPTIVE;
8712
+ } CONTRACTL_END;
8713
+
8714
+ CORINFO_METHOD_HANDLE result = nullptr ;
8715
+
8716
+ JIT_TO_EE_TRANSITION ();
8717
+
8718
+ MethodDesc* method = GetMethod (methodHnd);
8719
+
8720
+ // Method better be from a fully loaded class
8721
+ _ASSERTE (method->IsRestored () && method->GetMethodTable ()->IsFullyLoaded ());
8722
+
8723
+ // Method better be virtual
8724
+ _ASSERTE (method->IsVirtual ());
8725
+
8726
+ // @GENERICS: shouldn't be doing this for instantiated methods as they live elsewhere
8727
+ _ASSERTE (!method->HasMethodInstantiation ());
8728
+
8729
+ // Method's class better not be an interface
8730
+ _ASSERTE (!method->GetMethodTable ()->IsInterface ());
8731
+
8732
+ // Method better be in the vtable
8733
+ WORD slot = method->GetSlot ();
8734
+ _ASSERTE (slot < method->GetMethodTable ()->GetNumVirtuals ());
8735
+
8736
+ // TODO: Derived class should have base class as parent...
8737
+ TypeHandle DerivedClsHnd (derivedClass);
8738
+
8739
+ // If derived class is _Canon, we can't devirtualize.
8740
+ if (DerivedClsHnd != TypeHandle (g_pCanonMethodTableClass))
8741
+ {
8742
+ MethodTable* pMT = DerivedClsHnd.GetMethodTable ();
8743
+
8744
+ // MethodDescs returned to JIT at runtime are always fully loaded. Verify that it is the case.
8745
+ _ASSERTE (pMT->IsRestored () && pMT->IsFullyLoaded ());
8746
+
8747
+ MethodDesc* pDevirtMD = pMT->GetMethodDescForSlot (slot);
8748
+
8749
+ _ASSERTE (pDevirtMD->IsRestored ());
8750
+
8751
+ // Allow devirtialization if jitting, or if prejitting and the
8752
+ // method being jitted, the devirtualized class, and the
8753
+ // devirtualized method are all in the same versioning bubble.
8754
+ bool allowDevirt = true ;
8755
+
8756
+ #ifdef FEATURE_READYTORUN_COMPILER
8757
+ if (IsReadyToRunCompilation ())
8758
+ {
8759
+ Assembly * pCallerAssembly = m_pMethodBeingCompiled->GetModule ()->GetAssembly ();
8760
+ allowDevirt =
8761
+ IsInSameVersionBubble (pCallerAssembly , pDevirtMD->GetModule ()->GetAssembly ())
8762
+ && IsInSameVersionBubble (pCallerAssembly , pMT->GetAssembly ());
8763
+ }
8764
+ #endif
8765
+
8766
+ if (allowDevirt)
8767
+ {
8768
+ result = (CORINFO_METHOD_HANDLE) pDevirtMD;
8769
+ }
8770
+ }
8771
+
8772
+ EE_TO_JIT_TRANSITION ();
8773
+
8774
+ return result;
8775
+ }
8776
+
8703
8777
/* ********************************************************************/
8704
8778
void CEEInfo::getFunctionEntryPoint (CORINFO_METHOD_HANDLE ftnHnd,
8705
8779
CORINFO_CONST_LOOKUP * pResult,
0 commit comments