From b7181d14a8340a2ad8f9db143bd7a63401c21d39 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 25 Oct 2009 08:07:21 -0500 Subject: [PATCH] vm: debugging compaction --- vm/compaction.cpp | 31 ++++++++++++++++++++----------- vm/free_list_allocator.hpp | 18 ++++++++++++++++++ vm/full_collector.cpp | 27 ++++++++++++++++++--------- vm/mark_bits.hpp | 28 ++++++++-------------------- vm/vm.hpp | 5 +++-- 5 files changed, 67 insertions(+), 42 deletions(-) diff --git a/vm/compaction.cpp b/vm/compaction.cpp index a98876ffd4..74dd8935da 100644 --- a/vm/compaction.cpp +++ b/vm/compaction.cpp @@ -67,6 +67,7 @@ struct object_compaction_updater { slot_visitor slot_forwarder; code_block_visitor code_forwarder; mark_bits *data_forwarding_map; + object_start_map *starts; explicit object_compaction_updater(factor_vm *parent_, slot_visitor slot_forwarder_, @@ -75,18 +76,22 @@ struct object_compaction_updater { parent(parent_), slot_forwarder(slot_forwarder_), code_forwarder(code_forwarder_), - data_forwarding_map(data_forwarding_map_) {} + data_forwarding_map(data_forwarding_map_), + starts(&parent->data->tenured->starts) {} - void operator()(object *obj, cell size) + void operator()(object *old_address, object *new_address, cell size) { cell payload_start; - if(obj->h.hi_tag() == TUPLE_TYPE) - payload_start = tuple_size_with_forwarding(data_forwarding_map,obj); + if(old_address->h.hi_tag() == TUPLE_TYPE) + payload_start = tuple_size_with_forwarding(data_forwarding_map,old_address); else - payload_start = obj->binary_payload_start(); + payload_start = old_address->binary_payload_start(); - slot_forwarder.visit_slots(obj,payload_start); - code_forwarder.visit_object_code_block(obj); + memmove(new_address,old_address,size); + + slot_forwarder.visit_slots(new_address,payload_start); + code_forwarder.visit_object_code_block(new_address); + starts->record_object_start_offset(new_address); } }; @@ -97,14 +102,15 @@ struct code_block_compaction_updater { explicit code_block_compaction_updater(factor_vm *parent_, slot_visitor slot_forwarder_) : parent(parent_), slot_forwarder(slot_forwarder_) {} - void operator()(code_block *compiled, cell size) + void operator()(code_block *old_address, code_block *new_address, cell size) { - slot_forwarder.visit_literal_references(compiled); - parent->relocate_code_block(compiled); + memmove(new_address,old_address,size); + slot_forwarder.visit_literal_references(new_address); + parent->relocate_code_block(new_address); } }; -void factor_vm::compact_full_impl(bool trace_contexts_p) +void factor_vm::collect_full_compact(bool trace_contexts_p) { tenured_space *tenured = data->tenured; mark_bits *data_forwarding_map = &tenured->state; @@ -118,6 +124,9 @@ void factor_vm::compact_full_impl(bool trace_contexts_p) slot_visitor slot_forwarder(this,object_slot_forwarder(data_forwarding_map)); code_block_visitor code_forwarder(this,code_block_forwarder(code_forwarding_map)); + /* Object start offsets get recomputed by the object_compaction_updater */ + data->tenured->starts.clear_object_start_offsets(); + /* Slide everything in tenured space up, and update data and code heap pointers inside objects. */ object_compaction_updater object_updater(this,slot_forwarder,code_forwarder,data_forwarding_map); diff --git a/vm/free_list_allocator.hpp b/vm/free_list_allocator.hpp index 0f2271beac..822a40f797 100644 --- a/vm/free_list_allocator.hpp +++ b/vm/free_list_allocator.hpp @@ -356,6 +356,24 @@ void free_list_allocator::sweep(Iterator &iter) this->add_to_free_list((free_heap_block *)prev); } +template struct heap_compactor { + mark_bits *state; + char *address; + Iterator &iter; + + explicit heap_compactor(mark_bits *state_, Block *address_, Iterator &iter_) : + state(state_), address((char *)address_), iter(iter_) {} + + void operator()(Block *block, cell size) + { + if(this->state->marked_p(block)) + { + iter(block,(Block *)address,size); + address += size; + } + } +}; + /* The forwarding map must be computed first by calling state.compute_forwarding(). */ template diff --git a/vm/full_collector.cpp b/vm/full_collector.cpp index 18e368ab2b..65d0edbd47 100644 --- a/vm/full_collector.cpp +++ b/vm/full_collector.cpp @@ -40,7 +40,7 @@ struct object_start_map_updater { } }; -void factor_vm::collect_full_impl(bool trace_contexts_p) +void factor_vm::collect_full_mark(bool trace_contexts_p) { full_collector collector(this); @@ -68,16 +68,19 @@ void factor_vm::collect_full_impl(bool trace_contexts_p) code_marker.visit_object_code_block(obj); } - 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); data->reset_generation(&nursery); code->clear_remembered_set(); } +void factor_vm::collect_full_sweep() +{ + data->tenured->starts.clear_object_start_offsets(); + object_start_map_updater updater(&data->tenured->starts); + data->tenured->sweep(updater); +} + void factor_vm::collect_growing_heap(cell requested_bytes, bool trace_contexts_p, bool compact_p) @@ -85,23 +88,29 @@ void factor_vm::collect_growing_heap(cell requested_bytes, /* Grow the data heap and copy all live objects to the new heap. */ data_heap *old = data; set_data_heap(data->grow(requested_bytes)); - collect_full_impl(trace_contexts_p); + collect_full_mark(trace_contexts_p); delete old; if(compact_p) - compact_full_impl(trace_contexts_p); + collect_full_compact(trace_contexts_p); else + { + collect_full_sweep(); relocate_code_heap(); + } } void factor_vm::collect_full(bool trace_contexts_p, bool compact_p) { - collect_full_impl(trace_contexts_p); + collect_full_mark(trace_contexts_p); if(compact_p) - compact_full_impl(trace_contexts_p); + collect_full_compact(trace_contexts_p); else + { + collect_full_sweep(); update_code_heap_words_and_literals(); + } } } diff --git a/vm/mark_bits.hpp b/vm/mark_bits.hpp index cd739346f0..8b6b0c75eb 100644 --- a/vm/mark_bits.hpp +++ b/vm/mark_bits.hpp @@ -139,32 +139,20 @@ template struct mark_bits { /* We have the popcount for every 64 entries; look up and compute the rest */ Block *forward_block(Block *original) { +#ifdef FACTOR_DEBUG + assert(marked_p(original)); +#endif std::pair pair = bitmap_deref(original); cell approx_popcount = forwarding[pair.first]; u64 mask = ((u64)1 << pair.second) - 1; cell new_line_number = approx_popcount + popcount(marked[pair.first] & mask); - return line_block(new_line_number); - } -}; - -template struct heap_compactor { - mark_bits *state; - char *address; - Iterator &iter; - - explicit heap_compactor(mark_bits *state_, Block *address_, Iterator &iter_) : - state(state_), address((char *)address_), iter(iter_) {} - - void operator()(Block *block, cell size) - { - if(this->state->marked_p(block)) - { - memmove(address,block,size); - iter((Block *)address,size); - address += size; - } + Block *new_block = line_block(new_line_number); +#ifdef FACTOR_DEBUG + assert(new_block <= original); +#endif + return new_block; } }; diff --git a/vm/vm.hpp b/vm/vm.hpp index 29084d255d..f0f37619d2 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -247,8 +247,9 @@ struct factor_vm void collect_nursery(); void collect_aging(); void collect_to_tenured(); - void collect_full_impl(bool trace_contexts_p); - void compact_full_impl(bool trace_contexts_p); + void collect_full_mark(bool trace_contexts_p); + void collect_full_sweep(); + void collect_full_compact(bool trace_contexts_p); void collect_growing_heap(cell requested_bytes, bool trace_contexts_p, bool compact_p); void collect_full(bool trace_contexts_p, bool compact_p); void record_gc_stats(generation_statistics *stats);