Skip to content

Commit 0206926

Browse files
authored
OSR support for Arm64 (#62831)
* OSR support for Arm64 Enable OSR for Arm64: * rename `FpToSpDelta` in `PatchpointInfo` to `TotalFrameSize` so it makes sense for both x64 and Arm64. * make it clear that the local offsets in `PatchpointInfo` are virtual (relative to the top of the frame). Adjust recorded Arm64 offsets to match. * add new jit config setting `JitEnableOSRRange` to allow selectively enabling OSR for only a subset of jitted methods. * Arm64 OSR method is passed Tier0 SP but not Tier0 FP, as Tier0 FP can point either at top or bottom of Tier0 frame depending on frame type. For Arm64 the OSR method establishes its own FP that chains to caller FP. (I will likely revise x64 to work this way too, as it makes simple FP chain stackwalks work out better). * The Arm64 OSR epilog gets an extra SP adjustment to remove the Tier0 frame. * The Arm64 OSR prolog gets a phantom SP adjustment in unwind to account for being passed the Tier0 SP. * pad OSR funclet frames with tier0 frame size so `PSPSym` ends up at the same caller-SP relative offset as the OSR frame * handle the large `fiSpDelta1` offsets from the funclet frame padding * local/arg init for the OSR frame from the Tier0 frame was moved into a new method `genEnregisterOSRArgsAndLocals`; implemented the ARM64 version. * sequencing of this initialization in the prolog reordered slightly to prevent inadvertent clobbering. * comments/code that referred to `original` or `old` method were revised to instead try and consistently use `tier0`. * support the mixed-altjit case for OSR by allocating a local copy of the patchpoint info with similar and plausible information. * add symbol table note for locals in OSR methods that live on the Tier0 frame. * fix `fgIsThrowHlpBlk` when called on an empty block * broaden the jit-experimental testing matrix to include Arm64.
1 parent a3aec10 commit 0206926

File tree

13 files changed

+589
-235
lines changed

13 files changed

+589
-235
lines changed

eng/pipelines/coreclr/jit-experimental.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ jobs:
1515
jobTemplate: /eng/pipelines/common/build-coreclr-and-libraries-job.yml
1616
buildConfig: checked
1717
platforms:
18+
- OSX_arm64
19+
- OSX_x64
20+
- Linux_arm64
1821
- Linux_x64
22+
- windows_arm64
1923
- windows_x64
2024
- CoreClrTestBuildHost # Either OSX_x64 or Linux_x64
2125
jobParameters:
@@ -35,7 +39,11 @@ jobs:
3539
jobTemplate: /eng/pipelines/common/templates/runtimes/run-test-job.yml
3640
buildConfig: checked
3741
platforms:
42+
- OSX_arm64
43+
- OSX_x64
44+
- Linux_arm64
3845
- Linux_x64
46+
- windows_arm64
3947
- windows_x64
4048
helixQueueGroup: ci
4149
helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml

src/coreclr/clrdefinitions.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,9 @@ endif(FEATURE_ENABLE_NO_ADDRESS_SPACE_RANDOMIZATION)
179179
add_definitions(-DFEATURE_SVR_GC)
180180
add_definitions(-DFEATURE_SYMDIFF)
181181
add_compile_definitions(FEATURE_TIERED_COMPILATION)
182-
if (CLR_CMAKE_TARGET_ARCH_AMD64)
182+
if (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
183183
add_compile_definitions(FEATURE_ON_STACK_REPLACEMENT)
184-
endif (CLR_CMAKE_TARGET_ARCH_AMD64)
184+
endif (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
185185
add_compile_definitions(FEATURE_PGO)
186186
if (CLR_CMAKE_TARGET_WIN32)
187187
add_definitions(-DFEATURE_TYPEEQUIVALENCE)

src/coreclr/inc/patchpointinfo.h

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
// --------------------------------------------------------------------------------
1414
// Describes information needed to make an OSR transition
1515
// - location of Il-visible locals and other important state on the
16-
// original (Tier0) method frame
17-
// - total size of the original frame, and SP-FP delta
16+
// original (Tier0) method frame, with respect to top of frame
17+
// (hence these offsets will be negative as stack grows down)
18+
// - total size of the original frame
1819
//
1920
// Currently the patchpoint info is independent of the IL offset of the patchpoint.
2021
//
@@ -33,26 +34,40 @@ struct PatchpointInfo
3334
}
3435

3536
// Initialize
36-
void Initialize(unsigned localCount, int fpToSpDelta)
37+
void Initialize(unsigned localCount, int totalFrameSize)
3738
{
38-
m_fpToSpDelta = fpToSpDelta;
39+
m_totalFrameSize = totalFrameSize;
3940
m_numberOfLocals = localCount;
4041
m_genericContextArgOffset = -1;
4142
m_keptAliveThisOffset = -1;
4243
m_securityCookieOffset = -1;
4344
m_monitorAcquiredOffset = -1;
4445
}
4546

47+
// Copy
48+
void Copy(const PatchpointInfo* original)
49+
{
50+
m_genericContextArgOffset = original->m_genericContextArgOffset;
51+
m_keptAliveThisOffset = original->m_keptAliveThisOffset;
52+
m_securityCookieOffset = original->m_securityCookieOffset;
53+
m_monitorAcquiredOffset = original->m_monitorAcquiredOffset;
54+
55+
for (unsigned i = 0; i < original->m_numberOfLocals; i++)
56+
{
57+
m_offsetAndExposureData[i] = original->m_offsetAndExposureData[i];
58+
}
59+
}
60+
4661
// Total size of this patchpoint info record, in bytes
4762
unsigned PatchpointInfoSize() const
4863
{
4964
return ComputeSize(m_numberOfLocals);
5065
}
5166

52-
// FP to SP delta of the original method
53-
int FpToSpDelta() const
67+
// Total frame size of the original method
68+
int TotalFrameSize() const
5469
{
55-
return m_fpToSpDelta;
70+
return m_totalFrameSize;
5671
}
5772

5873
// Number of locals in the original method (including special locals)
@@ -154,7 +169,7 @@ struct PatchpointInfo
154169
};
155170

156171
unsigned m_numberOfLocals;
157-
int m_fpToSpDelta;
172+
int m_totalFrameSize;
158173
int m_genericContextArgOffset;
159174
int m_keptAliveThisOffset;
160175
int m_securityCookieOffset;

src/coreclr/jit/codegen.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,11 @@ class CodeGen final : public CodeGenInterface
255255
void genEstablishFramePointer(int delta, bool reportUnwindData);
256256
void genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbered, RegState* regState);
257257
void genEnregisterIncomingStackArgs();
258+
#if defined(TARGET_ARM64)
259+
void genEnregisterOSRArgsAndLocals(regNumber initReg, bool* pInitRegZeroed);
260+
#else
261+
void genEnregisterOSRArgsAndLocals();
262+
#endif
258263
void genCheckUseBlockInit();
259264
#if defined(UNIX_AMD64_ABI) && defined(FEATURE_SIMD)
260265
void genClearStackVec3ArgUpperBits();

