diff options
-rw-r--r-- | src/vm/method.hpp | 4 | ||||
-rw-r--r-- | src/vm/methodtable.cpp | 131 | ||||
-rw-r--r-- | src/vm/methodtablebuilder.cpp | 20 |
3 files changed, 82 insertions, 73 deletions
diff --git a/src/vm/method.hpp b/src/vm/method.hpp index 3953b05a16..9791ddd4ad 100644 --- a/src/vm/method.hpp +++ b/src/vm/method.hpp @@ -1010,7 +1010,11 @@ public: { LIMITED_METHOD_CONTRACT; +#ifdef FEATURE_DEFAULT_INTERFACES return (GetMethodTable()->IsInterface() && !IsStatic() && IsVirtual() && !IsAbstract()); +#else + return false; +#endif // FEATURE_DEFAULT_INTERFACES } inline BOOL HasNonVtableSlot(); diff --git a/src/vm/methodtable.cpp b/src/vm/methodtable.cpp index 1b19a33f3f..0b63e8a380 100644 --- a/src/vm/methodtable.cpp +++ b/src/vm/methodtable.cpp @@ -7071,6 +7071,7 @@ BOOL MethodTable::FindDefaultInterfaceImplementation( POSTCONDITION(!RETVAL || (*ppDefaultMethod) != nullptr); } CONTRACT_END; +#ifdef FEATURE_DEFAULT_INTERFACES InterfaceMapIterator it = this->IterateInterfaceMap(); CQuickArray<MatchCandidate> candidates; @@ -7276,6 +7277,9 @@ BOOL MethodTable::FindDefaultInterfaceImplementation( *ppDefaultMethod = pBestCandidateMD; RETURN(TRUE); } +#else + *ppDefaultMethod = NULL; +#endif // FEATURE_DEFAULT_INTERFACES RETURN(FALSE); } @@ -9826,84 +9830,83 @@ MethodTable::TryResolveConstraintMethodApprox( MethodDesc * pGenInterfaceMD = pInterfaceMD->StripMethodInstantiation(); MethodDesc * pMD = NULL; if (pGenInterfaceMD->IsInterface()) - { - // Sometimes (when compiling shared generic code) + { // Sometimes (when compiling shared generic code) // we don't have enough exact type information at JIT time // even to decide whether we will be able to resolve to an unboxed entry point... // To cope with this case we always go via the helper function if there's any -// chance of this happening by checking for all interfaces which might possibly -// be compatible with the call (verification will have ensured that -// at least one of them will be) - -// Enumerate all potential interface instantiations -MethodTable::InterfaceMapIterator it = pCanonMT->IterateInterfaceMap(); -DWORD cPotentialMatchingInterfaces = 0; -while (it.Next()) -{ - TypeHandle thPotentialInterfaceType(it.GetInterface()); - if (thPotentialInterfaceType.AsMethodTable()->GetCanonicalMethodTable() == - thInterfaceType.AsMethodTable()->GetCanonicalMethodTable()) - { - cPotentialMatchingInterfaces++; - pMD = pCanonMT->GetMethodDescForInterfaceMethod(thPotentialInterfaceType, pGenInterfaceMD); + // chance of this happening by checking for all interfaces which might possibly + // be compatible with the call (verification will have ensured that + // at least one of them will be) - // See code:#TryResolveConstraintMethodApprox_DoNotReturnParentMethod - if ((pMD != NULL) && !pMD->GetMethodTable()->IsValueType()) + // Enumerate all potential interface instantiations + MethodTable::InterfaceMapIterator it = pCanonMT->IterateInterfaceMap(); + DWORD cPotentialMatchingInterfaces = 0; + while (it.Next()) { - LOG((LF_JIT, LL_INFO10000, "TryResolveConstraintMethodApprox: %s::%s not a value type method\n", - pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName)); - return NULL; + TypeHandle thPotentialInterfaceType(it.GetInterface()); + if (thPotentialInterfaceType.AsMethodTable()->GetCanonicalMethodTable() == + thInterfaceType.AsMethodTable()->GetCanonicalMethodTable()) + { + cPotentialMatchingInterfaces++; + pMD = pCanonMT->GetMethodDescForInterfaceMethod(thPotentialInterfaceType, pGenInterfaceMD); + + // See code:#TryResolveConstraintMethodApprox_DoNotReturnParentMethod + if ((pMD != NULL) && !pMD->GetMethodTable()->IsValueType()) + { + LOG((LF_JIT, LL_INFO10000, "TryResolveConstraintMethodApprox: %s::%s not a value type method\n", + pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName)); + return NULL; + } + } } - } -} -_ASSERTE_MSG((cPotentialMatchingInterfaces != 0), - "At least one interface has to implement the method, otherwise there's a bug in JIT/verification."); + _ASSERTE_MSG((cPotentialMatchingInterfaces != 0), + "At least one interface has to implement the method, otherwise there's a bug in JIT/verification."); -if (cPotentialMatchingInterfaces > 1) -{ // We have more potentially matching interfaces - MethodTable * pInterfaceMT = thInterfaceType.GetMethodTable(); - _ASSERTE(pInterfaceMT->HasInstantiation()); + if (cPotentialMatchingInterfaces > 1) + { // We have more potentially matching interfaces + MethodTable * pInterfaceMT = thInterfaceType.GetMethodTable(); + _ASSERTE(pInterfaceMT->HasInstantiation()); - BOOL fIsExactMethodResolved = FALSE; + BOOL fIsExactMethodResolved = FALSE; - if (!pInterfaceMT->IsSharedByGenericInstantiations() && - !pInterfaceMT->IsGenericTypeDefinition() && - !this->IsSharedByGenericInstantiations() && - !this->IsGenericTypeDefinition()) - { // We have exact interface and type instantiations (no generic variables and __Canon used - // anywhere) - if (this->CanCastToInterface(pInterfaceMT)) - { - // We can resolve to exact method - pMD = this->GetMethodDescForInterfaceMethod(pInterfaceMT, pInterfaceMD); - _ASSERTE(pMD != NULL); - fIsExactMethodResolved = TRUE; - } - } + if (!pInterfaceMT->IsSharedByGenericInstantiations() && + !pInterfaceMT->IsGenericTypeDefinition() && + !this->IsSharedByGenericInstantiations() && + !this->IsGenericTypeDefinition()) + { // We have exact interface and type instantiations (no generic variables and __Canon used + // anywhere) + if (this->CanCastToInterface(pInterfaceMT)) + { + // We can resolve to exact method + pMD = this->GetMethodDescForInterfaceMethod(pInterfaceMT, pInterfaceMD); + _ASSERTE(pMD != NULL); + fIsExactMethodResolved = TRUE; + } + } - if (!fIsExactMethodResolved) - { // We couldn't resolve the interface statically - _ASSERTE(pfForceUseRuntimeLookup != NULL); - // Notify the caller that it should use runtime lookup - // Note that we can leave pMD incorrect, because we will use runtime lookup - *pfForceUseRuntimeLookup = TRUE; - } -} -else -{ - // If we can resolve the interface exactly then do so (e.g. when doing the exact - // lookup at runtime, or when not sharing generic code). - if (pCanonMT->CanCastToInterface(thInterfaceType.GetMethodTable())) - { - pMD = pCanonMT->GetMethodDescForInterfaceMethod(thInterfaceType, pGenInterfaceMD); - if (pMD == NULL) + if (!fIsExactMethodResolved) + { // We couldn't resolve the interface statically + _ASSERTE(pfForceUseRuntimeLookup != NULL); + // Notify the caller that it should use runtime lookup + // Note that we can leave pMD incorrect, because we will use runtime lookup + *pfForceUseRuntimeLookup = TRUE; + } + } + else { - LOG((LF_JIT, LL_INFO10000, "TryResolveConstraintMethodApprox: failed to find method desc for interface method\n")); + // If we can resolve the interface exactly then do so (e.g. when doing the exact + // lookup at runtime, or when not sharing generic code). + if (pCanonMT->CanCastToInterface(thInterfaceType.GetMethodTable())) + { + pMD = pCanonMT->GetMethodDescForInterfaceMethod(thInterfaceType, pGenInterfaceMD); + if (pMD == NULL) + { + LOG((LF_JIT, LL_INFO10000, "TryResolveConstraintMethodApprox: failed to find method desc for interface method\n")); + } + } } } -} - } else if (pGenInterfaceMD->IsVirtual()) { if (pGenInterfaceMD->HasNonVtableSlot() && pGenInterfaceMD->GetMethodTable()->IsValueType()) diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp index 9f4d2ca892..2c0d73e952 100644 --- a/src/vm/methodtablebuilder.cpp +++ b/src/vm/methodtablebuilder.cpp @@ -2871,16 +2871,16 @@ MethodTableBuilder::EnumerateClassMethods() BuildMethodTableThrowException(BFA_NONVIRT_AB_METHOD); } } - else if(fIsClassInterface) - { + else if(fIsClassInterface) + { if (IsMdRTSpecialName(dwMemberAttrs)) - { - CONSISTENCY_CHECK(CheckPointer(strMethodName)); - if (strcmp(strMethodName, COR_CCTOR_METHOD_NAME)) - { - BuildMethodTableThrowException(BFA_NONAB_NONCCTOR_METHOD_ON_INT); - } - } + { + CONSISTENCY_CHECK(CheckPointer(strMethodName)); + if (strcmp(strMethodName, COR_CCTOR_METHOD_NAME)) + { + BuildMethodTableThrowException(BFA_NONAB_NONCCTOR_METHOD_ON_INT); + } + } } // Virtual / not virtual @@ -10681,6 +10681,7 @@ BOOL MethodTableBuilder::HasDefaultInterfaceImplementation(MethodDesc *pDeclMD) { STANDARD_VM_CONTRACT; +#ifdef FEATURE_DEFAULT_INTERFACES // If the interface method is already non-abstract, we are done if (pDeclMD->IsDefaultInterfaceMethod()) return TRUE; @@ -10710,6 +10711,7 @@ BOOL MethodTableBuilder::HasDefaultInterfaceImplementation(MethodDesc *pDeclMD) } } } +#endif // FEATURE_DEFAULT_INTERFACES return FALSE; } |