@@ -20,6 +20,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2020#include " lower.h"
2121#include " gcinfo.h"
2222#include " gcinfoencoder.h"
23+ #include " patchpointinfo.h"
2324
2425/*
2526XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
@@ -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