src/coreclr/jit/codegenarm64.cpp

Lines changed: 112 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2020
#include "lower.h"
2121
#include "gcinfo.h"
2222
#include "gcinfoencoder.h"
23+
#include "patchpointinfo.h"
2324

2425
/*
2526
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
@@ -1113,9 +1114,20 @@ void CodeGen::genFuncletProlog(BasicBlock* block)
11131114

11141115
if (genFuncletInfo.fiFrameType == 1)
11151116
{
1116-
GetEmitter()->emitIns_R_R_R_I(INS_stp, EA_PTRSIZE, REG_FP, REG_LR, REG_SPBASE, genFuncletInfo.fiSpDelta1,
1117-
INS_OPTS_PRE_INDEX);
1118-
compiler->unwindSaveRegPairPreindexed(REG_FP, REG_LR, genFuncletInfo.fiSpDelta1);
1117+
// With OSR we may see large values for fiSpDelta1
1118+
// (we really need to probe the frame, sigh)
1119+
if (compiler->opts.IsOSR())
1120+
{
1121+
genStackPointerAdjustment(genFuncletInfo.fiSpDelta1, REG_SCRATCH, nullptr, /* reportUnwindData */ true);
1122+
GetEmitter()->emitIns_R_R_R_I(INS_stp, EA_PTRSIZE, REG_FP, REG_LR, REG_SPBASE, 0);
1123+
compiler->unwindSaveRegPair(REG_FP, REG_LR, 0);
1124+
}
1125+
else
1126+
{
1127+
GetEmitter()->emitIns_R_R_R_I(INS_stp, EA_PTRSIZE, REG_FP, REG_LR, REG_SPBASE, genFuncletInfo.fiSpDelta1,
1128+
INS_OPTS_PRE_INDEX);
1129+
compiler->unwindSaveRegPairPreindexed(REG_FP, REG_LR, genFuncletInfo.fiSpDelta1);
1130+
}
11191131

