X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FThreadPaused.c;h=2a3f3559966006b2435c526b93352a741ce75da5;hb=83adb5d625b3821ff3bd29596437a780db8fa98f;hp=5b64f76ff29aeb8766b26c74e32a6c3f71c5d8f5;hpb=a1e3066e066f0f75da361f881b2f3198e0aada5f;p=ghc-hetmet.git diff --git a/rts/ThreadPaused.c b/rts/ThreadPaused.c index 5b64f76..2a3f355 100644 --- a/rts/ThreadPaused.c +++ b/rts/ThreadPaused.c @@ -50,7 +50,7 @@ stackSqueeze(StgTSO *tso, StgPtr bottom) current_gap_size = 0; gap = (struct stack_gap *) (tso->sp - sizeofW(StgUpdateFrame)); - while (frame < bottom) { + while (frame <= bottom) { info = get_ret_itbl((StgClosure *)frame); switch (info->i.type) { @@ -195,6 +195,10 @@ threadPaused(Capability *cap, StgTSO *tso) maybePerformBlockedException (cap, tso); if (tso->what_next == ThreadKilled) { return; } + // NB. Blackholing is *not* optional, we must either do lazy + // blackholing, or eager blackholing consistently. See Note + // [upd-black-hole] in sm/Scav.c. + stack_end = &tso->stack[tso->stack_size]; frame = (StgClosure *)tso->sp; @@ -202,6 +206,11 @@ threadPaused(Capability *cap, StgTSO *tso) while (1) { // If we've already marked this frame, then stop here. if (frame->header.info == (StgInfoTable *)&stg_marked_upd_frame_info) { + if (prev_was_update_frame) { + words_to_squeeze += sizeofW(StgUpdateFrame); + weight += weight_pending; + weight_pending = 0; + } goto end; } @@ -226,8 +235,10 @@ threadPaused(Capability *cap, StgTSO *tso) (long)((StgPtr)frame - tso->sp)); // If this closure is already an indirection, then - // suspend the computation up to this point: - suspendComputation(cap,tso,(StgPtr)frame); + // suspend the computation up to this point. + // NB. check raiseAsync() to see what happens when + // we're in a loop (#2783). + suspendComputation(cap,tso,(StgUpdateFrame*)frame); // Now drop the update frame, and arrange to return // the value to the frame underneath: @@ -237,14 +248,12 @@ threadPaused(Capability *cap, StgTSO *tso) // And continue with threadPaused; there might be // yet more computation to suspend. - threadPaused(cap,tso); - return; + frame = (StgClosure *)tso->sp + 2; + prev_was_update_frame = rtsFalse; + continue; } if (bh->header.info != &stg_CAF_BLACKHOLE_info) { -#if (!defined(LAZY_BLACKHOLING)) && defined(DEBUG) - debugBelch("Unexpected lazy BHing required at 0x%04lx\n",(long)bh); -#endif // zero out the slop so that the sanity checker can tell // where the next closure is. DEBUG_FILL_SLOP(bh); @@ -253,7 +262,7 @@ threadPaused(Capability *cap, StgTSO *tso) // We pretend that bh is now dead. LDV_recordDead_FILL_SLOP_DYNAMIC((StgClosure *)bh); #endif - + // an EAGER_BLACKHOLE gets turned into a BLACKHOLE here. #ifdef THREADED_RTS cur_bh_info = (const StgInfoTable *) cas((StgVolatilePtr)&bh->header.info, @@ -305,7 +314,7 @@ end: // the number of words we have to shift down is less than the // number of stack words we squeeze away by doing so. if (RtsFlags.GcFlags.squeezeUpdFrames == rtsTrue && - weight < words_to_squeeze) { + ((weight <= 5 && words_to_squeeze > 0) || weight < words_to_squeeze)) { stackSqueeze(tso, (StgPtr)frame); } }