the stack check fails, we can just push the PAP on the stack and
return to the scheduler.
- On entry: R1 points to the PAP. The rest of the function's arguments
- (*all* of 'em) are on the stack, starting at Sp[0].
+ On entry: R1 points to the PAP. The rest of the function's
+ arguments (apart from those that are already in the PAP) are on the
+ stack, starting at Sp[0]. R2 contains an info table which
+ describes these arguments, which is used in the event that the
+ stack check in the entry code below fails. The info table is
+ currently one of the stg_ap_*_ret family, as this code is always
+ entered from those functions.
The idea is to copy the chunk of stack from the PAP object onto the
stack / into registers, and enter the function.
// We have a hand-rolled stack check fragment here, because none of
// the canned ones suit this situation.
if ((Sp - Words) < SpLim) {
- // there is a return address on the stack in the event of a
+ // there is a return address in R2 in the event of a
// stack check failure. The various stg_apply functions arrange
// this before calling stg_PAP_entry.
+ Sp--;
+ Sp[0] = R2.w;
JMP_(stg_gc_unpt_r1);
}
- // Sp is already pointing one word below the arguments...
- Sp -= Words-1;
+ Sp -= Words;
// profiling
TICK_ENT_PAP(pap);
Words = ap->n_args;
- // Check for stack overflow.
- STK_CHK_GEN(Words+sizeofW(StgUpdateFrame), R1_PTR, stg_AP_entry);
+ // Check for stack overflow. IMPORTANT: use a _NP check here,
+ // because if the check fails, we might end up blackholing this very
+ // closure, in which case we must enter the blackhole on return rather
+ // than continuing to evaluate the now-defunct closure.
+ STK_CHK_NP(Words+sizeofW(StgUpdateFrame),);
PUSH_UPD_FRAME(R1.p, 0);
Sp -= sizeofW(StgUpdateFrame) + Words;
Words = ap->size;
- // Check for stack overflow.
- STK_CHK_GEN(Words+sizeofW(StgUpdateFrame), R1_PTR, stg_AP_STACK_entry);
+ // Check for stack overflow. IMPORTANT: use a _NP check here,
+ // because if the check fails, we might end up blackholing this very
+ // closure, in which case we must enter the blackhole on return rather
+ // than continuing to evaluate the now-defunct closure.
+ STK_CHK_NP(Words+sizeofW(StgUpdateFrame),);
PUSH_UPD_FRAME(R1.p, 0);
Sp -= sizeofW(StgUpdateFrame) + Words;