Skip to content

Commit ee4bd19

Browse files
committed
Stop spilling ldvirtftn
1 parent 9c700f7 commit ee4bd19

File tree

8 files changed

+39
-36
lines changed

8 files changed

+39
-36
lines changed

src/coreclr/inc/corinfo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,7 +1522,7 @@ struct CORINFO_DEVIRTUALIZATION_INFO
15221522
// - If pResolvedTokenDevirtualizedMethod is not set to NULL and targeting an R2R image
15231523
// use it as the parameter to getCallInfo
15241524
// - isInstantiatingStub is set to TRUE if the devirtualized method is a generic method instantiating stub
1525-
// - wasArrayInterfaceDevirt is set TRUE for array interface method devirtualization
1525+
// - needsMethodContext is set TRUE if the devirtualized method requires a method context
15261526
// (in which case the method handle and context will be a generic method)
15271527
//
15281528
CORINFO_METHOD_HANDLE devirtualizedMethod;
@@ -1531,7 +1531,7 @@ struct CORINFO_DEVIRTUALIZATION_INFO
15311531
CORINFO_RESOLVED_TOKEN resolvedTokenDevirtualizedMethod;
15321532
CORINFO_RESOLVED_TOKEN resolvedTokenDevirtualizedUnboxedMethod;
15331533
bool isInstantiatingStub;
1534-
bool wasArrayInterfaceDevirt;
1534+
bool needsMethodContext;
15351535
};
15361536

15371537
//----------------------------------------------------------------------------

