X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FGC.c;h=0cef213cb6b4e66919c587dbcb660eda4b5ada0f;hb=c2d428ba7d0f92d4e97eec7d5d877958689dbc55;hp=75f11a291db4bce81c13193070ddf08829953088;hpb=6d194f48d7313fa8daa004b7b3e3a55ffa52f4a9;p=ghc-hetmet.git diff --git a/ghc/rts/GC.c b/ghc/rts/GC.c index 75f11a2..0cef213 100644 --- a/ghc/rts/GC.c +++ b/ghc/rts/GC.c @@ -11,6 +11,7 @@ #include "RtsFlags.h" #include "RtsUtils.h" #include "Apply.h" +#include "OSThreads.h" #include "Storage.h" #include "LdvProfile.h" #include "Updates.h" @@ -46,6 +47,12 @@ #include +// Turn off inlining when debugging - it obfuscates things +#ifdef DEBUG +# undef STATIC_INLINE +# define STATIC_INLINE static +#endif + /* STATIC OBJECT LIST. * * During GC: @@ -434,7 +441,7 @@ GarbageCollect ( void (*get_roots)(evac_fn), rtsBool force_major_gc ) bitmap_size = stp->n_blocks * BLOCK_SIZE / (sizeof(W_)*BITS_PER_BYTE); if (bitmap_size > 0) { - bitmap_bdescr = allocGroup((nat)BLOCK_ROUND_UP(bitmap_size) + bitmap_bdescr = allocGroup((lnat)BLOCK_ROUND_UP(bitmap_size) / BLOCK_SIZE); stp->bitmap = bitmap_bdescr; bitmap = bitmap_bdescr->start; @@ -977,7 +984,7 @@ GarbageCollect ( void (*get_roots)(evac_fn), rtsBool force_major_gc ) blocks = RtsFlags.GcFlags.minAllocAreaSize; } } - resizeNursery(blocks); + resizeNurseries(blocks); } else { /* Generational collector: @@ -994,7 +1001,7 @@ GarbageCollect ( void (*get_roots)(evac_fn), rtsBool force_major_gc ) * percentage of g0s0 that was live at the last minor GC. */ if (N == 0) { - g0s0_pcnt_kept = (new_blocks * 100) / g0s0->n_blocks; + g0s0_pcnt_kept = (new_blocks * 100) / countNurseryBlocks(); } /* Estimate a size for the allocation area based on the @@ -1017,12 +1024,12 @@ GarbageCollect ( void (*get_roots)(evac_fn), rtsBool force_major_gc ) blocks = RtsFlags.GcFlags.minAllocAreaSize; } - resizeNursery((nat)blocks); + resizeNurseries((nat)blocks); } else { // we might have added extra large blocks to the nursery, so // resize back to minAllocAreaSize again. - resizeNursery(RtsFlags.GcFlags.minAllocAreaSize); + resizeNurseriesFixed(RtsFlags.GcFlags.minAllocAreaSize); } } @@ -1287,6 +1294,21 @@ traverse_weak_ptr_list(void) } } + /* Finally, we can update the blackhole_queue. This queue + * simply strings together TSOs blocked on black holes, it is + * not intended to keep anything alive. Hence, we do not follow + * pointers on the blackhole_queue until now, when we have + * determined which TSOs are otherwise reachable. We know at + * this point that all TSOs have been evacuated, however. + */ + { + StgTSO **pt; + for (pt = &blackhole_queue; *pt != END_TSO_QUEUE; pt = &((*pt)->link)) { + *pt = (StgTSO *)isAlive((StgClosure *)*pt); + ASSERT(*pt != NULL); + } + } + weak_stage = WeakDone; // *now* we're done, return rtsTrue; // but one more round of scavenging, please @@ -1624,7 +1646,9 @@ evacuate_large(StgPtr p) REGPARM1 static StgClosure * evacuate(StgClosure *q) { +#if defined(PAR) StgClosure *to; +#endif bdescr *bd = NULL; step *stp; const StgInfoTable *info; @@ -1712,9 +1736,11 @@ loop: case FUN_1_0: case FUN_0_1: case CONSTR_1_0: + return copy(q,sizeofW(StgHeader)+1,stp); + case THUNK_1_0: case THUNK_0_1: - return copy(q,sizeofW(StgHeader)+1,stp); + return copy(q,sizeofW(StgThunk)+1,stp); case THUNK_1_1: case THUNK_0_2: @@ -1726,7 +1752,7 @@ loop: stp = bd->step; } #endif - return copy(q,sizeofW(StgHeader)+2,stp); + return copy(q,sizeofW(StgThunk)+2,stp); case FUN_1_1: case FUN_0_2: @@ -1736,8 +1762,10 @@ loop: case CONSTR_2_0: return copy(q,sizeofW(StgHeader)+2,stp); - case FUN: case THUNK: + return copy(q,thunk_sizeW_fromITBL(info),stp); + + case FUN: case CONSTR: case IND_PERM: case IND_OLDGEN_PERM: @@ -1755,10 +1783,6 @@ loop: case BLACKHOLE: return copyPart(q,BLACKHOLE_sizeW(),sizeofW(StgHeader),stp); - case BLACKHOLE_BQ: - to = copy(q,BLACKHOLE_sizeW(),stp); - return to; - case THUNK_SELECTOR: { StgClosure *p; @@ -1796,16 +1820,16 @@ loop: case THUNK_STATIC: if (info->srt_bitmap != 0 && major_gc && - THUNK_STATIC_LINK((StgClosure *)q) == NULL) { - THUNK_STATIC_LINK((StgClosure *)q) = static_objects; + *THUNK_STATIC_LINK((StgClosure *)q) == NULL) { + *THUNK_STATIC_LINK((StgClosure *)q) = static_objects; static_objects = (StgClosure *)q; } return q; case FUN_STATIC: if (info->srt_bitmap != 0 && major_gc && - FUN_STATIC_LINK((StgClosure *)q) == NULL) { - FUN_STATIC_LINK((StgClosure *)q) = static_objects; + *FUN_STATIC_LINK((StgClosure *)q) == NULL) { + *FUN_STATIC_LINK((StgClosure *)q) = static_objects; static_objects = (StgClosure *)q; } return q; @@ -1817,15 +1841,15 @@ loop: */ if (major_gc && ((StgIndStatic *)q)->saved_info == NULL - && IND_STATIC_LINK((StgClosure *)q) == NULL) { - IND_STATIC_LINK((StgClosure *)q) = static_objects; + && *IND_STATIC_LINK((StgClosure *)q) == NULL) { + *IND_STATIC_LINK((StgClosure *)q) = static_objects; static_objects = (StgClosure *)q; } return q; case CONSTR_STATIC: - if (major_gc && STATIC_LINK(info,(StgClosure *)q) == NULL) { - STATIC_LINK(info,(StgClosure *)q) = static_objects; + if (major_gc && *STATIC_LINK(info,(StgClosure *)q) == NULL) { + *STATIC_LINK(info,(StgClosure *)q) = static_objects; static_objects = (StgClosure *)q; } return q; @@ -1854,9 +1878,11 @@ loop: barf("evacuate: stack frame at %p\n", q); case PAP: - case AP: return copy(q,pap_sizeW((StgPAP*)q),stp); + case AP: + return copy(q,ap_sizeW((StgAP*)q),stp); + case AP_STACK: return copy(q,ap_stack_sizeW((StgAP_STACK*)q),stp); @@ -1919,7 +1945,7 @@ loop: } #if defined(PAR) - case RBH: // cf. BLACKHOLE_BQ + case RBH: { //StgInfoTable *rip = get_closure_info(q, &size, &ptrs, &nonptrs, &vhs, str); to = copy(q,BLACKHOLE_sizeW(),stp); @@ -1991,6 +2017,48 @@ loop: been BLACKHOLE'd, and should be updated with an indirection or a forwarding pointer. If the return value is NULL, then the selector thunk is unchanged. + + *** + ToDo: the treatment of THUNK_SELECTORS could be improved in the + following way (from a suggestion by Ian Lynagh): + + We can have a chain like this: + + sel_0 --> (a,b) + | + |-----> sel_0 --> (a,b) + | + |-----> sel_0 --> ... + + and the depth limit means we don't go all the way to the end of the + chain, which results in a space leak. This affects the recursive + call to evacuate() in the THUNK_SELECTOR case in evacuate(): *not* + the recursive call to eval_thunk_selector() in + eval_thunk_selector(). + + We could eliminate the depth bound in this case, in the following + way: + + - traverse the chain once to discover the *value* of the + THUNK_SELECTOR. Mark all THUNK_SELECTORS that we + visit on the way as having been visited already (somehow). + + - in a second pass, traverse the chain again updating all + THUNK_SEELCTORS that we find on the way with indirections to + the value. + + - if we encounter a "marked" THUNK_SELECTOR in a normal + evacuate(), we konw it can't be updated so just evac it. + + Program that illustrates the problem: + + foo [] = ([], []) + foo (x:xs) = let (ys, zs) = foo xs + in if x >= 0 then (x:ys, zs) else (ys, x:zs) + + main = bar [1..(100000000::Int)] + bar xs = (\(ys, zs) -> print ys >> print zs) (foo xs) + -------------------------------------------------------------------------- */ static inline rtsBool @@ -2167,7 +2235,6 @@ selector_loop: case SE_CAF_BLACKHOLE: case SE_BLACKHOLE: case BLACKHOLE: - case BLACKHOLE_BQ: #if defined(PAR) case RBH: case BLOCKED_FETCH: @@ -2297,15 +2364,6 @@ scavenge_fun_srt(const StgInfoTable *info) scavenge_srt((StgClosure **)GET_FUN_SRT(fun_info), fun_info->i.srt_bitmap); } -STATIC_INLINE void -scavenge_ret_srt(const StgInfoTable *info) -{ - StgRetInfoTable *ret_info; - - ret_info = itbl_to_ret_itbl(info); - scavenge_srt((StgClosure **)GET_SRT(ret_info), ret_info->i.srt_bitmap); -} - /* ----------------------------------------------------------------------------- Scavenge a TSO. -------------------------------------------------------------------------- */ @@ -2313,8 +2371,10 @@ scavenge_ret_srt(const StgInfoTable *info) static void scavengeTSO (StgTSO *tso) { - // chase the link field for any TSOs on the same queue - tso->link = (StgTSO *)evacuate((StgClosure *)tso->link); + // We don't chase the link field: TSOs on the blackhole queue are + // not automatically alive, so the link field is a "weak" pointer. + // Queues of TSOs are traversed explicitly. + if ( tso->why_blocked == BlockedOnMVar || tso->why_blocked == BlockedOnBlackHole || tso->why_blocked == BlockedOnException @@ -2352,8 +2412,8 @@ scavenge_arg_block (StgFunInfoTable *fun_info, StgClosure **args) p = (StgPtr)args; switch (fun_info->f.fun_type) { case ARG_GEN: - bitmap = BITMAP_BITS(fun_info->f.bitmap); - size = BITMAP_SIZE(fun_info->f.bitmap); + bitmap = BITMAP_BITS(fun_info->f.b.bitmap); + size = BITMAP_SIZE(fun_info->f.b.bitmap); goto small_bitmap; case ARG_GEN_BIG: size = GET_FUN_LARGE_BITMAP(fun_info)->size; @@ -2378,35 +2438,31 @@ scavenge_arg_block (StgFunInfoTable *fun_info, StgClosure **args) } STATIC_INLINE StgPtr -scavenge_PAP (StgPAP *pap) +scavenge_PAP_payload (StgClosure *fun, StgClosure **payload, StgWord size) { StgPtr p; - StgWord bitmap, size; + StgWord bitmap; StgFunInfoTable *fun_info; - - pap->fun = evacuate(pap->fun); - fun_info = get_fun_itbl(pap->fun); + + fun_info = get_fun_itbl(fun); ASSERT(fun_info->i.type != PAP); - - p = (StgPtr)pap->payload; - size = pap->n_args; + p = (StgPtr)payload; switch (fun_info->f.fun_type) { case ARG_GEN: - bitmap = BITMAP_BITS(fun_info->f.bitmap); + bitmap = BITMAP_BITS(fun_info->f.b.bitmap); goto small_bitmap; case ARG_GEN_BIG: scavenge_large_bitmap(p, GET_FUN_LARGE_BITMAP(fun_info), size); p += size; break; case ARG_BCO: - scavenge_large_bitmap((StgPtr)pap->payload, BCO_BITMAP(pap->fun), size); + scavenge_large_bitmap((StgPtr)payload, BCO_BITMAP(fun), size); p += size; break; default: bitmap = BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]); small_bitmap: - size = pap->n_args; while (size > 0) { if ((bitmap & 1) == 0) { *p = (StgWord)(StgPtr)evacuate((StgClosure *)*p); @@ -2420,6 +2476,20 @@ scavenge_PAP (StgPAP *pap) return p; } +STATIC_INLINE StgPtr +scavenge_PAP (StgPAP *pap) +{ + pap->fun = evacuate(pap->fun); + return scavenge_PAP_payload (pap->fun, pap->payload, pap->n_args); +} + +STATIC_INLINE StgPtr +scavenge_AP (StgAP *ap) +{ + ap->fun = evacuate(ap->fun); + return scavenge_PAP_payload (ap->fun, ap->payload, ap->n_args); +} + /* ----------------------------------------------------------------------------- Scavenge a given step until there are no more objects in this step to scavenge. @@ -2489,6 +2559,11 @@ scavenge(step *stp) case THUNK_2_0: scavenge_thunk_srt(info); + ((StgThunk *)p)->payload[1] = evacuate(((StgThunk *)p)->payload[1]); + ((StgThunk *)p)->payload[0] = evacuate(((StgThunk *)p)->payload[0]); + p += sizeofW(StgThunk) + 2; + break; + case CONSTR_2_0: ((StgClosure *)p)->payload[1] = evacuate(((StgClosure *)p)->payload[1]); ((StgClosure *)p)->payload[0] = evacuate(((StgClosure *)p)->payload[0]); @@ -2497,8 +2572,8 @@ scavenge(step *stp) case THUNK_1_0: scavenge_thunk_srt(info); - ((StgClosure *)p)->payload[0] = evacuate(((StgClosure *)p)->payload[0]); - p += sizeofW(StgHeader) + 1; + ((StgThunk *)p)->payload[0] = evacuate(((StgThunk *)p)->payload[0]); + p += sizeofW(StgThunk) + 1; break; case FUN_1_0: @@ -2510,7 +2585,7 @@ scavenge(step *stp) case THUNK_0_1: scavenge_thunk_srt(info); - p += sizeofW(StgHeader) + 1; + p += sizeofW(StgThunk) + 1; break; case FUN_0_1: @@ -2521,7 +2596,7 @@ scavenge(step *stp) case THUNK_0_2: scavenge_thunk_srt(info); - p += sizeofW(StgHeader) + 2; + p += sizeofW(StgThunk) + 2; break; case FUN_0_2: @@ -2532,8 +2607,8 @@ scavenge(step *stp) case THUNK_1_1: scavenge_thunk_srt(info); - ((StgClosure *)p)->payload[0] = evacuate(((StgClosure *)p)->payload[0]); - p += sizeofW(StgHeader) + 2; + ((StgThunk *)p)->payload[0] = evacuate(((StgThunk *)p)->payload[0]); + p += sizeofW(StgThunk) + 2; break; case FUN_1_1: @@ -2548,8 +2623,17 @@ scavenge(step *stp) goto gen_obj; case THUNK: + { + StgPtr end; + scavenge_thunk_srt(info); - // fall through + end = (P_)((StgThunk *)p)->payload + info->layout.payload.ptrs; + for (p = (P_)((StgThunk *)p)->payload; p < end; p++) { + *p = (StgWord)(StgPtr)evacuate((StgClosure *)*p); + } + p += info->layout.payload.nptrs; + break; + } gen_obj: case CONSTR: @@ -2614,16 +2698,6 @@ scavenge(step *stp) p += BLACKHOLE_sizeW(); break; - case BLACKHOLE_BQ: - { - StgBlockingQueue *bh = (StgBlockingQueue *)p; - bh->blocking_queue = - (StgTSO *)evacuate((StgClosure *)bh->blocking_queue); - failed_to_evac = rtsTrue; - p += BLACKHOLE_sizeW(); - break; - } - case THUNK_SELECTOR: { StgSelector *s = (StgSelector *)p; @@ -2644,10 +2718,13 @@ scavenge(step *stp) } case PAP: - case AP: p = scavenge_PAP((StgPAP *)p); break; + case AP: + p = scavenge_AP((StgAP *)p); + break; + case ARR_WORDS: // nothing to follow p += arr_words_sizeW((StgArrWords *)p); @@ -2697,7 +2774,7 @@ scavenge(step *stp) } #if defined(PAR) - case RBH: // cf. BLACKHOLE_BQ + case RBH: { #if 0 nat size, ptrs, nonptrs, vhs; @@ -2740,7 +2817,7 @@ scavenge(step *stp) p += sizeofW(StgFetchMe); break; // nothing to do in this case - case FETCH_ME_BQ: // cf. BLACKHOLE_BQ + case FETCH_ME_BQ: { StgFetchMeBlockingQueue *fmbq = (StgFetchMeBlockingQueue *)p; (StgClosure *)fmbq->blocking_queue = @@ -2878,6 +2955,10 @@ linear_scan: case THUNK_2_0: scavenge_thunk_srt(info); + ((StgThunk *)p)->payload[1] = evacuate(((StgThunk *)p)->payload[1]); + ((StgThunk *)p)->payload[0] = evacuate(((StgThunk *)p)->payload[0]); + break; + case CONSTR_2_0: ((StgClosure *)p)->payload[1] = evacuate(((StgClosure *)p)->payload[1]); ((StgClosure *)p)->payload[0] = evacuate(((StgClosure *)p)->payload[0]); @@ -2892,6 +2973,9 @@ linear_scan: case THUNK_1_0: case THUNK_1_1: scavenge_thunk_srt(info); + ((StgThunk *)p)->payload[0] = evacuate(((StgThunk *)p)->payload[0]); + break; + case CONSTR_1_0: case CONSTR_1_1: ((StgClosure *)p)->payload[0] = evacuate(((StgClosure *)p)->payload[0]); @@ -2916,8 +3000,16 @@ linear_scan: goto gen_obj; case THUNK: + { + StgPtr end; + scavenge_thunk_srt(info); - // fall through + end = (P_)((StgThunk *)p)->payload + info->layout.payload.ptrs; + for (p = (P_)((StgThunk *)p)->payload; p < end; p++) { + *p = (StgWord)(StgPtr)evacuate((StgClosure *)*p); + } + break; + } gen_obj: case CONSTR: @@ -2969,15 +3061,6 @@ linear_scan: case ARR_WORDS: break; - case BLACKHOLE_BQ: - { - StgBlockingQueue *bh = (StgBlockingQueue *)p; - bh->blocking_queue = - (StgTSO *)evacuate((StgClosure *)bh->blocking_queue); - failed_to_evac = rtsTrue; - break; - } - case THUNK_SELECTOR: { StgSelector *s = (StgSelector *)p; @@ -2996,9 +3079,12 @@ linear_scan: } case PAP: - case AP: scavenge_PAP((StgPAP *)p); break; + + case AP: + scavenge_AP((StgAP *)p); + break; case MUT_ARR_PTRS: // follow everything @@ -3039,7 +3125,7 @@ linear_scan: } #if defined(PAR) - case RBH: // cf. BLACKHOLE_BQ + case RBH: { #if 0 nat size, ptrs, nonptrs, vhs; @@ -3078,7 +3164,7 @@ linear_scan: case FETCH_ME: break; // nothing to do in this case - case FETCH_ME_BQ: // cf. BLACKHOLE_BQ + case FETCH_ME_BQ: { StgFetchMeBlockingQueue *fmbq = (StgFetchMeBlockingQueue *)p; (StgClosure *)fmbq->blocking_queue = @@ -3088,7 +3174,7 @@ linear_scan: p, info_type((StgClosure *)p))); break; } -#endif // PAR +#endif /* PAR */ case TVAR_WAIT_QUEUE: { @@ -3227,18 +3313,28 @@ scavenge_one(StgPtr p) break; } - case FUN: - case FUN_1_0: // hardly worth specialising these guys - case FUN_0_1: - case FUN_1_1: - case FUN_0_2: - case FUN_2_0: case THUNK: case THUNK_1_0: case THUNK_0_1: case THUNK_1_1: case THUNK_0_2: case THUNK_2_0: + { + StgPtr q, end; + + end = (StgPtr)((StgThunk *)p)->payload + info->layout.payload.ptrs; + for (q = (StgPtr)((StgThunk *)p)->payload; q < end; q++) { + *q = (StgWord)(StgPtr)evacuate((StgClosure *)*q); + } + break; + } + + case FUN: + case FUN_1_0: // hardly worth specialising these guys + case FUN_0_1: + case FUN_1_1: + case FUN_0_2: + case FUN_2_0: case CONSTR: case CONSTR_1_0: case CONSTR_0_1: @@ -3271,16 +3367,6 @@ scavenge_one(StgPtr p) case BLACKHOLE: break; - case BLACKHOLE_BQ: - { - StgBlockingQueue *bh = (StgBlockingQueue *)p; - evac_gen = 0; // repeatedly mutable - bh->blocking_queue = - (StgTSO *)evacuate((StgClosure *)bh->blocking_queue); - failed_to_evac = rtsTrue; - break; - } - case THUNK_SELECTOR: { StgSelector *s = (StgSelector *)p; @@ -3299,10 +3385,13 @@ scavenge_one(StgPtr p) } case PAP: - case AP: p = scavenge_PAP((StgPAP *)p); break; + case AP: + p = scavenge_AP((StgAP *)p); + break; + case ARR_WORDS: // nothing to follow break; @@ -3347,7 +3436,7 @@ scavenge_one(StgPtr p) } #if defined(PAR) - case RBH: // cf. BLACKHOLE_BQ + case RBH: { #if 0 nat size, ptrs, nonptrs, vhs; @@ -3387,7 +3476,7 @@ scavenge_one(StgPtr p) case FETCH_ME: break; // nothing to do in this case - case FETCH_ME_BQ: // cf. BLACKHOLE_BQ + case FETCH_ME_BQ: { StgFetchMeBlockingQueue *fmbq = (StgFetchMeBlockingQueue *)p; (StgClosure *)fmbq->blocking_queue = @@ -3565,8 +3654,8 @@ scavenge_static(void) /* Take this object *off* the static_objects list, * and put it on the scavenged_static_objects list. */ - static_objects = STATIC_LINK(info,p); - STATIC_LINK(info,p) = scavenged_static_objects; + static_objects = *STATIC_LINK(info,p); + *STATIC_LINK(info,p) = scavenged_static_objects; scavenged_static_objects = p; switch (info -> type) { @@ -3835,8 +3924,8 @@ zero_static_object_list(StgClosure* first_static) for (p = first_static; p != END_OF_STATIC_LIST; p = link) { info = get_itbl(p); - link = STATIC_LINK(info, p); - STATIC_LINK(info,p) = NULL; + link = *STATIC_LINK(info, p); + *STATIC_LINK(info,p) = NULL; } } @@ -3849,14 +3938,14 @@ revertCAFs( void ) { StgIndStatic *c; - for (c = (StgIndStatic *)caf_list; c != NULL; + for (c = (StgIndStatic *)revertible_caf_list; c != NULL; c = (StgIndStatic *)c->static_link) { SET_INFO(c, c->saved_info); c->saved_info = NULL; // could, but not necessary: c->static_link = NULL; } - caf_list = NULL; + revertible_caf_list = NULL; } void @@ -3869,6 +3958,11 @@ markCAFs( evac_fn evac ) { evac(&c->indirectee); } + for (c = (StgIndStatic *)revertible_caf_list; c != NULL; + c = (StgIndStatic *)c->static_link) + { + evac(&c->indirectee); + } } /* ----------------------------------------------------------------------------- @@ -3936,7 +4030,7 @@ threadLazyBlackHole(StgTSO *tso) { StgClosure *frame; StgRetInfoTable *info; - StgBlockingQueue *bh; + StgClosure *bh; StgPtr stack_end; stack_end = &tso->stack[tso->stack_size]; @@ -3949,7 +4043,7 @@ threadLazyBlackHole(StgTSO *tso) switch (info->i.type) { case UPDATE_FRAME: - bh = (StgBlockingQueue *)((StgUpdateFrame *)frame)->updatee; + bh = ((StgUpdateFrame *)frame)->updatee; /* if the thunk is already blackholed, it means we've also * already blackholed the rest of the thunks on this stack, @@ -3962,10 +4056,9 @@ threadLazyBlackHole(StgTSO *tso) return; } - if (bh->header.info != &stg_BLACKHOLE_BQ_info && - bh->header.info != &stg_CAF_BLACKHOLE_info) { + if (bh->header.info != &stg_CAF_BLACKHOLE_info) { #if (!defined(LAZY_BLACKHOLING)) && defined(DEBUG) - debugBelch("Unexpected lazy BHing required at 0x%04x",(int)bh); + debugBelch("Unexpected lazy BHing required at 0x%04x\n",(int)bh); #endif #ifdef PROFILING // @LDV profiling @@ -4067,7 +4160,6 @@ threadSqueezeStack(StgTSO *tso) * screw us up if we don't check. */ if (upd->updatee != updatee && !closure_IND(upd->updatee)) { - // this wakes the threads up UPD_IND_NOLOCK(upd->updatee, updatee); } @@ -4085,11 +4177,10 @@ threadSqueezeStack(StgTSO *tso) // single update frame, or the topmost update frame in a series else { - StgBlockingQueue *bh = (StgBlockingQueue *)upd->updatee; + StgClosure *bh = upd->updatee; // Do lazy black-holing if (bh->header.info != &stg_BLACKHOLE_info && - bh->header.info != &stg_BLACKHOLE_BQ_info && bh->header.info != &stg_CAF_BLACKHOLE_info) { #if (!defined(LAZY_BLACKHOLING)) && defined(DEBUG) debugBelch("Unexpected lazy BHing required at 0x%04x",(int)bh); @@ -4121,11 +4212,6 @@ threadSqueezeStack(StgTSO *tso) // Todo: maybe use SET_HDR() and remove LDV_RECORD_CREATE()? SET_INFO(bh,&stg_BLACKHOLE_info); - // Set the update frame to stg_bh_upd_info, which - // checks for blackholes (the normal update frame - // doesn't check, for efficiency). - ((StgClosure *)frame)->header.info = &stg_bh_upd_frame_info; - // We pretend that bh has just been created. LDV_RECORD_CREATE(bh); } @@ -4239,20 +4325,4 @@ printMutableList(generation *gen) } debugBelch("\n"); } - -STATIC_INLINE rtsBool -maybeLarge(StgClosure *closure) -{ - StgInfoTable *info = get_itbl(closure); - - /* closure types that may be found on the new_large_objects list; - see scavenge_large */ - return (info->type == MUT_ARR_PTRS || - info->type == MUT_ARR_PTRS_FROZEN || - info->type == MUT_ARR_PTRS_FROZEN0 || - info->type == TSO || - info->type == ARR_WORDS); -} - - -#endif // DEBUG +#endif /* DEBUG */