X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FApply.hc;h=30fbb5017b8ed05edebea1e6bd6d681bbc12136b;hb=553e90d9a32ee1b1809430f260c401cc4169c6c7;hp=fc445c9c5b068a052f4e63279ce375fb6c9ae3f1;hpb=0bffc410964e1688ad80d277d53400659e697ab5;p=ghc-hetmet.git diff --git a/ghc/rts/Apply.hc b/ghc/rts/Apply.hc index fc445c9..30fbb50 100644 --- a/ghc/rts/Apply.hc +++ b/ghc/rts/Apply.hc @@ -64,8 +64,13 @@ stg_ap_0_ret(void) 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. @@ -88,13 +93,14 @@ STGFUN(stg_PAP_entry) // 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); @@ -157,8 +163,11 @@ STGFUN(stg_AP_entry) 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; @@ -224,8 +233,11 @@ STGFUN(stg_AP_STACK_entry) 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;