]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: replace generations array with individual instance variables referencing zone...
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Wed, 7 Oct 2009 16:59:59 +0000 (11:59 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Wed, 7 Oct 2009 16:59:59 +0000 (11:59 -0500)
extra/websites/concatenative/concatenative.factor
vm/code_heap.cpp
vm/data_gc.cpp
vm/data_heap.cpp
vm/data_heap.hpp
vm/debug.cpp
vm/gc/zone.hpp [new file with mode: 0644]
vm/image.cpp
vm/master.hpp
vm/vm.hpp

index b5a29073cdb25126ef936bd6fc610011d8c54244..11b30a114c3865f02b0718a4a3478433e1c5d47c 100644 (file)
@@ -97,7 +97,7 @@ SYMBOL: dh-file
         <login-config> <factor-boilerplate> test-db <alloy> "concatenative.org" add-responder
         <pastebin> <login-config> <factor-boilerplate> test-db <alloy> "paste.factorcode.org" add-responder
         <planet> <login-config> <factor-boilerplate> test-db <alloy> "planet.factorcode.org" add-responder
-        home "docs" append-path <help-webapp> test-db <alloy> "docs.factorcode.org" add-responder
+        home "docs" append-path <help-webapp> "docs.factorcode.org" add-responder
         home "cgi" append-path <gitweb> "gitweb.factorcode.org" add-responder
         <mason-app> "builds.factorcode.org" add-responder
     main-responder set-global ;
index f07639d9bb8fcde61e21d4bcbac72631804dc245..6a5391a589114a4ba10dfe7de028d565e7440ac8 100755 (executable)
@@ -27,6 +27,7 @@ void code_heap::code_heap_free(code_block *compiled)
 void factor_vm::init_code_heap(cell size)
 {
        code = new code_heap(secure_gc,size);
+       code->youngest_referenced_generation = nursery_gen;
 }
 
 bool factor_vm::in_code_heap_p(cell ptr)
index 47effccf853bf833c311921d13454b02b0790f1c..b3836e4a3b451386b12502246fe6bf5a78316f4e 100755 (executable)
@@ -3,11 +3,6 @@
 namespace factor
 {
 
-void factor_vm::init_data_gc()
-{
-       code->youngest_referenced_generation = nursery_gen;
-}
-
 gc_state::gc_state(data_heap *data_, bool growing_data_heap_, cell collecting_gen_) :
        data(data_),
        growing_data_heap(growing_data_heap_),
@@ -81,26 +76,23 @@ template<typename Strategy> object *factor_vm::promote_object(object *untagged,
        return newpointer;
 }
 
-template<typename Strategy> void factor_vm::trace_card(card *ptr, cell gen, cell here, Strategy &strategy)
+template<typename Strategy> void factor_vm::trace_card(card *ptr, cell here, Strategy &strategy)
 {
        cell card_scan = card_to_addr(ptr) + card_offset(ptr);
        cell card_end = card_to_addr(ptr + 1);
 
-       if(here < card_end)
-               card_end = here;
+       if(here < card_end) card_end = here;
 
        strategy.copy_reachable_objects(card_scan,&card_end);
 
        gc_stats.cards_scanned++;
 }
 
-template<typename Strategy> void factor_vm::trace_card_deck(card_deck *deck, cell gen, card mask, card unmask, Strategy &strategy)
+template<typename Strategy> void factor_vm::trace_card_deck(card_deck *deck, cell here, card mask, card unmask, Strategy &strategy)
 {
        card *first_card = deck_to_card(deck);
        card *last_card = deck_to_card(deck + 1);
 
-       cell here = data->generations[gen].here;
-
        u32 *quad_ptr;
        u32 quad_mask = mask | (mask << 8) | (mask << 16) | (mask << 24);
 
@@ -115,7 +107,7 @@ template<typename Strategy> void factor_vm::trace_card_deck(card_deck *deck, cel
                        {
                                if(ptr[card] & mask)
                                {
-                                       trace_card(&ptr[card],gen,here,strategy);
+                                       trace_card(&ptr[card],here,strategy);
                                        ptr[card] &= ~unmask;
                                }
                        }
@@ -126,10 +118,12 @@ template<typename Strategy> void factor_vm::trace_card_deck(card_deck *deck, cel
 }
 
 /* Trace all objects referenced from marked cards */
-template<typename Strategy> void factor_vm::trace_generation_cards(cell gen, Strategy &strategy)
+template<typename Strategy> void factor_vm::trace_cards(cell gen, zone *z, Strategy &strategy)
 {
-       card_deck *first_deck = addr_to_deck(data->generations[gen].start);
-       card_deck *last_deck = addr_to_deck(data->generations[gen].end);
+       u64 start_time = current_micros();
+
+       card_deck *first_deck = addr_to_deck(z->start);
+       card_deck *last_deck = addr_to_deck(z->end);
 
        card mask, unmask;
 
@@ -185,23 +179,12 @@ template<typename Strategy> void factor_vm::trace_generation_cards(cell gen, Str
        {
                if(*ptr & mask)
                {
-                       trace_card_deck(ptr,gen,mask,unmask,strategy);
+                       trace_card_deck(ptr,z->here,mask,unmask,strategy);
                        *ptr &= ~unmask;
                }
        }
-}
-
-/* Scan cards in all generations older than the one being collected, copying
-old->new references */
-template<typename Strategy> void factor_vm::trace_cards(Strategy &strategy)
-{
-       u64 start = current_micros();
 
-       cell i;
-       for(i = current_gc->collecting_gen + 1; i < gen_count; i++)
-               trace_generation_cards(i,strategy);
-
-       gc_stats.card_scan_time += (current_micros() - start);
+       gc_stats.card_scan_time += (current_micros() - start_time);
 }
 
 /* Copy all tagged pointers in a range of memory */
@@ -482,7 +465,7 @@ struct aging_collector : copying_collector<aging_collector>
 
        explicit aging_collector(factor_vm *myvm_, zone *newspace_) :
                copying_collector<aging_collector>(myvm_,newspace_),
-               tenured(&myvm->data->generations[tenured_gen]) {}
+               tenured(myvm->data->tenured) {}
 
        bool should_copy_p(object *untagged)
        {
@@ -536,11 +519,12 @@ struct tenured_collector : copying_collector<tenured_collector>
 
 void factor_vm::collect_nursery()
 {
-       nursery_collector collector(this,&data->generations[aging_gen]);
+       nursery_collector collector(this,data->aging);
 
        trace_roots(collector);
        trace_contexts(collector);
-       trace_cards(collector);
+       trace_cards(tenured_gen,data->tenured,collector);
+       trace_cards(aging_gen,data->aging,collector);
        trace_code_heap_roots(collector);
        collector.go();
        update_dirty_code_blocks();
@@ -550,14 +534,14 @@ void factor_vm::collect_nursery()
 
 void factor_vm::collect_aging()
 {
-       std::swap(data->generations[aging_gen],data->semispaces[aging_gen]);
-       reset_generation(aging_gen);
+       std::swap(data->aging,data->aging_semispace);
+       reset_generation(data->aging);
 
-       aging_collector collector(this,&data->generations[aging_gen]);
+       aging_collector collector(this,data->aging);
 
        trace_roots(collector);
        trace_contexts(collector);
-       trace_cards(collector);
+       trace_cards(tenured_gen,data->tenured,collector);
        trace_code_heap_roots(collector);
        collector.go();
        update_dirty_code_blocks();
@@ -567,16 +551,16 @@ void factor_vm::collect_aging()
 
 void factor_vm::collect_aging_again()
 {
-       aging_again_collector collector(this,&data->generations[tenured_gen]);
+       aging_again_collector collector(this,data->tenured);
 
        trace_roots(collector);
        trace_contexts(collector);
-       trace_cards(collector);
+       trace_cards(tenured_gen,data->tenured,collector);
        trace_code_heap_roots(collector);
        collector.go();
        update_dirty_code_blocks();
 
-       reset_generation(aging_gen);
+       reset_generation(data->aging);
        nursery.here = nursery.start;
 }
 
@@ -589,18 +573,18 @@ void factor_vm::collect_tenured(cell requested_bytes, bool trace_contexts_)
        }
        else
        {
-               std::swap(data->generations[tenured_gen],data->semispaces[tenured_gen]);
-               reset_generation(tenured_gen);
+               std::swap(data->tenured,data->tenured_semispace);
+               reset_generation(data->tenured);
        }
 
-       tenured_collector collector(this,&data->generations[tenured_gen]);
+       tenured_collector collector(this,data->tenured);
 
         trace_roots(collector);
         if(trace_contexts_) trace_contexts(collector);
         collector.go();
         free_unmarked_code_blocks();
 
-       reset_generation(aging_gen);
+       reset_generation(data->aging);
        nursery.here = nursery.start;
 
        if(current_gc->growing_data_heap)
@@ -798,23 +782,15 @@ object *factor_vm::allot_object(header header, cell size)
        tenured space */
        else
        {
-               zone *tenured = &data->generations[tenured_gen];
-
                /* If tenured space does not have enough room, collect */
-               if(tenured->here + size > tenured->end)
-               {
+               if(data->tenured->here + size > data->tenured->end)
                        gc();
-                       tenured = &data->generations[tenured_gen];
-               }
 
                /* If it still won't fit, grow the heap */
-               if(tenured->here + size > tenured->end)
-               {
+               if(data->tenured->here + size > data->tenured->end)
                        garbage_collection(tenured_gen,true,true,size);
-                       tenured = &data->generations[tenured_gen];
-               }
 
-               obj = tenured->allot(size);
+               obj = data->tenured->allot(size);
                allot_barrier(obj);
 
                /* Allows initialization code to store old->new pointers
index 5ccde31f37949edc5fe6fe8ad5d1b3506888afe8..4fc9770c559d239a1b836806af6c56c266775e39 100755 (executable)
@@ -27,12 +27,7 @@ data_heap::data_heap(factor_vm *myvm, cell young_size_, cell aging_size_, cell t
 
        seg = new segment(total_size);
 
-       generations = new zone[gen_count];
-       semispaces = new zone[gen_count];
-
        cell cards_size = total_size >> card_bits;
-       allot_markers = new char[cards_size];
-       allot_markers_end = allot_markers + cards_size;
 
        cards = new char[cards_size];
        cards_end = cards + cards_size;
@@ -41,21 +36,41 @@ data_heap::data_heap(factor_vm *myvm, cell young_size_, cell aging_size_, cell t
        decks = new char[decks_size];
        decks_end = decks + decks_size;
 
+       allot_markers = new char[cards_size];
+       allot_markers_end = allot_markers + cards_size;
+
        cell alloter = align(seg->start,deck_size);
 
-       alloter = generations[tenured_gen].init_zone(tenured_size,alloter);
-       alloter = semispaces[tenured_gen].init_zone(tenured_size,alloter);
+       tenured = new zone;
+       tenured_semispace = new zone;
+       alloter = tenured->init_zone(tenured_size,alloter);
+       alloter = tenured_semispace->init_zone(tenured_size,alloter);
 
-       alloter = generations[aging_gen].init_zone(aging_size,alloter);
-       alloter = semispaces[aging_gen].init_zone(aging_size,alloter);
+       aging = new zone;
+       aging_semispace = new zone;
+       alloter = aging->init_zone(aging_size,alloter);
+       alloter = aging_semispace->init_zone(aging_size,alloter);
 
-       alloter = generations[nursery_gen].init_zone(young_size,alloter);
-       alloter = semispaces[nursery_gen].init_zone(0,alloter);
+       nursery = new zone;
+       alloter = nursery->init_zone(young_size,alloter);
 
        if(seg->end - alloter > deck_size)
                critical_error("Bug in alloc_data_heap",alloter);
 }
 
+data_heap::~data_heap()
+{
+       delete seg;
+       delete nursery;
+       delete aging;
+       delete aging_semispace;
+       delete tenured;
+       delete tenured_semispace;
+       delete[] allot_markers;
+       delete[] cards;
+       delete[] decks;
+}
+
 data_heap *factor_vm::grow_data_heap(data_heap *data, cell requested_bytes)
 {
        cell new_tenured_size = (data->tenured_size * 2) + requested_bytes;
@@ -66,48 +81,35 @@ data_heap *factor_vm::grow_data_heap(data_heap *data, cell requested_bytes)
                new_tenured_size);
 }
 
-data_heap::~data_heap()
-{
-       delete seg;
-       delete[] generations;
-       delete[] semispaces;
-       delete[] allot_markers;
-       delete[] cards;
-       delete[] decks;
-}
-
-void factor_vm::clear_cards(cell gen)
+void factor_vm::clear_cards(zone *gen)
 {
        /* NOTE: reverse order due to heap layout. */
-       card *first_card = addr_to_card(data->generations[gen].start);
-       card *last_card = addr_to_card(data->generations[gen].end);
+       card *first_card = addr_to_card(gen->start);
+       card *last_card = addr_to_card(gen->end);
        memset(first_card,0,last_card - first_card);
 }
 
-void factor_vm::clear_decks(cell gen)
+void factor_vm::clear_decks(zone *gen)
 {
        /* NOTE: reverse order due to heap layout. */
-       card_deck *first_deck = addr_to_deck(data->generations[gen].start);
-       card_deck *last_deck = addr_to_deck(data->generations[gen].end);
+       card_deck *first_deck = addr_to_deck(gen->start);
+       card_deck *last_deck = addr_to_deck(gen->end);
        memset(first_deck,0,last_deck - first_deck);
 }
 
-void factor_vm::clear_allot_markers(cell gen)
+void factor_vm::clear_allot_markers(zone *gen)
 {
-       card *first_card = addr_to_allot_marker((object *)data->generations[gen].start);
-       card *last_card = addr_to_allot_marker((object *)data->generations[gen].end);
+       card *first_card = addr_to_allot_marker((object *)gen->start);
+       card *last_card = addr_to_allot_marker((object *)gen->end);
        memset(first_card,invalid_allot_marker,last_card - first_card);
 }
 
 /* After garbage collection, any generations which are now empty need to have
 their allocation pointers and cards reset. */
-void factor_vm::reset_generation(cell gen)
+void factor_vm::reset_generation(zone *gen)
 {
-       assert(gen != nursery_gen);
-
-       zone *z = &data->generations[gen];
-       z->here = z->start;
-       if(secure_gc) memset((void*)z->start,69,z->size);
+       gen->here = gen->start;
+       if(secure_gc) memset((void*)gen->start,69,gen->size);
 
        clear_cards(gen);
        clear_decks(gen);
@@ -117,18 +119,17 @@ void factor_vm::reset_generation(cell gen)
 void factor_vm::set_data_heap(data_heap *data_)
 {
        data = data_;
-       nursery = data->generations[nursery_gen];
+       nursery = *data->nursery;
        nursery.here = nursery.start;
        init_card_decks();
-       reset_generation(aging_gen);
-       reset_generation(tenured_gen);
+       reset_generation(data->aging);
+       reset_generation(data->tenured);
 }
 
 void factor_vm::init_data_heap(cell young_size, cell aging_size, cell tenured_size, bool secure_gc_)
 {
        set_data_heap(new data_heap(this,young_size,aging_size,tenured_size));
        secure_gc = secure_gc_;
-       init_data_gc();
 }
 
 /* Size of the object pointed to by a tagged pointer */
@@ -231,13 +232,14 @@ void factor_vm::primitive_data_room()
 
        growable_array a(this);
 
-       cell gen;
-       for(gen = 0; gen < gen_count; gen++)
-       {
-               zone *z = (gen == nursery_gen ? &nursery : &data->generations[gen]);
-               a.add(tag_fixnum((z->end - z->here) >> 10));
-               a.add(tag_fixnum((z->size) >> 10));
-       }
+       a.add(tag_fixnum((nursery.end - nursery.here) >> 10));
+       a.add(tag_fixnum((nursery.size) >> 10));
+
+       a.add(tag_fixnum((data->aging->end - data->aging->here) >> 10));
+       a.add(tag_fixnum((data->aging->size) >> 10));
+
+       a.add(tag_fixnum((data->tenured->end - data->tenured->here) >> 10));
+       a.add(tag_fixnum((data->tenured->size) >> 10));
 
        a.trim();
        dpush(a.elements.value());
@@ -246,7 +248,7 @@ void factor_vm::primitive_data_room()
 /* Disables GC and activates next-object ( -- obj ) primitive */
 void factor_vm::begin_scan()
 {
-       heap_scan_ptr = data->generations[tenured_gen].start;
+       heap_scan_ptr = data->tenured->start;
        gc_off = true;
 }
 
@@ -265,7 +267,7 @@ cell factor_vm::next_object()
        if(!gc_off)
                general_error(ERROR_HEAP_SCAN,F,F,NULL);
 
-       if(heap_scan_ptr >= data->generations[tenured_gen].here)
+       if(heap_scan_ptr >= data->tenured->here)
                return F;
 
        object *obj = (object *)heap_scan_ptr;
@@ -294,9 +296,6 @@ template<typename Iterator> void factor_vm::each_object(Iterator &iterator)
        end_scan();
 }
 
-namespace
-{
-
 struct word_counter {
        cell count;
        explicit word_counter() : count(0) {}
@@ -309,8 +308,6 @@ struct word_accumulator {
        void operator()(tagged<object> obj) { if(obj.type_p(WORD_TYPE)) words.add(obj.value()); }
 };
 
-}
-
 cell factor_vm::find_all_words()
 {
        word_counter counter;
index cd53d66768f6cace0bae4626f1b661f151a201c2..891d1361edee43e0797e489e8b31950486e03820 100755 (executable)
@@ -1,45 +1,18 @@
 namespace factor
 {
 
-/* generational copying GC divides memory into zones */
-struct zone {
-       /* allocation pointer is 'here'; its offset is hardcoded in the
-       compiler backends */
-       cell start;
-       cell here;
-       cell size;
-       cell end;
-
-       cell init_zone(cell size_, cell start_)
-       {
-               size = size_;
-               start = here = start_;
-               end = start_ + size_;
-               return end;
-       }
-
-       inline bool contains_p(object *pointer)
-       {
-               return ((cell)pointer - start) < size;
-       }
-
-       inline object *allot(cell size)
-       {
-               cell h = here;
-               here = h + align8(size);
-               return (object *)h;
-       }
-};
-
 struct data_heap {
-       segment *seg;
-
        cell young_size;
        cell aging_size;
        cell tenured_size;
 
-       zone *generations;
-       zone *semispaces;
+       segment *seg;
+
+       zone *nursery;
+       zone *aging;
+       zone *aging_semispace;
+       zone *tenured;
+       zone *tenured_semispace;
 
        char *allot_markers;
        char *allot_markers_end;
index e1c1fa5a8584f1bbcd8522bb043ba4508a6409d9..5460a309fd4e6736bbcbdce381041e629b97a0ed 100755 (executable)
@@ -211,8 +211,9 @@ void factor_vm::dump_memory(cell from, cell to)
                dump_cell(from);
 }
 
-void factor_vm::dump_zone(zone *z)
+void factor_vm::dump_zone(cell gen, zone *z)
 {
+       print_string("Generation "); print_cell(gen); print_string(": ");
        print_string("Start="); print_cell(z->start);
        print_string(", size="); print_cell(z->size);
        print_string(", here="); print_cell(z->here - z->start); nl();
@@ -220,22 +221,9 @@ void factor_vm::dump_zone(zone *z)
 
 void factor_vm::dump_generations()
 {
-       cell i;
-
-       print_string("Nursery: ");
-       dump_zone(&nursery);
-       
-       for(i = 1; i < gen_count; i++)
-       {
-               print_string("Generation "); print_cell(i); print_string(": ");
-               dump_zone(&data->generations[i]);
-       }
-
-       for(i = 0; i < gen_count; i++)
-       {
-               print_string("Semispace "); print_cell(i); print_string(": ");
-               dump_zone(&data->semispaces[i]);
-       }
+       dump_zone(nursery_gen,&nursery);
+       dump_zone(aging_gen,data->aging);
+       dump_zone(tenured_gen,data->tenured);
 
        print_string("Cards: base=");
        print_cell((cell)data->cards);
diff --git a/vm/gc/zone.hpp b/vm/gc/zone.hpp
new file mode 100644 (file)
index 0000000..a05afd4
--- /dev/null
@@ -0,0 +1,33 @@
+namespace factor
+{
+
+struct zone {
+       /* allocation pointer is 'here'; its offset is hardcoded in the
+       compiler backends */
+       cell start;
+       cell here;
+       cell size;
+       cell end;
+
+       cell init_zone(cell size_, cell start_)
+       {
+               size = size_;
+               start = here = start_;
+               end = start_ + size_;
+               return end;
+       }
+
+       inline bool contains_p(object *pointer)
+       {
+               return ((cell)pointer - start) < size;
+       }
+
+       inline object *allot(cell size)
+       {
+               cell h = here;
+               here = h + align8(size);
+               return (object *)h;
+       }
+};
+
+}
index 5af87905062a74a7244514895e6e2658fd54ea02..9a7093750836731a4deb624ac51ebc36f9bf7e38 100755 (executable)
@@ -28,9 +28,7 @@ void factor_vm::load_data_heap(FILE *file, image_header *h, vm_parameters *p)
 
        clear_gc_stats();
 
-       zone *tenured = &data->generations[tenured_gen];
-
-       fixnum bytes_read = fread((void*)tenured->start,1,h->data_size,file);
+       fixnum bytes_read = fread((void*)data->tenured->start,1,h->data_size,file);
 
        if((cell)bytes_read != h->data_size)
        {
@@ -42,7 +40,7 @@ void factor_vm::load_data_heap(FILE *file, image_header *h, vm_parameters *p)
                fatal_error("load_data_heap failed",0);
        }
 
-       tenured->here = tenured->start + h->data_size;
+       data->tenured->here = data->tenured->start + h->data_size;
        data_relocation_base = h->data_relocation_base;
 }
 
@@ -85,12 +83,10 @@ bool factor_vm::save_image(const vm_char *filename)
                return false;
        }
 
-       zone *tenured = &data->generations[tenured_gen];
-
        h.magic = image_magic;
        h.version = image_version;
-       h.data_relocation_base = tenured->start;
-       h.data_size = tenured->here - tenured->start;
+       h.data_relocation_base = data->tenured->start;
+       h.data_size = data->tenured->here - data->tenured->start;
        h.code_relocation_base = code->seg->start;
        h.code_size = code->heap_size();
 
@@ -105,7 +101,7 @@ bool factor_vm::save_image(const vm_char *filename)
        bool ok = true;
 
        if(fwrite(&h,sizeof(image_header),1,file) != 1) ok = false;
-       if(fwrite((void*)tenured->start,h.data_size,1,file) != 1) ok = false;
+       if(fwrite((void*)data->tenured->start,h.data_size,1,file) != 1) ok = false;
        if(fwrite(code->first_block(),h.code_size,1,file) != 1) ok = false;
        if(fclose(file)) ok = false;
 
@@ -156,8 +152,7 @@ void factor_vm::data_fixup(cell *cell)
        if(immediate_p(*cell))
                return;
 
-       zone *tenured = &data->generations[tenured_gen];
-       *cell += (tenured->start - data_relocation_base);
+       *cell += (data->tenured->start - data_relocation_base);
 }
 
 template<typename Type> void factor_vm::code_fixup(Type **handle)
@@ -280,10 +275,8 @@ void factor_vm::relocate_data()
        data_fixup(&bignum_pos_one);
        data_fixup(&bignum_neg_one);
 
-       zone *tenured = &data->generations[tenured_gen];
-
-       for(relocating = tenured->start;
-               relocating < tenured->here;
+       for(relocating = data->tenured->start;
+               relocating < data->tenured->here;
                relocating += untagged_object_size((object *)relocating))
        {
                object *obj = (object *)relocating;
index 457dbee0ab7edd2d04936aca522ca2b9551eefcb..d942c1a3ac7c69252d13e9b677d29d5d2f87a37a 100755 (executable)
@@ -69,6 +69,7 @@ namespace factor
 #include "bignumint.hpp"
 #include "bignum.hpp"
 #include "code_block.hpp"
+#include "gc/zone.hpp"
 #include "data_heap.hpp"
 #include "write_barrier.hpp"
 #include "data_gc.hpp"
index 0ad1303156a0ae0743727d65a1ba7796a0aba072..9836342fe22849f56da252f59ec2debdc73ded7c 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -211,10 +211,10 @@ struct factor_vm
        //data_heap
        void init_card_decks();
        data_heap *grow_data_heap(data_heap *data, cell requested_bytes);
-       void clear_cards(cell gen);
-       void clear_decks(cell gen);
-       void clear_allot_markers(cell gen);
-       void reset_generation(cell gen);
+       void clear_cards(zone *gen);
+       void clear_decks(zone *gen);
+       void clear_allot_markers(zone *gen);
+       void reset_generation(zone *gen);
        void set_data_heap(data_heap *data_);
        void init_data_heap(cell young_size, cell aging_size, cell tenured_size, bool secure_gc_);
        cell untagged_object_size(object *pointer);
@@ -285,15 +285,13 @@ struct factor_vm
        }
 
        // data_gc
-       void init_data_gc();
        template<typename Strategy> object *resolve_forwarding(object *untagged, Strategy &strategy);
        template<typename Strategy> void trace_handle(cell *handle, Strategy &strategy);
        template<typename Strategy> object *promote_object(object *pointer, Strategy &strategy);
        template<typename Strategy> void trace_slots(object *ptr, Strategy &strategy);
-       template<typename Strategy> void trace_card(card *ptr, cell gen, cell here, Strategy &strategy);
-       template<typename Strategy> void trace_card_deck(card_deck *deck, cell gen, card mask, card unmask, Strategy &strategy);
-       template<typename Strategy> void trace_generation_cards(cell gen, Strategy &strategy);
-       template<typename Strategy> void trace_cards(Strategy &strategy);
+       template<typename Strategy> void trace_card(card *ptr, cell here, Strategy &strategy);
+       template<typename Strategy> void trace_card_deck(card_deck *deck, cell here, card mask, card unmask, Strategy &strategy);
+       template<typename Strategy> void trace_cards(cell gen, zone *z, Strategy &strategy);
        template<typename Strategy> void trace_stack_elements(segment *region, cell top, Strategy &strategy);
        template<typename Strategy> void trace_registered_locals(Strategy &strategy);
        template<typename Strategy> void trace_registered_bignums(Strategy &strategy);
@@ -368,7 +366,7 @@ struct factor_vm
        void print_callstack();
        void dump_cell(cell x);
        void dump_memory(cell from, cell to);
-       void dump_zone(zone *z);
+       void dump_zone(cell gen, zone *z);
        void dump_generations();
        void dump_objects(cell type);
        void find_data_references_step(cell *scan);