From af855b7fa9ec681ae056395047cc4929de80b06c Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 21 Oct 2009 19:41:54 -0500 Subject: [PATCH] vm: debugging mark-sweep --- vm/aging_collector.cpp | 3 ++- vm/data_heap.cpp | 34 +++++++++++++++++++++++++++++++++- vm/data_heap.hpp | 28 +++------------------------- vm/free_list_allocator.hpp | 23 +++++++++++++---------- vm/full_collector.cpp | 25 +++++++++++++++++++------ vm/layouts.hpp | 25 +++++++++++-------------- vm/mark_bits.hpp | 5 ----- vm/nursery_collector.cpp | 2 +- vm/tenured_space.hpp | 5 +++++ vm/to_tenured_collector.cpp | 9 +++++---- 10 files changed, 92 insertions(+), 67 deletions(-) diff --git a/vm/aging_collector.cpp b/vm/aging_collector.cpp index 2972528cb3..d33823b624 100644 --- a/vm/aging_collector.cpp +++ b/vm/aging_collector.cpp @@ -40,9 +40,10 @@ void factor_vm::collect_aging() collector.trace_contexts(); collector.trace_code_heap_roots(&code->points_to_aging); collector.cheneys_algorithm(); + update_code_heap_for_minor_gc(&code->points_to_aging); - nursery.here = nursery.start; + data->reset_generation(&nursery); code->points_to_nursery.clear(); } } diff --git a/vm/data_heap.cpp b/vm/data_heap.cpp index 7c887c7419..915ed8e32a 100755 --- a/vm/data_heap.cpp +++ b/vm/data_heap.cpp @@ -65,11 +65,43 @@ data_heap *data_heap::grow(cell requested_bytes) return new data_heap(young_size,aging_size,new_tenured_size); } +template void data_heap::clear_cards(Generation *gen) +{ + cell first_card = addr_to_card(gen->start - start); + cell last_card = addr_to_card(gen->end - start); + memset(&cards[first_card],0,last_card - first_card); +} + +template void data_heap::clear_decks(Generation *gen) +{ + cell first_deck = addr_to_deck(gen->start - start); + cell last_deck = addr_to_deck(gen->end - start); + memset(&decks[first_deck],0,last_deck - first_deck); +} + +void data_heap::reset_generation(nursery_space *gen) +{ + gen->here = gen->start; +} + +void data_heap::reset_generation(aging_space *gen) +{ + gen->here = gen->start; + clear_cards(gen); + clear_decks(gen); + gen->starts.clear_object_start_offsets(); +} + +void data_heap::reset_generation(tenured_space *gen) +{ + clear_cards(gen); + clear_decks(gen); +} + void factor_vm::set_data_heap(data_heap *data_) { data = data_; nursery = *data->nursery; - nursery.here = nursery.start; init_card_decks(); } diff --git a/vm/data_heap.hpp b/vm/data_heap.hpp index fe714b91b0..c8d6ce0b70 100755 --- a/vm/data_heap.hpp +++ b/vm/data_heap.hpp @@ -26,31 +26,9 @@ struct data_heap { data_heap *grow(cell requested_size); template void clear_cards(Generation *gen); template void clear_decks(Generation *gen); - template void reset_generation(Generation *gen); + void reset_generation(nursery_space *gen); + void reset_generation(aging_space *gen); + void reset_generation(tenured_space *gen); }; -template void data_heap::clear_cards(Generation *gen) -{ - cell first_card = addr_to_card(gen->start - start); - cell last_card = addr_to_card(gen->end - start); - memset(&cards[first_card],0,last_card - first_card); -} - -template void data_heap::clear_decks(Generation *gen) -{ - cell first_deck = addr_to_deck(gen->start - start); - cell last_deck = addr_to_deck(gen->end - start); - memset(&decks[first_deck],0,last_deck - first_deck); -} - -/* After garbage collection, any generations which are now empty need to have -their allocation pointers and cards reset. */ -template void data_heap::reset_generation(Generation *gen) -{ - gen->here = gen->start; - clear_cards(gen); - clear_decks(gen); - gen->starts.clear_object_start_offsets(); -} - } diff --git a/vm/free_list_allocator.hpp b/vm/free_list_allocator.hpp index c8f3bd6f47..efdad508cb 100644 --- a/vm/free_list_allocator.hpp +++ b/vm/free_list_allocator.hpp @@ -88,10 +88,12 @@ Makes a free list consisting of one free block, at the very end. */ template void free_list_allocator::build_free_list(cell size) { clear_free_list(); - free_heap_block *last_block = (free_heap_block *)(start + size); - last_block->set_free(); - last_block->set_size(end - (cell)last_block); - add_to_free_list(last_block); + if(size != this->size) + { + free_heap_block *last_block = (free_heap_block *)(start + size); + last_block->make_free(end - (cell)last_block); + add_to_free_list(last_block); + } } template void free_list_allocator::assert_free_block(free_heap_block *block) @@ -147,10 +149,9 @@ template free_heap_block *free_list_allocator::split_free { /* split the block in two */ free_heap_block *split = (free_heap_block *)((cell)block + size); - split->set_free(); - split->set_size(block->size() - size); + split->make_free(block->size() - size); split->next_free = block->next_free; - block->set_size(size); + block->make_free(size); add_to_free_list(split); } @@ -174,7 +175,7 @@ template Block *free_list_allocator::allot(cell size) template void free_list_allocator::free(Block *block) { free_heap_block *free_block = (free_heap_block *)block; - free_block->set_free(); + free_block->make_free(block->size()); add_to_free_list(free_block); } @@ -267,7 +268,8 @@ void free_list_allocator::sweep() } else { - ((free_heap_block *)scan)->set_free(); + free_heap_block *free_block = (free_heap_block *)scan; + free_block->make_free(size); prev = scan; } } @@ -319,7 +321,8 @@ void free_list_allocator::sweep(Iterator &iter) } else { - scan->set_free(); + free_heap_block *free_block = (free_heap_block *)scan; + free_block->make_free(size); prev = scan; } } diff --git a/vm/full_collector.cpp b/vm/full_collector.cpp index 9191823d75..817908ece5 100644 --- a/vm/full_collector.cpp +++ b/vm/full_collector.cpp @@ -108,12 +108,24 @@ void full_collector::mark_reachable_objects() } } +struct object_start_map_updater { + object_start_map *starts; + + object_start_map_updater(object_start_map *starts_) : starts(starts_) {} + + void operator()(object *obj, cell size) + { + starts->record_object_start_offset(obj); + } +}; + void factor_vm::collect_full_impl(bool trace_contexts_p) { full_collector collector(this); code->clear_mark_bits(); data->tenured->clear_mark_bits(); + data->tenured->clear_mark_stack(); collector.trace_roots(); if(trace_contexts_p) @@ -125,9 +137,14 @@ void factor_vm::collect_full_impl(bool trace_contexts_p) collector.mark_reachable_objects(); - data->tenured->sweep(); + data->tenured->starts.clear_object_start_offsets(); + object_start_map_updater updater(&data->tenured->starts); + data->tenured->sweep(updater); + + data->reset_generation(data->tenured); data->reset_generation(data->aging); - nursery.here = nursery.start; + data->reset_generation(&nursery); + code->clear_remembered_set(); } void factor_vm::collect_growing_heap(cell requested_bytes, @@ -144,8 +161,6 @@ void factor_vm::collect_growing_heap(cell requested_bytes, compact_code_heap(trace_contexts_p); else relocate_code_heap(); - - code->clear_remembered_set(); } void factor_vm::collect_full(bool trace_contexts_p, bool compact_code_heap_p) @@ -156,8 +171,6 @@ void factor_vm::collect_full(bool trace_contexts_p, bool compact_code_heap_p) compact_code_heap(trace_contexts_p); else update_code_heap_words_and_literals(); - - code->clear_remembered_set(); } } diff --git a/vm/layouts.hpp b/vm/layouts.hpp index ca51fd6dca..76581621ca 100644 --- a/vm/layouts.hpp +++ b/vm/layouts.hpp @@ -58,8 +58,6 @@ static const cell data_alignment = 16; #define TYPE_COUNT 15 -/* Not real types, but code_block's type can be set to this */ - enum code_block_type { code_block_unoptimized, @@ -229,30 +227,29 @@ struct heap_block return header & 1 == 1; } - void set_free() - { - header |= 1; - } - - void clear_free() - { - header &= ~1; - } - cell size() { - return header >> 3; + cell bytes = header >> 3; +#ifdef FACTOR_DEBUG + assert(bytes > 0); +#endif + return bytes; } void set_size(cell size) { - header = (header & 0x7) | (size << 3); + header = ((header & 0x7) | (size << 3)); } }; struct free_heap_block : public heap_block { free_heap_block *next_free; + + void make_free(cell size) + { + header = (size << 3) | 1; + } }; struct code_block : public heap_block diff --git a/vm/mark_bits.hpp b/vm/mark_bits.hpp index 44f8b17e35..161a7fd755 100644 --- a/vm/mark_bits.hpp +++ b/vm/mark_bits.hpp @@ -55,11 +55,6 @@ template struct mark_bits { cell line_number = block_line(address); cell word_index = (line_number >> 6); cell word_shift = (line_number & 63); - -#ifdef FACTOR_DEBUG - assert(word_index < bits_size); -#endif - return std::make_pair(word_index,word_shift); } diff --git a/vm/nursery_collector.cpp b/vm/nursery_collector.cpp index 909cde02f8..07f9666f37 100644 --- a/vm/nursery_collector.cpp +++ b/vm/nursery_collector.cpp @@ -28,7 +28,7 @@ void factor_vm::collect_nursery() collector.cheneys_algorithm(); update_code_heap_for_minor_gc(&code->points_to_nursery); - nursery.here = nursery.start; + data->reset_generation(&nursery); code->points_to_nursery.clear(); } diff --git a/vm/tenured_space.hpp b/vm/tenured_space.hpp index c0c12d3f58..7cc4131fa0 100644 --- a/vm/tenured_space.hpp +++ b/vm/tenured_space.hpp @@ -51,6 +51,11 @@ struct tenured_space : free_list_allocator { state.clear_mark_bits(); } + void clear_mark_stack() + { + mark_stack.clear(); + } + bool marked_p(object *obj) { return this->state.marked_p(obj); diff --git a/vm/to_tenured_collector.cpp b/vm/to_tenured_collector.cpp index 3150647cd2..ea7cb8ed72 100644 --- a/vm/to_tenured_collector.cpp +++ b/vm/to_tenured_collector.cpp @@ -26,19 +26,20 @@ void factor_vm::collect_to_tenured() /* Copy live objects from aging space to tenured space. */ to_tenured_collector collector(this); + data->tenured->clear_mark_stack(); + collector.trace_roots(); collector.trace_contexts(); collector.trace_cards(data->tenured, card_points_to_aging, - dummy_unmarker()); + simple_unmarker(card_mark_mask)); collector.trace_code_heap_roots(&code->points_to_aging); collector.tenure_reachable_objects(); update_code_heap_for_minor_gc(&code->points_to_aging); - nursery.here = nursery.start; + data->reset_generation(&nursery); data->reset_generation(data->aging); - code->points_to_nursery.clear(); - code->points_to_aging.clear(); + code->clear_remembered_set(); } }