11201132
maskSaveRegsInt &= ~(RBM_LR | RBM_FP); // We've saved these now
11211133

@@ -1141,9 +1153,20 @@ void CodeGen::genFuncletProlog(BasicBlock* block)
11411153
}
11421154
else if (genFuncletInfo.fiFrameType == 3)
11431155
{
1144-
GetEmitter()->emitIns_R_R_R_I(INS_stp, EA_PTRSIZE, REG_FP, REG_LR, REG_SPBASE, genFuncletInfo.fiSpDelta1,
1145-
INS_OPTS_PRE_INDEX);
1146-
compiler->unwindSaveRegPairPreindexed(REG_FP, REG_LR, genFuncletInfo.fiSpDelta1);
1156+
// With OSR we may see large values for fiSpDelta1
1157+
// (we really need to probe the frame, sigh)
1158+
if (compiler->opts.IsOSR())
1159+
{
1160+
genStackPointerAdjustment(genFuncletInfo.fiSpDelta1, REG_SCRATCH, nullptr, /* reportUnwindData */ true);
1161+
GetEmitter()->emitIns_R_R_R_I(INS_stp, EA_PTRSIZE, REG_FP, REG_LR, REG_SPBASE, 0);
1162+
compiler->unwindSaveRegPair(REG_FP, REG_LR, 0);
1163+
}
1164+
else
1165+
{
1166+
GetEmitter()->emitIns_R_R_R_I(INS_stp, EA_PTRSIZE, REG_FP, REG_LR, REG_SPBASE, genFuncletInfo.fiSpDelta1,
1167+
INS_OPTS_PRE_INDEX);
1168+
compiler->unwindSaveRegPairPreindexed(REG_FP, REG_LR, genFuncletInfo.fiSpDelta1);
1169+
}
11471170

11481171
maskSaveRegsInt &= ~(RBM_LR | RBM_FP); // We've saved these now
11491172
}
@@ -1171,17 +1194,25 @@ void CodeGen::genFuncletProlog(BasicBlock* block)
11711194

11721195
if ((genFuncletInfo.fiFrameType == 3) || (genFuncletInfo.fiFrameType == 5))
11731196
{
1174-
// Note that genFuncletInfo.fiSpDelta2 is always a negative value
1175-
assert(genFuncletInfo.fiSpDelta2 < 0);
1197+
// Note that genFuncletInfo.fiSpDelta2 is always a non-positive value
1198+
assert(genFuncletInfo.fiSpDelta2 <= 0);
11761199

11771200
// generate sub SP,SP,imm
1178-
genStackPointerAdjustment(genFuncletInfo.fiSpDelta2, REG_R2, nullptr, /* reportUnwindData */ true);
1201+
if (genFuncletInfo.fiSpDelta2 < 0)
1202+
{
1203+
genStackPointerAdjustment(genFuncletInfo.fiSpDelta2, REG_R2, nullptr, /* reportUnwindData */ true);
1204+
}
1205+
else
1206+
{
1207+
// we will only see fiSpDelta2 == 0 for osr funclets
1208+
assert(compiler->opts.IsOSR());
1209+
}
11791210
}
11801211

11811212
// This is the end of the OS-reported prolog for purposes of unwinding
11821213
compiler->unwindEndProlog();
11831214

