Handle marker types with more than 1 generic argument correctly when they must be...
authorDavid Wrighton <davidwr@microsoft.com>
Tue, 29 Jun 2021 16:43:48 +0000 (09:43 -0700)
committerGitHub <noreply@github.com>
Tue, 29 Jun 2021 16:43:48 +0000 (09:43 -0700)
src/coreclr/vm/methodtable.cpp
src/coreclr/vm/methodtable.h
src/coreclr/vm/methodtablebuilder.cpp

index 3539aca..a7f41cc 100644 (file)
@@ -9820,8 +9820,12 @@ PTR_MethodTable MethodTable::InterfaceMapIterator::GetInterface(MethodTable* pMT
     MethodTable *pResult = m_pMap->GetMethodTable();
     if (pResult->IsSpecialMarkerTypeForGenericCasting())
     {
-        TypeHandle ownerAsInst(pMTOwner);
-        Instantiation inst(&ownerAsInst, 1);
+        TypeHandle ownerAsInst[MaxGenericParametersForSpecialMarkerType];
+        for (DWORD i = 0; i < MaxGenericParametersForSpecialMarkerType; i++)
+            ownerAsInst[i] = pMTOwner;
+
+        _ASSERTE(pResult->GetInstantiation().GetNumArgs() <= MaxGenericParametersForSpecialMarkerType);
+        Instantiation inst(ownerAsInst, pResult->GetInstantiation().GetNumArgs());
         pResult = ClassLoader::LoadGenericInstantiationThrowing(pResult->GetModule(), pResult->GetCl(), inst, ClassLoader::LoadTypes, loadLevel).AsMethodTable();
         if (pResult->IsFullyLoaded())
             SetInterface(pResult);
index 3fbc682..476a1cd 100644 (file)
@@ -1254,6 +1254,8 @@ public:
         return IsGenericTypeDefinition();
     }
 
+    static const DWORD MaxGenericParametersForSpecialMarkerType = 8;
+
     static BOOL ComputeContainsGenericVariables(Instantiation inst);
 
     inline void SetContainsGenericVariables()
index 0d372a4..89926ff 100644 (file)
@@ -9147,8 +9147,9 @@ MethodTableBuilder::LoadExactInterfaceMap(MethodTable *pMT)
                     if (uninstGenericCase && pItfPossiblyApprox->HasInstantiation() && pItfPossiblyApprox->ContainsGenericVariables())
                     {
                         // We allow a limited set of interface generic shapes with type variables. In particular, we require the 
-                        // instantiations to be exactly simple type variables
-                        if (InstantiationIsAllTypeVariables(pItfPossiblyApprox->GetInstantiation()))
+                        // instantiations to be exactly simple type variables, and to have a relatively small number of generic arguments
+                        // so that the fallback instantiating logic works efficiently
+                        if (InstantiationIsAllTypeVariables(pItfPossiblyApprox->GetInstantiation()) && pItfPossiblyApprox->GetInstantiation().GetNumArgs() <= MethodTable::MaxGenericParametersForSpecialMarkerType)
                         {
                             pItfPossiblyApprox = ClassLoader::LoadTypeDefThrowing(pItfPossiblyApprox->GetModule(), pItfPossiblyApprox->GetCl(), ClassLoader::ThrowIfNotFound, ClassLoader::PermitUninstDefOrRef, 0, CLASS_LOAD_EXACTPARENTS).AsMethodTable();
                         }