/* -----------------------------------------------------------------------*-c-*-
*
- * (c) The GHC Team 1998-2006
+ * (c) The GHC Team 1998-2008
*
* Generational garbage collector: scavenging functions
*
// This file is #included into Scav.c, twice: firstly with PARALLEL_GC
// defined, the second time without.
-#ifndef PARALLEL_GC
-#define scavenge_block(a) scavenge_block1(a)
-#define evacuate(a) evacuate1(a)
-#define recordMutableGen_GC(a,b) recordMutableGen(a,b)
+#if defined(THREADED_RTS) && !defined(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
+# undef scavenge_block
+# undef evacuate
+# undef recordMutableGen_GC
+# if !defined(THREADED_RTS)
+# define scavenge_block1(a) scavenge_block(a)
+# endif
#endif
+
static void scavenge_block (bdescr *bd);
/* -----------------------------------------------------------------------------
rtsBool saved_eager_promotion;
step_workspace *ws;
- p = bd->u.scan;
-
debugTrace(DEBUG_gc, "scavenging block %p (gen %d, step %d) @ %p",
- bd->start, bd->gen_no, bd->step->no, p);
+ bd->start, bd->gen_no, bd->step->no, bd->u.scan);
+ gct->scan_bd = bd;
gct->evac_step = bd->step;
saved_evac_step = gct->evac_step;
saved_eager_promotion = gct->eager_promotion;
ws = &gct->steps[bd->step->abs_no];
+ p = bd->u.scan;
+
// 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.
case TSO:
{
StgTSO *tso = (StgTSO *)p;
-
- gct->eager_promotion = rtsFalse;
- scavengeTSO(tso);
- gct->eager_promotion = saved_eager_promotion;
-
- if (gct->failed_to_evac) {
- tso->flags |= TSO_DIRTY;
- } else {
- tso->flags &= ~TSO_DIRTY;
- }
-
- gct->failed_to_evac = rtsTrue; // always on the mutable list
+ scavengeTSO(tso);
p += tso_sizeW(tso);
break;
}
// update stats: this is a block that has been scavenged
gct->scanned += bd->free - bd->u.scan;
bd->u.scan = bd->free;
+
+ if (bd != ws->todo_bd) {
+ // we're not going to evac any more objects into
+ // this block, so push it now.
+ push_scanned_block(bd, ws);
+ }
+
+ gct->scan_bd = NULL;
}
#undef scavenge_block