src/coreclr/jit/compiler.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1606,7 +1606,7 @@ inline GenTreeCall* Compiler::gtNewHelperCallNode(
16061606
/*****************************************************************************/
16071607

16081608
//------------------------------------------------------------------------------
1609-
// gtNewHelperCallNode : Helper to create a call helper node.
1609+
// gtNewVirtualFunctionLookupHelperCallNode : Helper to create a virtual function lookup helper node.
16101610
//
16111611
//
16121612
// Arguments:

src/coreclr/jit/importercalls.cpp

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -400,23 +400,26 @@ var_types Compiler::impImportCall(OPCODE opcode,
400400
thisPtr = impTransformThis(thisPtr, pConstrainedResolvedToken, callInfo->thisTransform);
401401
assert(thisPtr != nullptr);
402402

403+
GenTree* origThisPtr = thisPtr;
403404
// Clone the (possibly transformed) "this" pointer
404405
GenTree* thisPtrCopy;
405406
thisPtr =
406407
impCloneExpr(thisPtr, &thisPtrCopy, CHECK_SPILL_ALL, nullptr DEBUGARG("LDVIRTFTN this pointer"));
407408

409+
// We cloned the "this" pointer, mark it as a single def and set the class for it
410+
if (thisPtr->TypeIs(TYP_REF) && (origThisPtr != thisPtr))
411+
{
412+
lvaGetDesc(thisPtr->AsLclVar())->lvSingleDef = 1;
413+
lvaSetClass(thisPtr->AsLclVar()->GetLclNum(), origThisPtr);
414+
}
415+
408416
GenTree* fptr = impImportLdvirtftn(thisPtr, pResolvedToken, callInfo);
409417
assert(fptr != nullptr);
410418

411419
call->AsCall()
412420
->gtArgs.PushFront(this, NewCallArg::Primitive(thisPtrCopy).WellKnown(WellKnownArg::ThisPointer));
413421

414422
// Now make an indirect call through the function pointer
415-
416-
unsigned lclNum = lvaGrabTemp(true DEBUGARG("VirtualCall through function pointer"));
417-
impStoreToTemp(lclNum, fptr, CHECK_SPILL_ALL);
418-
fptr = gtNewLclvNode(lclNum, TYP_I_IMPL);
419-
420423
call->AsCall()->gtCallAddr = fptr;
421424
call->gtFlags |= GTF_EXCEPT | (fptr->gtFlags & GTF_GLOB_EFFECT);
422425

@@ -7603,7 +7606,7 @@ void Compiler::considerGuardedDevirtualization(GenTreeCall* call,
76037606
}
76047607

76057608
addGuardedDevirtualizationCandidate(call, exactMethod, exactCls, exactContext, exactMethodAttrs,
7606-
clsAttrs, likelyHood, dvInfo.wasArrayInterfaceDevirt,
7609+
clsAttrs, likelyHood, dvInfo.needsMethodContext,
76077610
dvInfo.isInstantiatingStub, baseMethod, originalContext);
76087611
}
76097612

@@ -7676,7 +7679,7 @@ void Compiler::considerGuardedDevirtualization(GenTreeCall* call,
76767679

76777680
likelyContext = dvInfo.exactContext;
76787681
likelyMethod = dvInfo.devirtualizedMethod;
7679-
arrayInterface = dvInfo.wasArrayInterfaceDevirt;
7682+
arrayInterface = dvInfo.needsMethodContext;
76807683
instantiatingStub = dvInfo.isInstantiatingStub;
76817684
}
76827685
else
@@ -8767,14 +8770,14 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call,
87678770

87688771
if (((size_t)exactContext & CORINFO_CONTEXTFLAGS_MASK) == CORINFO_CONTEXTFLAGS_CLASS)
87698772
{
8770-
assert(!dvInfo.wasArrayInterfaceDevirt);
8773+
assert(!dvInfo.needsMethodContext);
87718774
derivedClass = (CORINFO_CLASS_HANDLE)((size_t)exactContext & ~CORINFO_CONTEXTFLAGS_MASK);
87728775
}
87738776
else
87748777
{
87758778
// Array interface devirt can return a nonvirtual generic method of the non-generic SZArrayHelper class.
87768779
//
8777-
assert(dvInfo.wasArrayInterfaceDevirt);
8780+
assert(dvInfo.needsMethodContext);
87788781
assert(((size_t)exactContext & CORINFO_CONTEXTFLAGS_MASK) == CORINFO_CONTEXTFLAGS_METHOD);
87798782
derivedClass = info.compCompHnd->getMethodClass(derivedMethod);
87808783
}
@@ -8795,9 +8798,9 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call,
87958798

87968799
if (dvInfo.isInstantiatingStub)
87978800
{
8798-
// We should only end up with generic methods for array interface devirt.
8801+
// We should only end up with generic methods that needs a method context (eg. array interface).
87998802
//
8800-
assert(dvInfo.wasArrayInterfaceDevirt);
8803+
assert(dvInfo.needsMethodContext);
88018804

88028805
// We don't expect NAOT to end up here, since it has Array<T>
88038806
// and normal devirtualization.
@@ -8920,14 +8923,6 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call,
89208923

89218924
JITDUMP(" %s; can devirtualize\n", note);
89228925

8923-
// Make the updates.
8924-
call->gtFlags &= ~GTF_CALL_VIRT_VTABLE;
8925-
call->gtFlags &= ~GTF_CALL_VIRT_STUB;
8926-
call->gtCallMethHnd = derivedMethod;
8927-
call->gtCallType = CT_USER_FUNC;
8928-
call->gtControlExpr = nullptr;
8929-
INDEBUG(call->gtCallDebugFlags |= GTF_CALL_MD_DEVIRTUALIZED);
8930-
89318926
if (dvInfo.isInstantiatingStub)
89328927
{
89338928
// Pass the instantiating stub method desc as the inst param arg.
@@ -8939,6 +8934,14 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call,
89398934
call->gtArgs.InsertInstParam(this, instParam);
89408935
}
89418936

8937+
// Make the updates.
8938+
call->gtFlags &= ~GTF_CALL_VIRT_VTABLE;
8939+
call->gtFlags &= ~GTF_CALL_VIRT_STUB;
8940+
call->gtCallMethHnd = derivedMethod;
8941+
call->gtCallType = CT_USER_FUNC;
8942+
call->gtControlExpr = nullptr;
8943+
INDEBUG(call->gtCallDebugFlags |= GTF_CALL_MD_DEVIRTUALIZED);
8944+
89428945
// Virtual calls include an implicit null check, which we may
89438946
// now need to make explicit.
89448947
if (!objIsNonNull)

src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,7 @@ private bool resolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO* info)
13241324
info->exactContext = null;
13251325
info->detail = CORINFO_DEVIRTUALIZATION_DETAIL.CORINFO_DEVIRTUALIZATION_UNKNOWN;
13261326
info->isInstantiatingStub = false;
1327-
info->wasArrayInterfaceDevirt = false;
1327+
info->needsMethodContext = false;
13281328

13291329
TypeDesc objType = HandleToObject(info->objClass);
13301330

src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,7 +1093,7 @@ public unsafe struct CORINFO_DEVIRTUALIZATION_INFO
10931093
// - exactContext is set to wrapped CORINFO_CLASS_HANDLE of devirt'ed method table.
10941094
// - detail describes the computation done by the jit host
10951095
// - isInstantiatingStub is set to TRUE if the devirtualized method is a method instantiation stub
1096-
// - wasArrayInterfaceDevirt is set TRUE for array interface method devirtualization
1096+
// - needsMethodContext is set TRUE if the devirtualized method requires a method context
10971097
// (in which case the method handle and context will be a generic method)
10981098
//
10991099
public CORINFO_METHOD_STRUCT_* devirtualizedMethod;
@@ -1103,8 +1103,8 @@ public unsafe struct CORINFO_DEVIRTUALIZATION_INFO
11031103
public CORINFO_RESOLVED_TOKEN resolvedTokenDevirtualizedUnboxedMethod;
11041104
public byte _isInstantiatingStub;
11051105
public bool isInstantiatingStub { get { return _isInstantiatingStub != 0; } set { _isInstantiatingStub = value ? (byte)1 : (byte)0; } }
1106-
public byte _wasArrayInterfaceDevirt;
1107-
public bool wasArrayInterfaceDevirt { get { return _wasArrayInterfaceDevirt != 0; } set { _wasArrayInterfaceDevirt = value ? (byte)1 : (byte)0; } }
1106+
public byte _needsMethodContext;
1107+
public bool needsMethodContext { get { return _needsMethodContext != 0; } set { _needsMethodContext = value ? (byte)1 : (byte)0; } }
11081108
}
11091109

