+
+ gct->copied += ws->todo_free - bd->free;
+ bd->free = ws->todo_free;
+
+ ASSERT(bd->u.scan >= bd->start && bd->u.scan <= bd->free);
+
+ // If this block is not the scan block, we want to push it out and
+ // make room for a new todo block.
+ if (bd != gct->scan_bd)
+ {
+ // If this block does not have enough space to allocate the
+ // current object, but it also doesn't have any work to push, then
+ // push it on to the scanned list. It cannot be empty, because
+ // then there would be enough room to copy the current object.
+ if (bd->u.scan == bd->free)
+ {
+ ASSERT(bd->free != bd->start);
+ push_scanned_block(bd, ws);
+ }
+ // Otherwise, push this block out to the global list.
+ else
+ {
+ generation *gen;
+ gen = ws->gen;
+ debugTrace(DEBUG_gc, "push todo block %p (%ld words), step %d, todo_q: %ld",
+ bd->start, (unsigned long)(bd->free - bd->u.scan),
+ gen->no, dequeElements(ws->todo_q));