Skip to content

Commit 0b6bb45

Browse files
am11jakobbotsch
andauthored
Remove unwind calls from patchpoint OSR transition (dotnet#127213)
Follow-up on dotnet#123645 (comment). --------- Co-authored-by: Jakob Botsch Nielsen <Jakob.botsch.nielsen@gmail.com>
1 parent 6959e10 commit 0b6bb45

23 files changed

Lines changed: 246 additions & 139 deletions

src/coreclr/jit/codegen.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,7 @@ class CodeGen final : public CodeGenInterface
13041304

13051305
void genReturn(GenTree* treeNode);
13061306
void genReturnSuspend(GenTreeUnOp* treeNode);
1307+
void genPatchpoint(GenTreeOp* treeNode);
13071308
void genMarkReturnGCInfo();
13081309

13091310
#ifdef SWIFT_SUPPORT

src/coreclr/jit/codegenarmarch.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,11 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
295295
break;
296296
#endif // SWIFT_SUPPORT
297297

298+
case GT_PATCHPOINT:
299+
case GT_PATCHPOINT_FORCED:
300+
genPatchpoint(treeNode->AsOp());
301+
break;
302+
298303
case GT_LEA:
299304
// If we are here, it is the case where there is an LEA that cannot be folded into a parent instruction.
300305
genLeaInstruction(treeNode->AsAddrMode());

src/coreclr/jit/codegencommon.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7304,6 +7304,61 @@ void CodeGen::genReturnSuspend(GenTreeUnOp* treeNode)
73047304
genMarkReturnGCInfo();
73057305
}
73067306

7307+
//------------------------------------------------------------------------
7308+
// genPatchpoint:
7309+
// Generate code for GT_PATCHPOINT / GT_PATCHPOINT_FORCED nodes.
7310+
// Emits a call to the patchpoint helper followed by an unconditional jump
7311+
// to the returned address.
7312+
//
7313+
// Arguments:
7314+
// treeNode - The patchpoint node (GT_PATCHPOINT or GT_PATCHPOINT_FORCED)
7315+
//
7316+
void CodeGen::genPatchpoint(GenTreeOp* treeNode)
7317+
{
7318+
assert(treeNode->OperIs(GT_PATCHPOINT, GT_PATCHPOINT_FORCED));
7319+
7320+
genConsumeOperands(treeNode);
7321+
7322+
// Move operands into the expected argument registers if needed.
7323+
genCopyRegIfNeeded(treeNode->gtGetOp1(), REG_ARG_0);
7324+
if (treeNode->OperIs(GT_PATCHPOINT))
7325+
{
7326+
genCopyRegIfNeeded(treeNode->gtGetOp2(), REG_ARG_1);
7327+
}
7328+
7329+
CorInfoHelpFunc helper = treeNode->OperIs(GT_PATCHPOINT) ? CORINFO_HELP_PATCHPOINT : CORINFO_HELP_PATCHPOINT_FORCED;
7330+
7331+
genEmitHelperCall(helper, 0, EA_UNKNOWN);
7332+
7333+
// On non-x64 targets, mark the method as having tail calls so that
7334+
// return-address hijacking is disabled — after the jump the return
7335+
// address may have moved in the frame and unhijacking will write
7336+
// to the wrong slot.
7337+
// On x64 this is unnecessary because the return address is always at
7338+
// the same stack slot regardless of tail calls.
7339+
#ifndef TARGET_XARCH
7340+
SetHasTailCalls(true);
7341+
#endif
7342+
7343+
// Jump to the address returned by the patchpoint helper.
7344+
// Must not use INS_tail_i_jmp: it is a REX-prefixed jump that the
7345+
// win-x64 unwinder detects as an epilog instruction, which would
7346+
// incorrectly signal that callee saves / RSP have been restored.
7347+
#ifdef TARGET_XARCH
7348+
GetEmitter()->emitIns_R(INS_i_jmp, EA_PTRSIZE, REG_INTRET);
7349+
#elif defined(TARGET_ARM64)
7350+
GetEmitter()->emitIns_R(INS_br, EA_PTRSIZE, REG_INTRET);
7351+
#elif defined(TARGET_ARM)
7352+
GetEmitter()->emitIns_R(INS_bx, EA_PTRSIZE, REG_INTRET);
7353+
#elif defined(TARGET_LOONGARCH64)
7354+
GetEmitter()->emitIns_R_R_I(INS_jirl, EA_PTRSIZE, REG_R0, REG_INTRET, 0);
7355+
#elif defined(TARGET_RISCV64)
7356+
GetEmitter()->emitIns_R_R_I(INS_jalr, EA_PTRSIZE, REG_R0, REG_INTRET, 0);
7357+
#else
7358+
#error "Unsupported target architecture for GT_PATCHPOINT"
7359+
#endif
7360+
}
7361+
73077362
//------------------------------------------------------------------------
73087363
// genMarkReturnGCInfo:
73097364
// Mark GC and non-GC pointers of return registers going into the epilog..

src/coreclr/jit/codegenloongarch64.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4491,6 +4491,11 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
44914491
// Do nothing; this node is a marker for debug info.
44924492
break;
44934493