11101110
//----------------------------------------------------------------------------

src/coreclr/tools/superpmi/superpmi-shared/agnostic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ struct Agnostic_ResolveVirtualMethodResult
676676
bool returnValue;
677677
DWORDLONG devirtualizedMethod;
678678
bool isInstantiatingStub;
679-
bool wasArrayInterfaceDevirt;
679+
bool needsMethodContext;
680680
DWORDLONG exactContext;
681681
DWORD detail;
682682
Agnostic_CORINFO_RESOLVED_TOKEN resolvedTokenDevirtualizedMethod;

src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3276,7 +3276,7 @@ void MethodContext::recResolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info
32763276
result.isInstantiatingStub = info->isInstantiatingStub;
32773277
result.exactContext = CastHandle(info->exactContext);
32783278
result.detail = (DWORD) info->detail;
3279-
result.wasArrayInterfaceDevirt = info->wasArrayInterfaceDevirt;
3279+
result.needsMethodContext = info->needsMethodContext;
32803280

32813281
if (returnValue)
32823282
{
@@ -3301,11 +3301,11 @@ void MethodContext::dmpResolveVirtualMethod(const Agnostic_ResolveVirtualMethodK
33013301
key.context,
33023302
key.pResolvedTokenVirtualMethodNonNull,
33033303
key.pResolvedTokenVirtualMethodNonNull ? SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(key.pResolvedTokenVirtualMethod).c_str() : "???");
3304-
printf(", value returnValue-%s, devirtMethod-%016" PRIX64 ", instantiatingStub-%s, wasArrayInterfaceDevirt-%s, exactContext-%016" PRIX64 ", detail-%d, tokDvMeth{%s}, tokDvUnboxMeth{%s}",
3304+
printf(", value returnValue-%s, devirtMethod-%016" PRIX64 ", instantiatingStub-%s, needsMethodContext-%s, exactContext-%016" PRIX64 ", detail-%d, tokDvMeth{%s}, tokDvUnboxMeth{%s}",
33053305
result.returnValue ? "true" : "false",
33063306
result.devirtualizedMethod,
33073307
result.isInstantiatingStub ? "true" : "false",
3308-
result.wasArrayInterfaceDevirt ? "true" : "false",
3308+
result.needsMethodContext ? "true" : "false",
33093309
result.exactContext,
33103310
result.detail,
33113311
result.returnValue ? SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(result.resolvedTokenDevirtualizedMethod).c_str() : "???",
@@ -3330,7 +3330,7 @@ bool MethodContext::repResolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info
33303330

33313331
info->devirtualizedMethod = (CORINFO_METHOD_HANDLE) result.devirtualizedMethod;
33323332
info->isInstantiatingStub = result.isInstantiatingStub;
3333-
info->wasArrayInterfaceDevirt = result.wasArrayInterfaceDevirt;
3333+
info->needsMethodContext = result.needsMethodContext;
33343334
info->exactContext = (CORINFO_CONTEXT_HANDLE) result.exactContext;
33353335
info->detail = (CORINFO_DEVIRTUALIZATION_DETAIL) result.detail;
33363336
if (result.returnValue)

src/coreclr/vm/jitinterface.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8549,14 +8549,14 @@ bool CEEInfo::resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info)
85498549
memset(&info->resolvedTokenDevirtualizedMethod, 0, sizeof(info->resolvedTokenDevirtualizedMethod));
85508550
memset(&info->resolvedTokenDevirtualizedUnboxedMethod, 0, sizeof(info->resolvedTokenDevirtualizedUnboxedMethod));
85518551
info->isInstantiatingStub = false;
8552-
info->wasArrayInterfaceDevirt = false;
8552+
info->needsMethodContext = false;
85538553

85548554
MethodDesc* pBaseMD = GetMethod(info->virtualMethod);
85558555
MethodTable* pBaseMT = pBaseMD->GetMethodTable();
85568556

85578557
// Method better be from a fully loaded class
85588558
_ASSERTE(pBaseMT->IsFullyLoaded());
8559-
8559+
85608560
//@GENERICS: shouldn't be doing this for instantiated methods as they live elsewhere
85618561
_ASSERTE(!pBaseMD->HasMethodInstantiation());
85628562

@@ -8783,7 +8783,7 @@ bool CEEInfo::resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info)
87838783
{
87848784
pExactMT = pDevirtMD->GetExactDeclaringType(pObjMT);
87858785
}
8786-
8786+
87878787
// Success! Pass back the results.
87888788
//
87898789
if (isArray)
@@ -8793,13 +8793,13 @@ bool CEEInfo::resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info)
87938793
//
87948794
info->isInstantiatingStub = pDevirtMD->IsInstantiatingStub();
87958795
info->exactContext = MAKE_METHODCONTEXT((CORINFO_METHOD_HANDLE) pDevirtMD);
8796-
info->wasArrayInterfaceDevirt = true;
8796+
info->needsMethodContext = true;
87978797
}
87988798
else
87998799
{
88008800
info->exactContext = MAKE_CLASSCONTEXT((CORINFO_CLASS_HANDLE) pExactMT);
88018801
info->isInstantiatingStub = false;
8802-
info->wasArrayInterfaceDevirt = false;
8802+
info->needsMethodContext = false;
88038803
}
88048804

88058805
info->devirtualizedMethod = (CORINFO_METHOD_HANDLE) pDevirtMD;

0 commit comments

Comments
 (0)