1184-
// If there is no PSPSym (CoreRT ABI), we are done. Otherwise, we need to set up the PSPSym in the functlet frame.
1215+
// If there is no PSPSym (CoreRT ABI), we are done. Otherwise, we need to set up the PSPSym in the funclet frame.
11851216
if (compiler->lvaPSPSym != BAD_VAR_NUM)
11861217
{
11871218
if (isFilter)
@@ -1252,11 +1283,19 @@ void CodeGen::genFuncletEpilog()
12521283

12531284
if ((genFuncletInfo.fiFrameType == 3) || (genFuncletInfo.fiFrameType == 5))
12541285
{
1255-
// Note that genFuncletInfo.fiSpDelta2 is always a negative value
1256-
assert(genFuncletInfo.fiSpDelta2 < 0);
1286+
// Note that genFuncletInfo.fiSpDelta2 is always a non-positive value
1287+
assert(genFuncletInfo.fiSpDelta2 <= 0);
12571288

12581289
// generate add SP,SP,imm
1259-
genStackPointerAdjustment(-genFuncletInfo.fiSpDelta2, REG_R2, nullptr, /* reportUnwindData */ true);
1290+
if (genFuncletInfo.fiSpDelta2 < 0)
1291+
{
1292+
genStackPointerAdjustment(-genFuncletInfo.fiSpDelta2, REG_R2, nullptr, /* reportUnwindData */ true);
1293+
}
1294+
else
1295+
{
1296+
// we should only zee zero SpDelta2 with osr.
1297+
assert(compiler->opts.IsOSR());
1298+
}
12601299
}
12611300

12621301
regMaskTP regsToRestoreMask = maskRestoreRegsInt | maskRestoreRegsFloat;
@@ -1269,9 +1308,21 @@ void CodeGen::genFuncletEpilog()
12691308

12701309
if (genFuncletInfo.fiFrameType == 1)
12711310
{
1272-
GetEmitter()->emitIns_R_R_R_I(INS_ldp, EA_PTRSIZE, REG_FP, REG_LR, REG_SPBASE, -genFuncletInfo.fiSpDelta1,
1273-
INS_OPTS_POST_INDEX);
1274-
compiler->unwindSaveRegPairPreindexed(REG_FP, REG_LR, genFuncletInfo.fiSpDelta1);
1311+
// With OSR we may see large values for fiSpDelta1
1312+
//
1313+
if (compiler->opts.IsOSR())
1314+
{
1315+
GetEmitter()->emitIns_R_R_R_I(INS_ldp, EA_PTRSIZE, REG_FP, REG_LR, REG_SPBASE, 0);
1316+
compiler->unwindSaveRegPair(REG_FP, REG_LR, 0);
1317+
1318+
genStackPointerAdjustment(-genFuncletInfo.fiSpDelta1, REG_SCRATCH, nullptr, /* reportUnwindData */ true);
1319+
}
1320+
else
1321+
{
1322+
GetEmitter()->emitIns_R_R_R_I(INS_ldp, EA_PTRSIZE, REG_FP, REG_LR, REG_SPBASE, -genFuncletInfo.fiSpDelta1,
1323+
INS_OPTS_POST_INDEX);
1324+
compiler->unwindSaveRegPairPreindexed(REG_FP, REG_LR, genFuncletInfo.fiSpDelta1);
1325+
}
12751326

12761327
assert(genFuncletInfo.fiSpDelta2 == 0);
12771328
assert(genFuncletInfo.fiSP_to_FPLR_save_delta == 0);
@@ -1293,9 +1344,21 @@ void CodeGen::genFuncletEpilog()
12931344
}
12941345
else if (genFuncletInfo.fiFrameType == 3)
12951346
{
1296-
GetEmitter()->emitIns_R_R_R_I(INS_ldp, EA_PTRSIZE, REG_FP, REG_LR, REG_SPBASE, -genFuncletInfo.fiSpDelta1,
1297-
INS_OPTS_POST_INDEX);
1298-
compiler->unwindSaveRegPairPreindexed(REG_FP, REG_LR, genFuncletInfo.fiSpDelta1);
1347+
// With OSR we may see large values for fiSpDelta1
1348+
//
1349+
if (compiler->opts.IsOSR())
1350+
{
1351+
GetEmitter()->emitIns_R_R_R_I(INS_ldp, EA_PTRSIZE, REG_FP, REG_LR, REG_SPBASE, 0);
1352+
compiler->unwindSaveRegPair(REG_FP, REG_LR, 0);
1353+
1354+
genStackPointerAdjustment(-genFuncletInfo.fiSpDelta1, REG_SCRATCH, nullptr, /* reportUnwindData */ true);
1355+
}
1356+
else
1357+
{
1358+
GetEmitter()->emitIns_R_R_R_I(INS_ldp, EA_PTRSIZE, REG_FP, REG_LR, REG_SPBASE, -genFuncletInfo.fiSpDelta1,
1359+
INS_OPTS_POST_INDEX);
1360+
compiler->unwindSaveRegPairPreindexed(REG_FP, REG_LR, genFuncletInfo.fiSpDelta1);
1361+
}
12991362
}
13001363
else if (genFuncletInfo.fiFrameType == 4)
13011364
{
@@ -1346,14 +1409,23 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
13461409
// The frame size and offsets must be finalized
13471410
assert(compiler->lvaDoneFrameLayout == Compiler::FINAL_FRAME_LAYOUT);
13481411

1349-
genFuncletInfo.fiFunction_CallerSP_to_FP_delta = genCallerSPtoFPdelta();
1412+
unsigned const PSPSize = (compiler->lvaPSPSym != BAD_VAR_NUM) ? REGSIZE_BYTES : 0;
1413+
1414+
// Because a method and funclets must have the same caller-relative PSPSym offset,
1415+
// if there is a PSPSym, we have to pad the funclet frame size for OSR.
1416+
//
1417+
unsigned osrPad = 0;
1418+
if (compiler->opts.IsOSR() && (PSPSize > 0))
1419+
{
1420+
osrPad = compiler->info.compPatchpointInfo->TotalFrameSize();
1421+
}
1422+
1423+
genFuncletInfo.fiFunction_CallerSP_to_FP_delta = genCallerSPtoFPdelta() - osrPad;
13501424

13511425
regMaskTP rsMaskSaveRegs = regSet.rsMaskCalleeSaved;
13521426
assert((rsMaskSaveRegs & RBM_LR) != 0);
13531427
assert((rsMaskSaveRegs & RBM_FP) != 0);
13541428

1355-
unsigned PSPSize = (compiler->lvaPSPSym != BAD_VAR_NUM) ? REGSIZE_BYTES : 0;
1356-
13571429
unsigned saveRegsCount = genCountBits(rsMaskSaveRegs);
13581430
unsigned saveRegsPlusPSPSize = saveRegsCount * REGSIZE_BYTES + PSPSize;
13591431
if (compiler->info.compIsVarArgs)
@@ -1362,23 +1434,24 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
13621434
// so that they are contiguous with the incoming stack arguments.
13631435
saveRegsPlusPSPSize += MAX_REG_ARG * REGSIZE_BYTES;
13641436
}
1365-
unsigned saveRegsPlusPSPSizeAligned = roundUp(saveRegsPlusPSPSize, STACK_ALIGN);
1437+
1438+
unsigned const saveRegsPlusPSPSizeAligned = roundUp(saveRegsPlusPSPSize, STACK_ALIGN);
13661439

13671440
assert(compiler->lvaOutgoingArgSpaceSize % REGSIZE_BYTES == 0);
1368-
unsigned outgoingArgSpaceAligned = roundUp(compiler->lvaOutgoingArgSpaceSize, STACK_ALIGN);
1441+
unsigned const outgoingArgSpaceAligned = roundUp(compiler->lvaOutgoingArgSpaceSize, STACK_ALIGN);
13691442

1370-
unsigned maxFuncletFrameSizeAligned = saveRegsPlusPSPSizeAligned + outgoingArgSpaceAligned;
1443+
unsigned const maxFuncletFrameSizeAligned = saveRegsPlusPSPSizeAligned + osrPad + outgoingArgSpaceAligned;
13711444
assert((maxFuncletFrameSizeAligned % STACK_ALIGN) == 0);
13721445

13731446
int SP_to_FPLR_save_delta;
13741447
int SP_to_PSP_slot_delta;
13751448
int CallerSP_to_PSP_slot_delta;
13761449

1377-
unsigned funcletFrameSize = saveRegsPlusPSPSize + compiler->lvaOutgoingArgSpaceSize;
1378-
unsigned funcletFrameSizeAligned = roundUp(funcletFrameSize, STACK_ALIGN);
1450+
unsigned const funcletFrameSize = saveRegsPlusPSPSize + osrPad + compiler->lvaOutgoingArgSpaceSize;
1451+
unsigned const funcletFrameSizeAligned = roundUp(funcletFrameSize, STACK_ALIGN);
13791452
assert(funcletFrameSizeAligned <= maxFuncletFrameSizeAligned);
13801453

1381-
unsigned funcletFrameAlignmentPad = funcletFrameSizeAligned - funcletFrameSize;
1454+
unsigned const funcletFrameAlignmentPad = funcletFrameSizeAligned - funcletFrameSize;
13821455
assert((funcletFrameAlignmentPad == 0) || (funcletFrameAlignmentPad == REGSIZE_BYTES));
13831456

13841457
if (maxFuncletFrameSizeAligned <= 512)
@@ -1391,16 +1464,16 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
13911464
SP_to_FPLR_save_delta -= MAX_REG_ARG * REGSIZE_BYTES;
13921465
}
13931466

