Skip to content

Commit c228ca4

Browse files
committed
Spill side-effects for fat pointer handling before impPopCallArgs
1 parent 3853113 commit c228ca4

File tree

1 file changed

+25
-13
lines changed

1 file changed

+25
-13
lines changed

src/coreclr/jit/importercalls.cpp

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,27 @@ var_types Compiler::impImportCall(OPCODE opcode,
386386
{
387387
assert(!(mflags & CORINFO_FLG_STATIC)); // can't call a static method
388388
assert(!(clsFlags & CORINFO_FLG_VALUECLASS));
389+
assert(stackState.esStackDepth >= sig->numArgs + 1);
390+
391+
const bool needsFatPointerHandling =
392+
(sig->sigInst.methInstCount != 0) && IsTargetAbi(CORINFO_NATIVEAOT_ABI);
393+
if (needsFatPointerHandling)
394+
{
395+
// NativeAOT generic virtual method: need to handle potential fat function pointers
396+
// Spill any side-effecting arguments before we do the LDVIRTFTN
397+
for (unsigned argIndex = 0; argIndex < sig->numArgs; argIndex++)
398+
{
399+
const unsigned level = stackState.esStackDepth - 1 - argIndex;
400+
GenTree* argTree = stackState.esStack[level].val;
401+
if ((argTree->gtFlags & GTF_SIDE_EFFECT) == 0)
402+
{
403+
continue;
404+
}
405+
406+
impSpillStackEntry(level, BAD_VAR_NUM DEBUGARG(false) DEBUGARG("fat pointer arg spill"));
407+
}
408+
}
409+
389410
// OK, We've been told to call via LDVIRTFTN, so just
390411
// take the call now....
391412
call = gtNewIndCallNode(nullptr, callRetTyp, di);
@@ -421,9 +442,11 @@ var_types Compiler::impImportCall(OPCODE opcode,
421442
call->AsCall()->gtCallAddr = fptr;
422443
call->gtFlags |= GTF_EXCEPT | (fptr->gtFlags & GTF_GLOB_EFFECT);
423444

424-
if ((sig->sigInst.methInstCount != 0) && IsTargetAbi(CORINFO_NATIVEAOT_ABI))
445+
if (needsFatPointerHandling)
425446
{
426-
// NativeAOT generic virtual method: need to handle potential fat function pointers
447+
const unsigned fptrLclNum = lvaGrabTemp(true DEBUGARG("fat pointer temp"));
448+
impStoreToTemp(fptrLclNum, fptr, CHECK_SPILL_ALL);
449+
call->AsCall()->gtCallAddr = gtNewLclvNode(fptrLclNum, genActualType(fptr->TypeGet()));
427450
addFatPointerCandidate(call->AsCall());
428451
}
429452
#ifdef FEATURE_READYTORUN
@@ -6943,17 +6966,6 @@ void Compiler::addFatPointerCandidate(GenTreeCall* call)
69436966
{
69446967
JITDUMP("Marking call [%06u] as fat pointer candidate\n", dspTreeID(call));
69456968

6946-
GenTree* fptr = call->gtCallAddr;
6947-
assert(fptr != nullptr);
6948-
if (!fptr->OperIsLocalRead())
6949-
{
6950-
// Spill the call address to a local for fat pointer handling
6951-
const unsigned fptrLclNum = lvaGrabTemp(true DEBUGARG("fat pointer temp"));
6952-
impStoreToTemp(fptrLclNum, fptr, CHECK_SPILL_ALL);
6953-
fptr = gtNewLclvNode(fptrLclNum, genActualType(fptr->TypeGet()));
6954-
call->gtCallAddr = fptr;
6955-
}
6956-
69576969
setMethodHasFatPointer();
69586970
call->SetFatPointerCandidate();
69596971
SpillRetExprHelper helper(this);

0 commit comments

Comments
 (0)