- // Two-space collector: free the old to-space.
- // g0->old_blocks is the old nursery
- // g0->blocks is to-space from the previous GC
- if (RtsFlags.GcFlags.generations == 1) {
- if (g0->blocks != NULL) {
- freeChain(g0->blocks);
- g0->blocks = NULL;
- }
- }
-
- // For each workspace, in each thread, move the copied blocks to the step
- {
- gc_thread *thr;
- gen_workspace *ws;
- bdescr *prev, *next;
-
- for (t = 0; t < n_gc_threads; t++) {
- thr = gc_threads[t];
-
- for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
- ws = &thr->gens[g];
-
- // Push the final block
- if (ws->todo_bd) {
- push_scanned_block(ws->todo_bd, ws);
- }
-
- ASSERT(gct->scan_bd == NULL);
- ASSERT(countBlocks(ws->scavd_list) == ws->n_scavd_blocks);
-
- prev = NULL;
- for (bd = ws->scavd_list; bd != NULL; bd = bd->link) {
- ws->gen->n_words += bd->free - bd->start;
- prev = bd;
- }
- if (prev != NULL) {
- prev->link = ws->gen->blocks;
- ws->gen->blocks = ws->scavd_list;
- }
- ws->gen->n_blocks += ws->n_scavd_blocks;
- }
- }
-
- // Add all the partial blocks *after* we've added all the full
- // blocks. This is so that we can grab the partial blocks back
- // again and try to fill them up in the next GC.
- for (t = 0; t < n_gc_threads; t++) {
- thr = gc_threads[t];
-
- for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
- ws = &thr->gens[g];
-
- prev = NULL;
- for (bd = ws->part_list; bd != NULL; bd = next) {
- next = bd->link;
- if (bd->free == bd->start) {
- if (prev == NULL) {
- ws->part_list = next;
- } else {
- prev->link = next;
- }
- freeGroup(bd);
- ws->n_part_blocks--;
- } else {
- ws->gen->n_words += bd->free - bd->start;
- prev = bd;
- }
- }
- if (prev != NULL) {
- prev->link = ws->gen->blocks;
- ws->gen->blocks = ws->part_list;
- }
- ws->gen->n_blocks += ws->n_part_blocks;
-
- ASSERT(countBlocks(ws->gen->blocks) == ws->gen->n_blocks);
- ASSERT(countOccupied(ws->gen->blocks) == ws->gen->n_words);
- }
- }
- }
-