1394-
SP_to_PSP_slot_delta = compiler->lvaOutgoingArgSpaceSize + funcletFrameAlignmentPad;
1395-
CallerSP_to_PSP_slot_delta = -(int)saveRegsPlusPSPSize;
1467+
SP_to_PSP_slot_delta = compiler->lvaOutgoingArgSpaceSize + funcletFrameAlignmentPad + osrPad;
1468+
CallerSP_to_PSP_slot_delta = -(int)(osrPad + saveRegsPlusPSPSize);
13961469

13971470
genFuncletInfo.fiFrameType = 4;
13981471
}
13991472
else
14001473
{
14011474
SP_to_FPLR_save_delta = compiler->lvaOutgoingArgSpaceSize;
14021475
SP_to_PSP_slot_delta = SP_to_FPLR_save_delta + 2 /* FP, LR */ * REGSIZE_BYTES + funcletFrameAlignmentPad;
1403-
CallerSP_to_PSP_slot_delta = -(int)(saveRegsPlusPSPSize - 2 /* FP, LR */ * REGSIZE_BYTES);
1476+
CallerSP_to_PSP_slot_delta = -(int)(osrPad + saveRegsPlusPSPSize - 2 /* FP, LR */ * REGSIZE_BYTES);
14041477

14051478
if (compiler->lvaOutgoingArgSpaceSize == 0)
14061479
{
@@ -1432,21 +1505,21 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
14321505

14331506
SP_to_PSP_slot_delta =
14341507
compiler->lvaOutgoingArgSpaceSize + funcletFrameAlignmentPad + saveRegsPlusPSPAlignmentPad;
1435-
CallerSP_to_PSP_slot_delta = -(int)saveRegsPlusPSPSize;
1508+
CallerSP_to_PSP_slot_delta = -(int)(osrPad + saveRegsPlusPSPSize);
14361509

14371510
genFuncletInfo.fiFrameType = 5;
14381511
}
14391512
else
14401513
{
14411514
SP_to_FPLR_save_delta = outgoingArgSpaceAligned;
14421515
SP_to_PSP_slot_delta = SP_to_FPLR_save_delta + 2 /* FP, LR */ * REGSIZE_BYTES + saveRegsPlusPSPAlignmentPad;
1443-
CallerSP_to_PSP_slot_delta =
1444-
-(int)(saveRegsPlusPSPSizeAligned - 2 /* FP, LR */ * REGSIZE_BYTES - saveRegsPlusPSPAlignmentPad);
1516+
CallerSP_to_PSP_slot_delta = -(int)(osrPad + saveRegsPlusPSPSizeAligned - 2 /* FP, LR */ * REGSIZE_BYTES -
1517+
saveRegsPlusPSPAlignmentPad);
14451518

14461519
genFuncletInfo.fiFrameType = 3;
14471520
}
14481521

1449-
genFuncletInfo.fiSpDelta1 = -(int)saveRegsPlusPSPSizeAligned;
1522+
genFuncletInfo.fiSpDelta1 = -(int)(osrPad + saveRegsPlusPSPSizeAligned);
14501523
genFuncletInfo.fiSpDelta2 = -(int)outgoingArgSpaceAligned;
14511524

14521525
assert(genFuncletInfo.fiSpDelta1 + genFuncletInfo.fiSpDelta2 == -(int)maxFuncletFrameSizeAligned);
@@ -1468,7 +1541,10 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
14681541
printf(" Save regs: ");
14691542
dspRegMask(genFuncletInfo.fiSaveRegs);
14701543
printf("\n");
1471-
printf(" Function CallerSP-to-FP delta: %d\n", genFuncletInfo.fiFunction_CallerSP_to_FP_delta);
1544+
if (compiler->opts.IsOSR())
1545+
{
1546+
printf(" OSR Pad: %d\n", osrPad);
1547+
}
14721548
printf(" SP to FP/LR save location delta: %d\n", genFuncletInfo.fiSP_to_FPLR_save_delta);
14731549
printf(" SP to PSP slot delta: %d\n", genFuncletInfo.fiSP_to_PSP_slot_delta);
14741550
printf(" SP to callee-saved area delta: %d\n", genFuncletInfo.fiSP_to_CalleeSave_delta);

0 commit comments

Comments
 (0)