]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: compaction now updates the needs_fixup set
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Wed, 25 Nov 2009 01:29:59 +0000 (19:29 -0600)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Wed, 25 Nov 2009 01:29:59 +0000 (19:29 -0600)
vm/code_block_visitor.hpp
vm/code_blocks.cpp
vm/code_heap.cpp
vm/collector.hpp
vm/compaction.cpp
vm/full_collector.cpp
vm/instruction_operands.cpp
vm/instruction_operands.hpp
vm/slot_visitor.hpp
vm/vm.hpp

index dbaa00e83a31c1c87a3d9d9cee0fc431219137ef..e9ed1d88effc782fab7f3d3c1ece1d1728ec7a54 100644 (file)
@@ -9,7 +9,7 @@ template<typename Visitor> 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<Visitor>::visit_object_code_block(object *obj)
 }
 
 template<typename Visitor>
-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<typename Visitor>
-void code_block_visitor<Visitor>::visit_referenced_code_blocks(code_block *compiled)
+void code_block_visitor<Visitor>::visit_embedded_code_pointers(code_block *compiled)
 {
        if(!parent->code->needs_fixup_p(compiled))
        {
-               referenced_code_blocks_visitor<Visitor> visitor(this->visitor);
+               embedded_code_pointers_visitor<Visitor> visitor(this->visitor);
                parent->iterate_relocations(compiled,visitor);
        }
 }
index ef066f1a13f43d83df323d5a3c00f70f3e90ec9d..9d6e9a4b2590cd0a1c11005b13eaadac71ab6d62 100755 (executable)
@@ -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());
        }
 }
 
index 920a6030573607a591d7d61b107d65650457adea..bad5a2fb67e8c63c3f1677ca387383bc7571bdd9 100755 (executable)
@@ -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<array> alist(dpop(),this);
index c59f826225466462377b02dcd9f0f603790b57fc..4dac6d28c358eff15b63037196ec0a546d00119b 100644 (file)
@@ -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<code_block *> *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++;
                }
        }
index 0c173a84f644931264d2305a72f5023a4d05a15b..4b6b9d4eacaeb0dc5b670f5a8dcb998b7a819df4 100644 (file)
@@ -2,6 +2,21 @@
 
 namespace factor {
 
+void factor_vm::update_fixup_set_for_compaction(mark_bits<code_block> *forwarding_map)
+{
+       std::set<code_block *>::const_iterator iter = code->needs_fixup.begin();
+       std::set<code_block *>::const_iterator end = code->needs_fixup.end();
+
+       std::set<code_block *> 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<typename Block> struct forwarder {
        mark_bits<Block> *forwarding_map;
 
@@ -85,18 +100,50 @@ struct object_compaction_updater {
        }
 };
 
-template<typename SlotForwarder> struct code_block_compaction_updater {
+struct relative_address_updater {
+       factor_vm *parent;
+       code_block *old_address;
+
+       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<typename SlotForwarder, typename CodeBlockForwarder>
+struct code_block_compaction_updater {
        factor_vm *parent;
-       SlotForwarder slot_forwarder;
+       slot_visitor<forwarder<object> > slot_forwarder;
+       code_block_visitor<forwarder<code_block> > code_forwarder;
 
-       explicit code_block_compaction_updater(factor_vm *parent_, SlotForwarder slot_forwarder_) :
-               parent(parent_), slot_forwarder(slot_forwarder_) {}
+       explicit code_block_compaction_updater(factor_vm *parent_,
+               slot_visitor<forwarder<object> > slot_forwarder_,
+               code_block_visitor<forwarder<code_block> > 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<forwarder<object> > slot_forwarder(this,forwarder<object>(data_forwarding_map));
        code_block_visitor<forwarder<code_block> > code_forwarder(this,forwarder<code_block>(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<slot_visitor<forwarder<object> > > code_block_updater(this,slot_forwarder);
+       code_block_compaction_updater<slot_visitor<forwarder<object> >, code_block_visitor<forwarder<code_block> > > code_block_updater(this,slot_forwarder,code_forwarder);
        standard_sizer<code_block> 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<forwarder<code_block> > *visitor;
+       code_block_visitor<forwarder<code_block> > code_forwarder;
 
-       explicit object_code_block_updater(code_block_visitor<forwarder<code_block> > *visitor_) :
-               visitor(visitor_) {}
+       explicit object_code_block_updater(code_block_visitor<forwarder<code_block> > 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_block> *code_forwarding_map = &code->allocator->state;
        code_forwarding_map->compute_forwarding();
+
+       update_fixup_set_for_compaction(code_forwarding_map);
+
        code_block_visitor<forwarder<code_block> > code_forwarder(this,forwarder<code_block>(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<dummy_slot_forwarder> code_block_updater(this,slot_forwarder);
+       code_block_grow_heap_updater code_block_updater(this);
        standard_sizer<code_block> code_block_sizer;
        code->allocator->compact(code_block_updater,code_block_sizer);
 
index 22fb21e2422a006e2669c76df441fe92206851fe..d2f2cd2cf24cbbe8f211aebe2942685735f12947 100644 (file)
@@ -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()
index cc46140023d50330fd97c0777c722ca1d863b728..1ee10ea06a7bfdea2a3d035ec62417753e0683f2 100644 (file)
@@ -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)
 {
index 554c870f58c66ea3005f95de33c10eaf6fdf06eb..fc6b9c74bd30b1cad72a26c0a89bf49d6cfeb899 100644 (file)
@@ -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);
index 9a403043d1d653e2cfba6bf46e47dbf15ea8eb54..265f2d8663121861284836982a80f99c74efb12a 100644 (file)
@@ -17,7 +17,8 @@ template<typename Visitor> 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<typename Visitor>
@@ -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<typename Visitor>
-void slot_visitor<Visitor>::visit_referenced_literals(code_block *compiled)
+void slot_visitor<Visitor>::visit_code_block_objects(code_block *compiled)
 {
        visit_handle(&compiled->owner);
        visit_handle(&compiled->literals);
        visit_handle(&compiled->relocation);
+}
 
+template<typename Visitor>
+void slot_visitor<Visitor>::visit_embedded_literals(code_block *compiled)
+{
        if(!parent->code->needs_fixup_p(compiled))
        {
                literal_references_visitor<Visitor> visitor(this);
index e63202f09e46f27cc4a5ec661f4f586677f33e57..d8745fbc3eacaebc5be831b515193da4012d86c5 100755 (executable)
--- 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<code_block> *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);