@@ -1078,10 +1078,14 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
10781078 * |-----------------------|
10791079 * | incoming arguments |
10801080 * +=======================+ <---- Caller's SP
1081+ * | OSR padding | // If required
1082+ * |-----------------------|
10811083 * | Varargs regs space | // Only for varargs main functions; 64 bytes
10821084 * |-----------------------|
10831085 * |Callee saved registers | // multiple of 8 bytes
10841086 * |-----------------------|
1087+ * | MonitorAcquired | // 8 bytes; for synchronized methods
1088+ * |-----------------------|
10851089 * | PSP slot | // 8 bytes (omitted in NativeAOT ABI)
10861090 * |-----------------------|
10871091 * ~ alignment padding ~ // To make the whole frame 16 byte aligned.
@@ -1105,10 +1109,14 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
11051109 * |-----------------------|
11061110 * | incoming arguments |
11071111 * +=======================+ <---- Caller's SP
1112+ * | OSR padding | // If required
1113+ * |-----------------------|
11081114 * | Varargs regs space | // Only for varargs main functions; 64 bytes
11091115 * |-----------------------|
11101116 * |Callee saved registers | // multiple of 8 bytes
11111117 * |-----------------------|
1118+ * | MonitorAcquired | // 8 bytes; for synchronized methods
1119+ * |-----------------------|
11121120 * | PSP slot | // 8 bytes (omitted in NativeAOT ABI)
11131121 * |-----------------------|
11141122 * ~ alignment padding ~ // To make the whole frame 16 byte aligned.
@@ -1135,20 +1143,24 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
11351143 * |-----------------------|
11361144 * | incoming arguments |
11371145 * +=======================+ <---- Caller's SP
1146+ * | OSR padding | // If required
1147+ * |-----------------------|
11381148 * | Varargs regs space | // Only for varargs main functions; 64 bytes
11391149 * |-----------------------|
11401150 * |Callee saved registers | // multiple of 8 bytes
11411151 * |-----------------------|
1152+ * | MonitorAcquired | // 8 bytes; for synchronized methods
1153+ * |-----------------------|
11421154 * | PSP slot | // 8 bytes (omitted in NativeAOT ABI)
11431155 * |-----------------------|
11441156 * ~ alignment padding ~ // To make the first SP subtraction 16 byte aligned
11451157 * |-----------------------|
1146- * | Saved FP, LR | // 16 bytes
1158+ * | Saved FP, LR | // 16 bytes <-- SP after first adjustment (points at saved FP)
11471159 * |-----------------------|
11481160 * ~ alignment padding ~ // To make the whole frame 16 byte aligned (specifically, to 16-byte align the outgoing argument space).
11491161 * |-----------------------|
11501162 * | Outgoing arg space | // multiple of 8 bytes
1151- * |-----------------------| <---- Ambient SP
1163+ * |-----------------------| <---- Ambient SP (SP after second adjustment)
11521164 * | | |
11531165 * ~ | Stack grows ~
11541166 * | | downward |
@@ -1163,7 +1175,7 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
11631175 * 8 float callee-saved registers v8-v15
11641176 * 8 saved integer argument registers x0-x7, if varargs function
11651177 * 1 PSP slot
1166- * 1 alignment slot
1178+ * 1 alignment slot or monitor acquired slot
11671179 * == 30 slots * 8 bytes = 240 bytes.
11681180 *
11691181 * The outgoing argument size, however, can be very large, if we call a function that takes a large number of
@@ -1199,6 +1211,8 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
11991211 * |-----------------------|
12001212 * | incoming arguments |
12011213 * +=======================+ <---- Caller's SP
1214+ * | OSR padding | // If required
1215+ * |-----------------------|
12021216 * | Varargs regs space | // Only for varargs main functions; 64 bytes
12031217 * |-----------------------|
12041218 * | Saved LR | // 8 bytes
@@ -1207,6 +1221,8 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
12071221 * |-----------------------|
12081222 * |Callee saved registers | // multiple of 8 bytes
12091223 * |-----------------------|
1224+ * | MonitorAcquired | // 8 bytes; for synchronized methods
1225+ * |-----------------------|
12101226 * | PSP slot | // 8 bytes (omitted in NativeAOT ABI)
12111227 * |-----------------------|
12121228 * ~ alignment padding ~ // To make the whole frame 16 byte aligned.
@@ -1236,6 +1252,8 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
12361252 * |-----------------------|
12371253 * | incoming arguments |
12381254 * +=======================+ <---- Caller's SP
1255+ * | OSR padding | // If required
1256+ * |-----------------------|
12391257 * | Varargs regs space | // Only for varargs main functions; 64 bytes
12401258 * |-----------------------|
12411259 * | Saved LR | // 8 bytes
@@ -1244,14 +1262,16 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
12441262 * |-----------------------|
12451263 * |Callee saved registers | // multiple of 8 bytes
12461264 * |-----------------------|
1265+ * | MonitorAcquired | // 8 bytes; for synchronized methods
1266+ * |-----------------------|
12471267 * | PSP slot | // 8 bytes (omitted in NativeAOT ABI)
12481268 * |-----------------------|
1249- * ~ alignment padding ~ // To make the first SP subtraction 16 byte aligned
1269+ * ~ alignment padding ~ // To make the first SP subtraction 16 byte aligned <-- SP after first adjustment (points at alignment padding or PSP slot)
12501270 * |-----------------------|
12511271 * ~ alignment padding ~ // To make the whole frame 16 byte aligned (specifically, to 16-byte align the outgoing argument space).
12521272 * |-----------------------|
12531273 * | Outgoing arg space | // multiple of 8 bytes
1254- * |-----------------------| <---- Ambient SP
1274+ * |-----------------------| <---- Ambient SP (SP after second adjustment)
12551275 * | | |
12561276 * ~ | Stack grows ~
12571277 * | | downward |
@@ -1311,6 +1331,8 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
13111331 * ldp fp,lr,[sp],#framesz
13121332 * ret lr
13131333 *
1334+ * See CodeGen::genPushCalleeSavedRegisters() for a description of the main function frame layout.
1335+ * See Compiler::lvaAssignVirtualFrameOffsetsToLocals() for calculation of main frame local variable offsets.
13141336 */
13151337// clang-format on
13161338
@@ -1504,6 +1526,8 @@ void CodeGen::genFuncletProlog(BasicBlock* block)
15041526/* ****************************************************************************
15051527 *
15061528 * Generates code for an EH funclet epilog.
1529+ *
1530+ * See the description of frame shapes at genFuncletProlog().
15071531 */
15081532
15091533void CodeGen::genFuncletEpilog ()
@@ -1711,43 +1735,50 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
17111735 assert (compiler->lvaOutgoingArgSpaceSize % REGSIZE_BYTES == 0 );
17121736 unsigned const outgoingArgSpaceAligned = roundUp (compiler->lvaOutgoingArgSpaceSize , STACK_ALIGN);
17131737
1714- unsigned const maxFuncletFrameSizeAligned = osrPad + saveRegsPlusPSPSizeAligned + outgoingArgSpaceAligned;
1715- assert ((maxFuncletFrameSizeAligned % STACK_ALIGN) == 0 );
1738+ // If do two SP adjustments, each one must be aligned. This represents the largest possible stack size, if two
1739+ // separate alignment slots are required.
1740+ unsigned const twoSpAdjustmentFuncletFrameSizeAligned =
1741+ osrPad + saveRegsPlusPSPSizeAligned + outgoingArgSpaceAligned;
1742+ assert ((twoSpAdjustmentFuncletFrameSizeAligned % STACK_ALIGN) == 0 );
17161743
17171744 int SP_to_FPLR_save_delta;
17181745 int SP_to_PSP_slot_delta;
17191746 int CallerSP_to_PSP_slot_delta;
17201747
1721- unsigned const funcletFrameSize = osrPad + saveRegsPlusPSPSize + compiler->lvaOutgoingArgSpaceSize ;
1722- unsigned const funcletFrameSizeAligned = roundUp (funcletFrameSize, STACK_ALIGN);
1723- assert (funcletFrameSizeAligned <= maxFuncletFrameSizeAligned);
1724-
1725- unsigned const funcletFrameAlignmentPad = funcletFrameSizeAligned - funcletFrameSize;
1726- assert ((funcletFrameAlignmentPad == 0 ) || (funcletFrameAlignmentPad == REGSIZE_BYTES));
1727-
17281748 // Are we stressing frame type 5? Don't do it unless we have non-zero outgoing arg space.
17291749 const bool useFrameType5 =
17301750 genSaveFpLrWithAllCalleeSavedRegisters && genForceFuncletFrameType5 && (compiler->lvaOutgoingArgSpaceSize > 0 );
17311751
1732- if ((maxFuncletFrameSizeAligned <= 512 ) && !useFrameType5)
1752+ if ((twoSpAdjustmentFuncletFrameSizeAligned <= 512 ) && !useFrameType5)
17331753 {
1754+ unsigned const oneSpAdjustmentFuncletFrameSize =
1755+ osrPad + saveRegsPlusPSPSize + compiler->lvaOutgoingArgSpaceSize ;
1756+ unsigned const oneSpAdjustmentFuncletFrameSizeAligned = roundUp (oneSpAdjustmentFuncletFrameSize, STACK_ALIGN);
1757+ assert (oneSpAdjustmentFuncletFrameSizeAligned <= twoSpAdjustmentFuncletFrameSizeAligned);
1758+
1759+ unsigned const oneSpAdjustmentFuncletFrameSizeAlignmentPad =
1760+ oneSpAdjustmentFuncletFrameSizeAligned - oneSpAdjustmentFuncletFrameSize;
1761+ assert ((oneSpAdjustmentFuncletFrameSizeAlignmentPad == 0 ) ||
1762+ (oneSpAdjustmentFuncletFrameSizeAlignmentPad == REGSIZE_BYTES));
1763+
17341764 if (genSaveFpLrWithAllCalleeSavedRegisters)
17351765 {
1736- SP_to_FPLR_save_delta = funcletFrameSizeAligned - (2 /* FP, LR */ * REGSIZE_BYTES);
1766+ SP_to_FPLR_save_delta = oneSpAdjustmentFuncletFrameSizeAligned - (2 /* FP, LR */ * REGSIZE_BYTES);
17371767 if (compiler->info .compIsVarArgs )
17381768 {
17391769 SP_to_FPLR_save_delta -= MAX_REG_ARG * REGSIZE_BYTES;
17401770 }
17411771
1742- SP_to_PSP_slot_delta = compiler->lvaOutgoingArgSpaceSize + funcletFrameAlignmentPad + osrPad ;
1772+ SP_to_PSP_slot_delta = compiler->lvaOutgoingArgSpaceSize + oneSpAdjustmentFuncletFrameSizeAlignmentPad ;
17431773 CallerSP_to_PSP_slot_delta = -(int )(osrPad + saveRegsPlusPSPSize);
17441774
17451775 genFuncletInfo.fiFrameType = 4 ;
17461776 }
17471777 else
17481778 {
17491779 SP_to_FPLR_save_delta = compiler->lvaOutgoingArgSpaceSize ;
1750- SP_to_PSP_slot_delta = SP_to_FPLR_save_delta + 2 /* FP, LR */ * REGSIZE_BYTES + funcletFrameAlignmentPad;
1780+ SP_to_PSP_slot_delta =
1781+ SP_to_FPLR_save_delta + 2 /* FP, LR */ * REGSIZE_BYTES + oneSpAdjustmentFuncletFrameSizeAlignmentPad;
17511782 CallerSP_to_PSP_slot_delta = -(int )(osrPad + saveRegsPlusPSPSize - 2 /* FP, LR */ * REGSIZE_BYTES);
17521783
17531784 if (compiler->lvaOutgoingArgSpaceSize == 0 )
@@ -1760,10 +1791,10 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
17601791 }
17611792 }
17621793
1763- genFuncletInfo.fiSpDelta1 = -(int )funcletFrameSizeAligned ;
1794+ genFuncletInfo.fiSpDelta1 = -(int )oneSpAdjustmentFuncletFrameSizeAligned ;
17641795 genFuncletInfo.fiSpDelta2 = 0 ;
17651796
1766- assert (genFuncletInfo.fiSpDelta1 + genFuncletInfo.fiSpDelta2 == -(int )funcletFrameSizeAligned );
1797+ assert (genFuncletInfo.fiSpDelta1 + genFuncletInfo.fiSpDelta2 == -(int )oneSpAdjustmentFuncletFrameSizeAligned );
17671798 }
17681799 else
17691800 {
@@ -1772,17 +1803,13 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
17721803
17731804 if (genSaveFpLrWithAllCalleeSavedRegisters)
17741805 {
1775- SP_to_FPLR_save_delta = funcletFrameSizeAligned - (2 /* FP, LR */ * REGSIZE_BYTES);
1806+ SP_to_FPLR_save_delta = twoSpAdjustmentFuncletFrameSizeAligned - (2 /* FP, LR */ * REGSIZE_BYTES);
17761807 if (compiler->info .compIsVarArgs )
17771808 {
17781809 SP_to_FPLR_save_delta -= MAX_REG_ARG * REGSIZE_BYTES;
17791810 }
17801811
1781- unsigned const outgoingArgSpaceAlignmentPad = outgoingArgSpaceAligned - compiler->lvaOutgoingArgSpaceSize ;
1782- assert ((outgoingArgSpaceAlignmentPad == 0 ) || (outgoingArgSpaceAlignmentPad == REGSIZE_BYTES));
1783-
1784- SP_to_PSP_slot_delta =
1785- compiler->lvaOutgoingArgSpaceSize + outgoingArgSpaceAlignmentPad + saveRegsPlusPSPAlignmentPad;
1812+ SP_to_PSP_slot_delta = outgoingArgSpaceAligned + saveRegsPlusPSPAlignmentPad;
17861813 CallerSP_to_PSP_slot_delta = -(int )(osrPad + saveRegsPlusPSPSize);
17871814
17881815 genFuncletInfo.fiFrameType = 5 ;
@@ -1800,7 +1827,7 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
18001827 genFuncletInfo.fiSpDelta1 = -(int )(osrPad + saveRegsPlusPSPSizeAligned);
18011828 genFuncletInfo.fiSpDelta2 = -(int )outgoingArgSpaceAligned;
18021829
1803- assert (genFuncletInfo.fiSpDelta1 + genFuncletInfo.fiSpDelta2 == -(int )maxFuncletFrameSizeAligned );
1830+ assert (genFuncletInfo.fiSpDelta1 + genFuncletInfo.fiSpDelta2 == -(int )twoSpAdjustmentFuncletFrameSizeAligned );
18041831 }
18051832
18061833 /* Now save it for future use */
0 commit comments