// For stats:
long copied; // *words* copied & scavenged during this GC
-long scavd_copied; // *words* copied only during this GC
#ifdef THREADED_RTS
SpinLock recordMutableGen_sync;
lnat live, allocated;
lnat oldgen_saved_blocks = 0;
nat n_threads; // number of threads participating in GC
-
+ gc_thread *saved_gct;
nat g, s, t;
+ // necessary if we stole a callee-saves register for gct:
+ saved_gct = gct;
+
#ifdef PROFILING
CostCentreStack *prev_CCS;
#endif
// Initialise stats
copied = 0;
- scavd_copied = 0;
// this is the main thread
gct = &gc_threads[0];
}
// follow roots from the CAF list (used by GHCi)
- gct->evac_gen = 0;
+ gct->evac_step = 0;
markCAFs(mark_root);
// follow all the roots that the application knows about.
- gct->evac_gen = 0;
+ gct->evac_step = 0;
GetRoots(mark_root);
// Mark the weak pointer list, and prepare to detect dead weak pointers.
// Push the final block
if (ws->scan_bd) { push_scan_block(ws->scan_bd, ws); }
- // update stats: we haven't counted the block at the
- // front of the scavd_list yet.
- scavd_copied += ws->scavd_list->free - ws->scavd_list->start;
-
ASSERT(countBlocks(ws->scavd_list) == ws->n_scavd_blocks);
prev = ws->scavd_list;
#endif
// ok, GC over: tell the stats department what happened.
- stat_endGC(allocated, live, copied, scavd_copied, N);
+ stat_endGC(allocated, live, copied, N);
#if defined(RTS_USER_SIGNALS)
if (RtsFlags.MiscFlags.install_signal_handlers) {
#endif
RELEASE_SM_LOCK;
+
+ gct = saved_gct;
}
/* ---------------------------------------------------------------------------
ws->buffer_todo_bd = NULL;
gc_alloc_todo_block(ws);
- // allocate a block for "already scavenged" objects. This goes
- // on the front of the stp->blocks list, so it won't be
- // traversed by the scavenging sweep.
ws->scavd_list = NULL;
ws->n_scavd_blocks = 0;
- gc_alloc_scavd_block(ws);
}
}
}
ws->buffer_todo_bd = NULL;
ws->todo_large_objects = NULL;
+ ws->scavd_list = NULL;
+ ws->n_scavd_blocks = 0;
+
// If the block at the head of the list in this generation
// is less than 3/4 full, then use it as a todo block.
if (isPartiallyFull(stp->blocks))
ws->todo_bd = NULL;
gc_alloc_todo_block(ws);
}
-
- // Do the same trick for the scavd block
- if (isPartiallyFull(stp->blocks))
- {
- ws->scavd_list = stp->blocks;
- stp->blocks = stp->blocks->link;
- stp->n_blocks -= 1;
- ws->scavd_list->link = NULL;
- ws->n_scavd_blocks = 1;
- // subtract the contents of this block from the stats,
- // because we'll count the whole block later.
- scavd_copied -= ws->scavd_list->free - ws->scavd_list->start;
- }
- else
- {
- ws->scavd_list = NULL;
- ws->n_scavd_blocks = 0;
- gc_alloc_scavd_block(ws);
- }
}
}
static void
init_gc_thread (gc_thread *t)
{
- t->evac_gen = 0;
+ t->evac_step = 0;
t->failed_to_evac = rtsFalse;
t->eager_promotion = rtsTrue;
t->thunk_selector_depth = 0;
static void
mark_root(StgClosure **root)
{
- *root = evacuate(*root);
+ evacuate(root);
}
/* -----------------------------------------------------------------------------