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);
return IsGenericTypeDefinition();
}
+ static const DWORD MaxGenericParametersForSpecialMarkerType = 8;
+
static BOOL ComputeContainsGenericVariables(Instantiation inst);
inline void SetContainsGenericVariables()
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();
}