@@ -24,28 +24,15 @@ StackLevelSetter::StackLevelSetter(Compiler* compiler)
2424}
2525
2626// ------------------------------------------------------------------------
27- // DoPhase: Calculate stack slots numbers for outgoing args.
27+ // DoPhase: Calculate stack slots numbers for outgoing args and compute
28+ // requirements of throw helper blocks.
2829//
2930// Returns:
3031// PhaseStatus indicating what, if anything, was changed.
3132//
32- // Notes:
33- // For non-x86 platforms it calculates the max number of slots
34- // that calls inside this method can push on the stack.
35- // This value is used for sanity checks in the emitter.
36- //
37- // Stack slots are pointer-sized: 4 bytes for 32-bit platforms, 8 bytes for 64-bit platforms.
38- //
39- // For x86 it also sets throw-helper blocks incoming stack depth and set
40- // framePointerRequired when it is necessary. These values are used to pop
41- // pushed args when an exception occurs.
42- //
4333PhaseStatus StackLevelSetter::DoPhase ()
4434{
45- for (BasicBlock* const block : comp->Blocks ())
46- {
47- ProcessBlock (block);
48- }
35+ ProcessBlocks ();
4936
5037#if !FEATURE_FIXED_OUT_ARGS
5138 if (framePointerRequired)
@@ -56,7 +43,6 @@ PhaseStatus StackLevelSetter::DoPhase()
5643
5744 CheckAdditionalArgs ();
5845
59- comp->fgSetPtrArgCntMax (maxStackLevel);
6046 CheckArgCnt ();
6147
6248 // When optimizing, check if there are any unused throw helper blocks,
@@ -109,7 +95,28 @@ PhaseStatus StackLevelSetter::DoPhase()
10995}
11096
11197// ------------------------------------------------------------------------
112- // ProcessBlock: Do stack level calculations for one block.
98+ // ProcessBlocks: Process all the blocks if necessary.
99+ //
100+ void StackLevelSetter::ProcessBlocks ()
101+ {
102+ #ifndef TARGET_X86
103+ // Outside x86 we do not need to compute pushed/popped stack slots.
104+ // However, we do optimize throw-helpers and need to process the blocks for
105+ // that, but only when optimizing.
106+ if (!throwHelperBlocksUsed || comp->opts .OptimizationDisabled ())
107+ {
108+ return ;
109+ }
110+ #endif
111+
112+ for (BasicBlock* const block : comp->Blocks ())
113+ {
114+ ProcessBlock (block);
115+ }
116+ }
117+
118+ // ------------------------------------------------------------------------
119+ // ProcessBlock: Do stack level and throw helper determinations for one block.
113120//
114121// Notes:
115122// Block starts and ends with an empty outgoing stack.
@@ -125,10 +132,13 @@ PhaseStatus StackLevelSetter::DoPhase()
125132void StackLevelSetter::ProcessBlock (BasicBlock* block)
126133{
127134 assert (currentStackLevel == 0 );
135+
128136 LIR::ReadOnlyRange& range = LIR::AsRange (block);
129137 for (auto i = range.rbegin (); i != range.rend (); ++i)
130138 {
131139 GenTree* node = *i;
140+
141+ #ifdef TARGET_X86
132142 if (node->OperIsPutArgStkOrSplit ())
133143 {
134144 GenTreePutArgStk* putArg = node->AsPutArgStk ();
@@ -145,6 +155,7 @@ void StackLevelSetter::ProcessBlock(BasicBlock* block)
145155 call->gtArgs .SetStkSizeBytes (usedStackSlotsCount * TARGET_POINTER_SIZE);
146156#endif // UNIX_X86_ABI
147157 }
158+ #endif
148159
149160 if (!throwHelperBlocksUsed)
150161 {
@@ -418,7 +429,12 @@ void StackLevelSetter::SubStackLevel(unsigned value)
418429//
419430void StackLevelSetter::CheckArgCnt ()
420431{
421- if (!comp->compCanEncodePtrArgCntMax ())
432+ #ifdef JIT32_GCENCODER
433+ // The GC encoding for fully interruptible methods does not
434+ // support more than 1023 pushed arguments, so we have to
435+ // use a partially interruptible GC info/encoding.
436+ //
437+ if (maxStackLevel >= MAX_PTRARG_OFS)
422438 {
423439#ifdef DEBUG
424440 if (comp->verbose )
@@ -429,6 +445,7 @@ void StackLevelSetter::CheckArgCnt()
429445#endif
430446 comp->SetInterruptible (false );
431447 }
448+
432449 if (maxStackLevel >= sizeof (unsigned ))
433450 {
434451#ifdef DEBUG
@@ -439,6 +456,7 @@ void StackLevelSetter::CheckArgCnt()
439456#endif
440457 comp->codeGen ->setFramePointerRequired (true );
441458 }
459+ #endif
442460}
443461
444462// ------------------------------------------------------------------------
0 commit comments