Skip to content

Commit

Permalink
Support for devirtualizing array interface methods
Browse files Browse the repository at this point in the history
Update jit and runtime to devirtualize interface calls on arrays.
This resolves the first two issues noted in dotnet#62457.
  • Loading branch information
AndyAyersMS committed Dec 7, 2021
1 parent 27226f6 commit 91d5c54
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 7 deletions.
18 changes: 14 additions & 4 deletions src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21696,8 +21696,18 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call,
if (derivedMethod != nullptr)
{
assert(exactContext != nullptr);
assert(((size_t)exactContext & CORINFO_CONTEXTFLAGS_MASK) == CORINFO_CONTEXTFLAGS_CLASS);
derivedClass = (CORINFO_CLASS_HANDLE)((size_t)exactContext & ~CORINFO_CONTEXTFLAGS_MASK);

if (((size_t)exactContext & CORINFO_CONTEXTFLAGS_MASK) == CORINFO_CONTEXTFLAGS_CLASS)
{
derivedClass = (CORINFO_CLASS_HANDLE)((size_t)exactContext & ~CORINFO_CONTEXTFLAGS_MASK);
}
else
{
// Array interface devirt can return a generic method of the non-generic SZArrayHelper class.
//
assert(((size_t)exactContext & CORINFO_CONTEXTFLAGS_MASK) == CORINFO_CONTEXTFLAGS_METHOD);
derivedClass = info.compCompHnd->getMethodClass(derivedMethod);
}
}

DWORD derivedMethodAttribs = 0;
Expand Down Expand Up @@ -22164,7 +22174,7 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call,
//
if (pExactContextHandle != nullptr)
{
*pExactContextHandle = MAKE_CLASSCONTEXT(derivedClass);
*pExactContextHandle = exactContext;
}

#ifdef FEATURE_READYTORUN
Expand Down Expand Up @@ -22497,7 +22507,7 @@ void Compiler::considerGuardedDevirtualization(

if (!canResolve)
{
JITDUMP("Can't figure out which method would be invoked, sorry\n");
JITDUMP("Can't figure out which method would be invoked, sorry (reason %d)\n", dvInfo.detail);
return;
}

Expand Down
36 changes: 33 additions & 3 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8517,7 +8517,19 @@ bool CEEInfo::resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info)
//
// We must ensure that pObjMT actually implements the
// interface corresponding to pBaseMD.
if (!pObjMT->CanCastToInterface(pBaseMT))
//
if (pObjMT->IsArray())
{
// Could avoid this mode switch by using type handle's CanCastTo...
//
GCX_COOP();
if (!pObjMT->CanCastTo(pBaseMT, nullptr))
{
info->detail = CORINFO_DEVIRTUALIZATION_FAILED_CAST;
return false;
}
}
else if (!pObjMT->CanCastToInterface(pBaseMT))
{
info->detail = CORINFO_DEVIRTUALIZATION_FAILED_CAST;
return false;
Expand Down Expand Up @@ -8627,8 +8639,12 @@ bool CEEInfo::resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info)
// We may fail to get an exact context if the method is a default
// interface method. If so, we'll use the method's class.
//
// For array -> interface devirt, the devirtualized methods
// will be defined by SZArrayHelper.
//
MethodTable* pApproxMT = pDevirtMD->GetMethodTable();
MethodTable* pExactMT = pApproxMT;
bool isArray = false;

if (pApproxMT->IsInterface())
{
Expand All @@ -8637,6 +8653,10 @@ bool CEEInfo::resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info)
_ASSERTE(!pDevirtMD->HasClassInstantiation());

}
else if (pBaseMT->IsInterface() && pObjMT->IsArray())
{
isArray = true;
}
else
{
pExactMT = pDevirtMD->GetExactDeclaringType(pObjMT);
Expand All @@ -8645,8 +8665,18 @@ bool CEEInfo::resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info)
// Success! Pass back the results.
//
info->devirtualizedMethod = (CORINFO_METHOD_HANDLE) pDevirtMD;
info->exactContext = MAKE_CLASSCONTEXT((CORINFO_CLASS_HANDLE) pExactMT);
info->requiresInstMethodTableArg = false;

if (isArray)
{
info->exactContext = MAKE_METHODCONTEXT((CORINFO_METHOD_HANDLE) pDevirtMD);
info->requiresInstMethodTableArg = pDevirtMD->RequiresInstMethodTableArg();
}
else
{
info->exactContext = MAKE_CLASSCONTEXT((CORINFO_CLASS_HANDLE) pExactMT);
info->requiresInstMethodTableArg = false;
}

info->detail = CORINFO_DEVIRTUALIZATION_SUCCESS;

return true;
Expand Down

0 comments on commit 91d5c54

Please sign in to comment.