X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fsm%2FScav.c-inc;h=6f852035b5d1a75e5894ec9411d98a50d15146ff;hb=dbbf15c0f141357aa49b583286174867baadb821;hp=50c4088d8d26eca985d7f760caf108014c9c7d76;hpb=d13df738cbbe8017ae19ae2702f4e10805ee521b;p=ghc-hetmet.git diff --git a/rts/sm/Scav.c-inc b/rts/sm/Scav.c-inc index 50c4088..6f85203 100644 --- a/rts/sm/Scav.c-inc +++ b/rts/sm/Scav.c-inc @@ -1,4 +1,4 @@ -/* ----------------------------------------------------------------------------- +/* -----------------------------------------------------------------------*-c-*- * * (c) The GHC Team 1998-2006 * @@ -11,18 +11,20 @@ * * ---------------------------------------------------------------------------*/ -// This file is #included into Scav.c, twice: firstly with MINOR_GC +// This file is #included into Scav.c, twice: firstly with PARALLEL_GC // defined, the second time without. -#ifdef MINOR_GC -#define scavenge_block(a,b) scavenge_block0(a,b) -#define evacuate(a) evacuate0(a) +#ifndef PARALLEL_GC +#define scavenge_block(a) scavenge_block1(a) +#define evacuate(a) evacuate1(a) +#define recordMutableGen_GC(a,b) recordMutableGen(a,b) #else #undef scavenge_block #undef evacuate +#undef recordMutableGen_GC #endif -static void scavenge_block (bdescr *bd, StgPtr scan); +static void scavenge_block (bdescr *bd); /* ----------------------------------------------------------------------------- Scavenge a block from the given scan pointer up to bd->free. @@ -37,25 +39,30 @@ static void scavenge_block (bdescr *bd, StgPtr scan); -------------------------------------------------------------------------- */ static void -scavenge_block (bdescr *bd, StgPtr scan) +scavenge_block (bdescr *bd) { StgPtr p, q; StgInfoTable *info; step *saved_evac_step; + rtsBool saved_eager_promotion; + step_workspace *ws; - p = scan; + p = bd->u.scan; debugTrace(DEBUG_gc, "scavenging block %p (gen %d, step %d) @ %p", - bd->start, bd->gen_no, bd->step->no, scan); + bd->start, bd->gen_no, bd->step->no, p); gct->evac_step = bd->step; saved_evac_step = gct->evac_step; + saved_eager_promotion = gct->eager_promotion; gct->failed_to_evac = rtsFalse; + ws = &gct->steps[bd->step->abs_no]; + // we might be evacuating into the very object that we're // scavenging, so we have to check the real bd->free pointer each // time around the loop. - while (p < bd->free) { + while (p < bd->free || (bd == ws->todo_bd && p < ws->todo_free)) { ASSERT(LOOKS_LIKE_CLOSURE_PTR(p)); info = get_itbl((StgClosure *)p); @@ -68,8 +75,6 @@ scavenge_block (bdescr *bd, StgPtr scan) case MVAR_CLEAN: case MVAR_DIRTY: { - rtsBool saved_eager_promotion = gct->eager_promotion; - StgMVar *mvar = ((StgMVar *)p); gct->eager_promotion = rtsFalse; evacuate((StgClosure **)&mvar->head); @@ -87,18 +92,14 @@ scavenge_block (bdescr *bd, StgPtr scan) } case FUN_2_0: -#ifndef MINOR_GC scavenge_fun_srt(info); -#endif evacuate(&((StgClosure *)p)->payload[1]); evacuate(&((StgClosure *)p)->payload[0]); p += sizeofW(StgHeader) + 2; break; case THUNK_2_0: -#ifndef MINOR_GC scavenge_thunk_srt(info); -#endif evacuate(&((StgThunk *)p)->payload[1]); evacuate(&((StgThunk *)p)->payload[0]); p += sizeofW(StgThunk) + 2; @@ -111,82 +112,62 @@ scavenge_block (bdescr *bd, StgPtr scan) break; case THUNK_1_0: -#ifndef MINOR_GC scavenge_thunk_srt(info); -#endif evacuate(&((StgThunk *)p)->payload[0]); p += sizeofW(StgThunk) + 1; break; case FUN_1_0: -#ifndef MINOR_GC scavenge_fun_srt(info); -#endif case CONSTR_1_0: evacuate(&((StgClosure *)p)->payload[0]); p += sizeofW(StgHeader) + 1; break; case THUNK_0_1: -#ifndef MINOR_GC scavenge_thunk_srt(info); -#endif p += sizeofW(StgThunk) + 1; break; case FUN_0_1: -#ifndef MINOR_GC scavenge_fun_srt(info); -#endif case CONSTR_0_1: p += sizeofW(StgHeader) + 1; break; case THUNK_0_2: -#ifndef MINOR_GC scavenge_thunk_srt(info); -#endif p += sizeofW(StgThunk) + 2; break; case FUN_0_2: -#ifndef MINOR_GC scavenge_fun_srt(info); -#endif case CONSTR_0_2: p += sizeofW(StgHeader) + 2; break; case THUNK_1_1: -#ifndef MINOR_GC scavenge_thunk_srt(info); -#endif evacuate(&((StgThunk *)p)->payload[0]); p += sizeofW(StgThunk) + 2; break; case FUN_1_1: -#ifndef MINOR_GC scavenge_fun_srt(info); -#endif case CONSTR_1_1: evacuate(&((StgClosure *)p)->payload[0]); p += sizeofW(StgHeader) + 2; break; case FUN: -#ifndef MINOR_GC scavenge_fun_srt(info); -#endif goto gen_obj; case THUNK: { StgPtr end; -#ifndef MINOR_GC scavenge_thunk_srt(info); -#endif end = (P_)((StgThunk *)p)->payload + info->layout.payload.ptrs; for (p = (P_)((StgThunk *)p)->payload; p < end; p++) { evacuate((StgClosure **)p); @@ -242,9 +223,7 @@ scavenge_block (bdescr *bd, StgPtr scan) break; case MUT_VAR_CLEAN: - case MUT_VAR_DIRTY: { - rtsBool saved_eager_promotion = gct->eager_promotion; - + case MUT_VAR_DIRTY: gct->eager_promotion = rtsFalse; evacuate(&((StgMutVar *)p)->var); gct->eager_promotion = saved_eager_promotion; @@ -256,7 +235,6 @@ scavenge_block (bdescr *bd, StgPtr scan) } p += sizeofW(StgMutVar); break; - } case CAF_BLACKHOLE: case SE_CAF_BLACKHOLE: @@ -302,19 +280,17 @@ scavenge_block (bdescr *bd, StgPtr scan) // follow everything { StgPtr next; - rtsBool saved_eager; // We don't eagerly promote objects pointed to by a mutable // array, but if we find the array only points to objects in // the same or an older generation, we mark it "clean" and // avoid traversing it during minor GCs. - saved_eager = gct->eager_promotion; gct->eager_promotion = rtsFalse; next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p); for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) { evacuate((StgClosure **)p); } - gct->eager_promotion = saved_eager; + gct->eager_promotion = saved_eager_promotion; if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_MUT_ARR_PTRS_DIRTY_info; @@ -350,11 +326,10 @@ scavenge_block (bdescr *bd, StgPtr scan) case TSO: { StgTSO *tso = (StgTSO *)p; - rtsBool saved_eager = gct->eager_promotion; gct->eager_promotion = rtsFalse; scavengeTSO(tso); - gct->eager_promotion = saved_eager; + gct->eager_promotion = saved_eager_promotion; if (gct->failed_to_evac) { tso->flags |= TSO_DIRTY; @@ -468,5 +443,19 @@ scavenge_block (bdescr *bd, StgPtr scan) } } - debugTrace(DEBUG_gc, " scavenged %ld bytes", (bd->free - scan) * sizeof(W_)); + if (p > bd->free) { + bd->free = p; + } + + debugTrace(DEBUG_gc, " scavenged %ld bytes", + (unsigned long)((bd->free - bd->u.scan) * sizeof(W_))); + + // update stats: this is a block that has been copied & scavenged + gct->copied += bd->free - bd->u.scan; + + bd->u.scan = bd->free; } + +#undef scavenge_block +#undef evacuate +#undef recordMutableGen_GC