4494+
case GT_PATCHPOINT:
4495+
case GT_PATCHPOINT_FORCED:
4496+
genPatchpoint(treeNode->AsOp());
4497+
break;
4498+
44944499
default:
44954500
{
44964501
#ifdef DEBUG

src/coreclr/jit/codegenriscv64.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4277,6 +4277,11 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
42774277
// Do nothing; this node is a marker for debug info.
42784278
break;
42794279

4280+
case GT_PATCHPOINT:
4281+
case GT_PATCHPOINT_FORCED:
4282+
genPatchpoint(treeNode->AsOp());
4283+
break;
4284+
42804285
case GT_SH1ADD:
42814286
case GT_SH1ADD_UW:
42824287
case GT_SH2ADD:

src/coreclr/jit/codegenxarch.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,6 +1925,11 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
19251925
break;
19261926
#endif // SWIFT_SUPPORT
19271927

1928+
case GT_PATCHPOINT:
1929+
case GT_PATCHPOINT_FORCED:
1930+
genPatchpoint(treeNode->AsOp());
1931+
break;
1932+
19281933
case GT_LEA:
19291934
// If we are here, it is the case where there is an LEA that cannot be folded into a parent instruction.
19301935
genLeaInstruction(treeNode->AsAddrMode());

src/coreclr/jit/compiler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12565,6 +12565,7 @@ class GenTreeVisitor
1256512565
case GT_FIELD_ADDR:
1256612566
case GT_RETURN:
1256712567
case GT_RETURN_SUSPEND:
12568+
case GT_PATCHPOINT_FORCED:
1256812569
case GT_NONLOCAL_JMP:
1256912570
case GT_RETFILT:
1257012571
case GT_RUNTIMELOOKUP:

src/coreclr/jit/compiler.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4479,6 +4479,7 @@ GenTree::VisitResult GenTree::VisitOperandUses(TVisitor visitor)
44794479
case GT_KEEPALIVE:
44804480
case GT_INC_SATURATE:
44814481
case GT_RETURN_SUSPEND:
4482+
case GT_PATCHPOINT_FORCED:
44824483
case GT_NONLOCAL_JMP:
44834484
return visitor(&this->AsUnOp()->gtOp1);
44844485

src/coreclr/jit/fgstmt.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,8 @@ inline bool OperIsControlFlow(genTreeOps oper)
593593
case GT_RETFILT:
594594
case GT_SWIFT_ERROR_RET:
595595
case GT_RETURN_SUSPEND:
596+
case GT_PATCHPOINT:
597+
case GT_PATCHPOINT_FORCED:
596598
case GT_NONLOCAL_JMP:
597599

598600
case GT_WASM_JEXCEPT:

src/coreclr/jit/gentree.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8076,6 +8076,7 @@ bool GenTree::TryGetUse(GenTree* operand, GenTree*** pUse)
80768076
case GT_RETURN:
80778077
case GT_RETFILT:
80788078
case GT_RETURN_SUSPEND:
8079+
case GT_PATCHPOINT_FORCED:
80798080
case GT_NONLOCAL_JMP:
80808081
case GT_BSWAP:
80818082
case GT_BSWAP16:
@@ -8348,6 +8349,8 @@ bool GenTree::OperRequiresCallFlag(Compiler* comp) const
83488349
case GT_KEEPALIVE:
83498350
case GT_ASYNC_CONTINUATION:
83508351
case GT_RETURN_SUSPEND:
8352+
case GT_PATCHPOINT:
8353+
case GT_PATCHPOINT_FORCED:
83518354
case GT_NONLOCAL_JMP:
83528355
return true;
83538356

@@ -8692,6 +8695,8 @@ bool GenTree::OperRequiresGlobRefFlag(Compiler* comp) const
86928695
case GT_KEEPALIVE:
86938696
case GT_ASYNC_CONTINUATION:
86948697
case GT_RETURN_SUSPEND:
8698+
case GT_PATCHPOINT:
8699+
case GT_PATCHPOINT_FORCED:
86958700
case GT_NONLOCAL_JMP:
86968701
case GT_SWIFT_ERROR:
86978702
case GT_GCPOLL:
@@ -8758,6 +8763,8 @@ bool GenTree::OperSupportsOrderingSideEffect() const
87588763
case GT_CATCH_ARG:
87598764
case GT_ASYNC_CONTINUATION:
87608765
case GT_RETURN_SUSPEND:
8766+
case GT_PATCHPOINT:
8767+
case GT_PATCHPOINT_FORCED:
87618768
case GT_NONLOCAL_JMP:
87628769
case GT_SWIFT_ERROR:
87638770
return true;
@@ -11737,6 +11744,7 @@ GenTreeUseEdgeIterator::GenTreeUseEdgeIterator(GenTree* node)
1173711744
case GT_INC_SATURATE:
1173811745
case GT_RETURNTRAP:
1173911746
case GT_RETURN_SUSPEND:
11747+
case GT_PATCHPOINT_FORCED:
1174011748
case GT_NONLOCAL_JMP:
1174111749
m_edge = &m_node->AsUnOp()->gtOp1;
1174211750
assert(*m_edge != nullptr);

0 commit comments

Comments
 (0)