From bfd4cce364e54dca4e652a43c9936ba3c98d2c8c Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 24 Nov 2009 19:29:59 -0600 Subject: [PATCH] vm: compaction now updates the needs_fixup set --- vm/code_block_visitor.hpp | 12 ++--- vm/code_blocks.cpp | 8 ++-- vm/code_heap.cpp | 13 ------ vm/collector.hpp | 13 ++++-- vm/compaction.cpp | 93 ++++++++++++++++++++++++++++++------- vm/full_collector.cpp | 5 +- vm/instruction_operands.cpp | 19 +++++--- vm/instruction_operands.hpp | 1 + vm/slot_visitor.hpp | 15 ++++-- vm/vm.hpp | 1 + 10 files changed, 122 insertions(+), 58 deletions(-) diff --git a/vm/code_block_visitor.hpp b/vm/code_block_visitor.hpp index dbaa00e83a..e9ed1d88ef 100644 --- a/vm/code_block_visitor.hpp +++ b/vm/code_block_visitor.hpp @@ -9,7 +9,7 @@ template struct code_block_visitor { parent(parent_), visitor(visitor_) {} void visit_object_code_block(object *obj); - void visit_referenced_code_blocks(code_block *compiled); + void visit_embedded_code_pointers(code_block *compiled); void visit_context_code_blocks(); void visit_callback_code_blocks(); }; @@ -67,17 +67,17 @@ void code_block_visitor::visit_object_code_block(object *obj) } template -struct referenced_code_blocks_visitor { +struct embedded_code_pointers_visitor { Visitor visitor; - explicit referenced_code_blocks_visitor(Visitor visitor_) : visitor(visitor_) {} + explicit embedded_code_pointers_visitor(Visitor visitor_) : visitor(visitor_) {} void operator()(relocation_entry rel, cell index, code_block *compiled) { relocation_type type = rel.rel_type(); if(type == RT_XT || type == RT_XT_PIC || type == RT_XT_PIC_TAIL) { - instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)(compiled + 1)); + instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt()); cell literal = op.load_value(); code_block *compiled = ((code_block *)literal - 1); compiled = visitor(compiled); @@ -88,11 +88,11 @@ struct referenced_code_blocks_visitor { }; template -void code_block_visitor::visit_referenced_code_blocks(code_block *compiled) +void code_block_visitor::visit_embedded_code_pointers(code_block *compiled) { if(!parent->code->needs_fixup_p(compiled)) { - referenced_code_blocks_visitor visitor(this->visitor); + embedded_code_pointers_visitor visitor(this->visitor); parent->iterate_relocations(compiled,visitor); } } diff --git a/vm/code_blocks.cpp b/vm/code_blocks.cpp index ef066f1a13..9d6e9a4b25 100755 --- a/vm/code_blocks.cpp +++ b/vm/code_blocks.cpp @@ -127,10 +127,10 @@ cell factor_vm::compute_relocation(relocation_entry rel, cell index, code_block case RT_HERE: { fixnum arg = untag_fixnum(ARG); - return (arg >= 0 ? offset + arg : (cell)(compiled + 1) - arg); + return (arg >= 0 ? offset + arg : (cell)compiled->xt() - arg); } case RT_THIS: - return (cell)(compiled + 1); + return (cell)compiled->xt(); case RT_CONTEXT: return (cell)&ctx; case RT_UNTAGGED: @@ -241,8 +241,8 @@ void factor_vm::fixup_labels(array *labels, code_block *compiled) cell offset = untag_fixnum(array_nth(labels,i + 1)); cell target = untag_fixnum(array_nth(labels,i + 2)); - instruction_operand op(rel_class,offset + (cell)(compiled + 1)); - op.store_value(target + (cell)(compiled + 1)); + instruction_operand op(rel_class,offset + (cell)compiled->xt()); + op.store_value(target + (cell)compiled->xt()); } } diff --git a/vm/code_heap.cpp b/vm/code_heap.cpp index 920a603057..bad5a2fb67 100755 --- a/vm/code_heap.cpp +++ b/vm/code_heap.cpp @@ -103,19 +103,6 @@ void factor_vm::update_code_heap_words() iterate_code_heap(updater); } -/* After growing the heap, we have to perform a full relocation to update -references to card and deck arrays. */ -struct code_heap_relocator { - factor_vm *parent; - - explicit code_heap_relocator(factor_vm *parent_) : parent(parent_) {} - - void operator()(code_block *block, cell size) - { - parent->relocate_code_block(block); - } -}; - void factor_vm::primitive_modify_code_heap() { data_root alist(dpop(),this); diff --git a/vm/collector.hpp b/vm/collector.hpp index c59f826225..4dac6d28c3 100644 --- a/vm/collector.hpp +++ b/vm/collector.hpp @@ -128,10 +128,14 @@ struct collector { data_visitor.visit_contexts(); } - /* Trace all literals referenced from a code block. Only for aging and nursery collections */ - void trace_referenced_literals(code_block *compiled) + void trace_code_block_objects(code_block *compiled) { - data_visitor.visit_referenced_literals(compiled); + data_visitor.visit_code_block_objects(compiled); + } + + void trace_embedded_literals(code_block *compiled) + { + data_visitor.visit_embedded_literals(compiled); } void trace_code_heap_roots(std::set *remembered_set) @@ -141,7 +145,8 @@ struct collector { for(; iter != end; iter++) { - trace_referenced_literals(*iter); + trace_code_block_objects(*iter); + trace_embedded_literals(*iter); code_blocks_scanned++; } } diff --git a/vm/compaction.cpp b/vm/compaction.cpp index 0c173a84f6..4b6b9d4eac 100644 --- a/vm/compaction.cpp +++ b/vm/compaction.cpp @@ -2,6 +2,21 @@ namespace factor { +void factor_vm::update_fixup_set_for_compaction(mark_bits *forwarding_map) +{ + std::set::const_iterator iter = code->needs_fixup.begin(); + std::set::const_iterator end = code->needs_fixup.end(); + + std::set new_needs_fixup; + for(; iter != end; iter++) + { + printf("a block needs fixup\n"); + new_needs_fixup.insert(forwarding_map->forward_block(*iter)); + } + + code->needs_fixup = new_needs_fixup; +} + template struct forwarder { mark_bits *forwarding_map; @@ -85,18 +100,50 @@ struct object_compaction_updater { } }; -template struct code_block_compaction_updater { +struct relative_address_updater { factor_vm *parent; - SlotForwarder slot_forwarder; + code_block *old_address; - explicit code_block_compaction_updater(factor_vm *parent_, SlotForwarder slot_forwarder_) : - parent(parent_), slot_forwarder(slot_forwarder_) {} + explicit relative_address_updater(factor_vm *parent_, code_block *old_address_) : + parent(parent_), old_address(old_address_) {} + + void operator()(relocation_entry rel, cell index, code_block *compiled) + { + instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt()); + + relocation_type type = rel.rel_type(); + cell value; + if(type == RT_HERE || type == RT_THIS) + value = parent->compute_relocation(rel,index,compiled); + else + value = op.load_value(rel.rel_offset() + (cell)old_address->xt()); + + op.store_value(value); + } +}; + +template +struct code_block_compaction_updater { + factor_vm *parent; + slot_visitor > slot_forwarder; + code_block_visitor > code_forwarder; + + explicit code_block_compaction_updater(factor_vm *parent_, + slot_visitor > slot_forwarder_, + code_block_visitor > code_forwarder_) : + parent(parent_), slot_forwarder(slot_forwarder_), code_forwarder(code_forwarder_) {} void operator()(code_block *old_address, code_block *new_address, cell size) { memmove(new_address,old_address,size); - slot_forwarder.visit_referenced_literals(new_address); - parent->relocate_code_block(new_address); + + slot_forwarder.visit_code_block_objects(new_address); + + relative_address_updater updater(parent,old_address); + parent->iterate_relocations(new_address,updater); + + slot_forwarder.visit_embedded_literals(new_address); + code_forwarder.visit_embedded_code_pointers(new_address); } }; @@ -113,6 +160,8 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p) data_forwarding_map->compute_forwarding(); code_forwarding_map->compute_forwarding(); + update_fixup_set_for_compaction(code_forwarding_map); + slot_visitor > slot_forwarder(this,forwarder(data_forwarding_map)); code_block_visitor > code_forwarder(this,forwarder(code_forwarding_map)); @@ -127,7 +176,7 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p) /* Slide everything in the code heap up, and update data and code heap pointers inside code blocks. */ - code_block_compaction_updater > > code_block_updater(this,slot_forwarder); + code_block_compaction_updater >, code_block_visitor > > code_block_updater(this,slot_forwarder,code_forwarder); standard_sizer code_block_sizer; code->allocator->compact(code_block_updater,code_block_sizer); @@ -145,27 +194,38 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p) } struct object_code_block_updater { - code_block_visitor > *visitor; + code_block_visitor > code_forwarder; - explicit object_code_block_updater(code_block_visitor > *visitor_) : - visitor(visitor_) {} + explicit object_code_block_updater(code_block_visitor > code_forwarder_) : + code_forwarder(code_forwarder_) {} void operator()(object *obj) { - visitor->visit_object_code_block(obj); + code_forwarder.visit_object_code_block(obj); } }; -struct dummy_slot_forwarder { - void visit_referenced_literals(code_block *compiled) {} +struct code_block_grow_heap_updater { + factor_vm *parent; + + explicit code_block_grow_heap_updater(factor_vm *parent_) : parent(parent_) {} + + void operator()(code_block *old_address, code_block *new_address, cell size) + { + memmove(new_address,old_address,size); + parent->relocate_code_block(new_address); + } }; -/* Compact just the code heap */ +/* Compact just the code heap, after growing the data heap */ void factor_vm::collect_compact_code_impl(bool trace_contexts_p) { /* Figure out where blocks are going to go */ mark_bits *code_forwarding_map = &code->allocator->state; code_forwarding_map->compute_forwarding(); + + update_fixup_set_for_compaction(code_forwarding_map); + code_block_visitor > code_forwarder(this,forwarder(code_forwarding_map)); if(trace_contexts_p) @@ -175,13 +235,12 @@ void factor_vm::collect_compact_code_impl(bool trace_contexts_p) } /* Update code heap references in data heap */ - object_code_block_updater updater(&code_forwarder); + object_code_block_updater updater(code_forwarder); each_object(updater); /* Slide everything in the code heap up, and update code heap pointers inside code blocks. */ - dummy_slot_forwarder slot_forwarder; - code_block_compaction_updater code_block_updater(this,slot_forwarder); + code_block_grow_heap_updater code_block_updater(this); standard_sizer code_block_sizer; code->allocator->compact(code_block_updater,code_block_sizer); diff --git a/vm/full_collector.cpp b/vm/full_collector.cpp index 22fb21e242..d2f2cd2cf2 100644 --- a/vm/full_collector.cpp +++ b/vm/full_collector.cpp @@ -17,8 +17,9 @@ full_collector::full_collector(factor_vm *parent_) : void full_collector::trace_code_block(code_block *compiled) { - data_visitor.visit_referenced_literals(compiled); - code_visitor.visit_referenced_code_blocks(compiled); + data_visitor.visit_code_block_objects(compiled); + data_visitor.visit_embedded_literals(compiled); + code_visitor.visit_embedded_code_pointers(compiled); } void full_collector::trace_context_code_blocks() diff --git a/vm/instruction_operands.cpp b/vm/instruction_operands.cpp index cc46140023..1ee10ea06a 100644 --- a/vm/instruction_operands.cpp +++ b/vm/instruction_operands.cpp @@ -20,7 +20,7 @@ fixnum instruction_operand::load_value_masked(cell mask, fixnum shift) return (*ptr & mask) << shift; } -fixnum instruction_operand::load_value() +fixnum instruction_operand::load_value(cell relative_to) { switch(rel_class) { @@ -29,27 +29,32 @@ fixnum instruction_operand::load_value() case RC_ABSOLUTE: return *(u32*)pointer; case RC_RELATIVE: - return *(s32*)pointer + pointer + sizeof(u32); + return *(s32*)pointer + relative_to + sizeof(u32); case RC_ABSOLUTE_PPC_2_2: return load_value_2_2(); case RC_ABSOLUTE_PPC_2: return load_value_masked(rel_absolute_ppc_2_mask,0); case RC_RELATIVE_PPC_2: - return load_value_masked(rel_relative_ppc_2_mask,0) + pointer; + return load_value_masked(rel_relative_ppc_2_mask,0) + relative_to; case RC_RELATIVE_PPC_3: - return load_value_masked(rel_relative_ppc_3_mask,0) + pointer; + return load_value_masked(rel_relative_ppc_3_mask,0) + relative_to; case RC_RELATIVE_ARM_3: - return load_value_masked(rel_relative_arm_3_mask,2) + pointer + sizeof(cell) * 2; + return load_value_masked(rel_relative_arm_3_mask,2) + relative_to + sizeof(cell) * 2; case RC_INDIRECT_ARM: - return load_value_masked(rel_indirect_arm_mask,0) + pointer + sizeof(cell); + return load_value_masked(rel_indirect_arm_mask,0) + relative_to + sizeof(cell); case RC_INDIRECT_ARM_PC: - return load_value_masked(rel_indirect_arm_mask,0) + pointer + sizeof(cell) * 2; + return load_value_masked(rel_indirect_arm_mask,0) + relative_to + sizeof(cell) * 2; default: critical_error("Bad rel class",rel_class); return 0; } } +fixnum instruction_operand::load_value() +{ + return load_value(pointer); +} + /* Store a 32-bit value into a PowerPC LIS/ORI sequence */ void instruction_operand::store_value_2_2(fixnum value) { diff --git a/vm/instruction_operands.hpp b/vm/instruction_operands.hpp index 554c870f58..fc6b9c74bd 100644 --- a/vm/instruction_operands.hpp +++ b/vm/instruction_operands.hpp @@ -128,6 +128,7 @@ struct instruction_operand { fixnum load_value_2_2(); fixnum load_value_masked(cell mask, fixnum shift); + fixnum load_value(cell relative_to); fixnum load_value(); void store_value_2_2(fixnum value); diff --git a/vm/slot_visitor.hpp b/vm/slot_visitor.hpp index 9a403043d1..265f2d8663 100644 --- a/vm/slot_visitor.hpp +++ b/vm/slot_visitor.hpp @@ -17,7 +17,8 @@ template struct slot_visitor { void visit_bignum_roots(); void visit_roots(); void visit_contexts(); - void visit_referenced_literals(code_block *compiled); + void visit_code_block_objects(code_block *compiled); + void visit_embedded_literals(code_block *compiled); }; template @@ -133,21 +134,25 @@ struct literal_references_visitor { { if(rel.rel_type() == RT_IMMEDIATE) { - instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)(compiled + 1)); - cell literal = op.load_address(); + instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt()); + cell literal = op.load_value(); literal = visitor->visit_pointer(literal); - op.store_address(literal); + op.store_value(literal); } } }; template -void slot_visitor::visit_referenced_literals(code_block *compiled) +void slot_visitor::visit_code_block_objects(code_block *compiled) { visit_handle(&compiled->owner); visit_handle(&compiled->literals); visit_handle(&compiled->relocation); +} +template +void slot_visitor::visit_embedded_literals(code_block *compiled) +{ if(!parent->code->needs_fixup_p(compiled)) { literal_references_visitor visitor(this); diff --git a/vm/vm.hpp b/vm/vm.hpp index e63202f09e..d8745fbc3e 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -288,6 +288,7 @@ struct factor_vm void collect_mark_impl(bool trace_contexts_p); void collect_sweep_impl(); void collect_full(bool trace_contexts_p); + void update_fixup_set_for_compaction(mark_bits *forwarding_map); void collect_compact_impl(bool trace_contexts_p); void collect_compact_code_impl(bool trace_contexts_p); void collect_compact(bool trace_contexts_p);