]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: growing heap no longer uses relocate_code_block()
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 29 Nov 2009 01:48:26 +0000 (19:48 -0600)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 29 Nov 2009 01:48:26 +0000 (19:48 -0600)
vm/code_block_visitor.hpp
vm/code_blocks.cpp
vm/compaction.cpp
vm/image.cpp
vm/vm.hpp

index 5d4e3f77d9a002267c3604e6cd5df68f77291f22..dbc3018491a1351dcb49dbab6d0c09831bca0c0b 100644 (file)
@@ -8,12 +8,19 @@ template<typename Visitor> struct code_block_visitor {
        explicit code_block_visitor(factor_vm *parent_, Visitor visitor_) :
                parent(parent_), visitor(visitor_) {}
 
+       code_block *visit_code_block(code_block *compiled);
        void visit_object_code_block(object *obj);
        void visit_embedded_code_pointers(code_block *compiled);
        void visit_context_code_blocks();
        void visit_callback_code_blocks();
 };
 
+template<typename Visitor>
+code_block *code_block_visitor<Visitor>::visit_code_block(code_block *compiled)
+{
+       return visitor(compiled);
+}
+
 template<typename Visitor>
 struct call_frame_code_block_visitor {
        factor_vm *parent;
index d734f430aab10610e77648b78ff9be7f584f0615..8ede7af6541ad1c8bbda89061d8e009d2665ea83 100755 (executable)
@@ -145,10 +145,10 @@ cell factor_vm::code_block_owner(code_block *compiled)
        }
 }
 
-struct word_references_updater {
+struct update_word_references_relocation_visitor {
        factor_vm *parent;
 
-       word_references_updater(factor_vm *parent_) : parent(parent_) {}
+       explicit update_word_references_relocation_visitor(factor_vm *parent_) : parent(parent_) {}
 
        void operator()(relocation_entry rel, cell index, code_block *compiled)
        {
@@ -200,57 +200,12 @@ void factor_vm::update_word_references(code_block *compiled)
                code->code_heap_free(compiled);
        else
        {
-               word_references_updater updater(this);
-               iterate_relocations(compiled,updater);
+               update_word_references_relocation_visitor visitor(this);
+               iterate_relocations(compiled,visitor);
                compiled->flush_icache();
        }
 }
 
-cell factor_vm::compute_relocation(relocation_entry rel, cell index, code_block *compiled)
-{
-       array *literals = (to_boolean(compiled->literals)
-               ? untag<array>(compiled->literals) : NULL);
-
-#define ARG array_nth(literals,index)
-
-       switch(rel.rel_type())
-       {
-       case RT_PRIMITIVE:
-               return compute_primitive_relocation(ARG);
-       case RT_DLSYM:
-               return compute_dlsym_relocation(literals,index);
-       case RT_IMMEDIATE:
-               return ARG;
-       case RT_XT:
-               return compute_xt_relocation(ARG);
-       case RT_XT_PIC:
-               return compute_xt_pic_relocation(ARG);
-       case RT_XT_PIC_TAIL:
-               return compute_xt_pic_tail_relocation(ARG);
-       case RT_HERE:
-               return compute_here_relocation(ARG,rel.rel_offset(),compiled);
-       case RT_THIS:
-               return (cell)compiled->xt();
-       case RT_CONTEXT:
-               return compute_context_relocation();
-       case RT_UNTAGGED:
-               return untag_fixnum(ARG);
-       case RT_MEGAMORPHIC_CACHE_HITS:
-               return (cell)&dispatch_stats.megamorphic_cache_hits;
-       case RT_VM:
-               return compute_vm_relocation(ARG);
-       case RT_CARDS_OFFSET:
-               return cards_offset;
-       case RT_DECKS_OFFSET:
-               return decks_offset;
-       default:
-               critical_error("Bad rel type",rel.rel_type());
-               return 0; /* Can't happen */
-       }
-
-#undef ARG
-}
-
 void factor_vm::check_code_address(cell address)
 {
 #ifdef FACTOR_DEBUG
@@ -258,15 +213,65 @@ void factor_vm::check_code_address(cell address)
 #endif
 }
 
-struct code_block_relocator {
+struct relocate_code_block_relocation_visitor {
        factor_vm *parent;
 
-       explicit code_block_relocator(factor_vm *parent_) : parent(parent_) {}
+       explicit relocate_code_block_relocation_visitor(factor_vm *parent_) : parent(parent_) {}
 
        void operator()(relocation_entry rel, cell index, code_block *compiled)
        {
                instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt());
-               op.store_value(parent->compute_relocation(rel,index,compiled));
+               array *literals = (parent->to_boolean(compiled->literals)
+                       ? untag<array>(compiled->literals) : NULL);
+
+               switch(rel.rel_type())
+               {
+               case RT_PRIMITIVE:
+                       op.store_value(parent->compute_primitive_relocation(array_nth(literals,index)));
+                       break;
+               case RT_DLSYM:
+                       op.store_value(parent->compute_dlsym_relocation(literals,index));
+                       break;
+               case RT_IMMEDIATE:
+                       op.store_value(array_nth(literals,index));
+                       break;
+               case RT_XT:
+                       op.store_value(parent->compute_xt_relocation(array_nth(literals,index)));
+                       break;
+               case RT_XT_PIC:
+                       op.store_value(parent->compute_xt_pic_relocation(array_nth(literals,index)));
+                       break;
+               case RT_XT_PIC_TAIL:
+                       op.store_value(parent->compute_xt_pic_tail_relocation(array_nth(literals,index)));
+                       break;
+               case RT_HERE:
+                       op.store_value(parent->compute_here_relocation(array_nth(literals,index),rel.rel_offset(),compiled));
+                       break;
+               case RT_THIS:
+                       op.store_value((cell)compiled->xt());
+                       break;
+               case RT_CONTEXT:
+                       op.store_value(parent->compute_context_relocation());
+                       break;
+               case RT_UNTAGGED:
+                       op.store_value(untag_fixnum(array_nth(literals,index)));
+                       break;
+               case RT_MEGAMORPHIC_CACHE_HITS:
+                       op.store_value((cell)&parent->dispatch_stats.megamorphic_cache_hits);
+                       break;
+               case RT_VM:
+                       op.store_value(parent->compute_vm_relocation(array_nth(literals,index)));
+                       break;
+               case RT_CARDS_OFFSET:
+                       op.store_value(parent->cards_offset);
+                       break;
+               case RT_DECKS_OFFSET:
+                       op.store_value(parent->decks_offset);
+                       break;
+               default:
+                       critical_error("Bad rel type",rel.rel_type());
+                       break;
+               }
        }
 };
 
@@ -274,8 +279,8 @@ struct code_block_relocator {
 void factor_vm::relocate_code_block(code_block *compiled)
 {
        code->needs_fixup.erase(compiled);
-       code_block_relocator relocator(this);
-       iterate_relocations(compiled,relocator);
+       relocate_code_block_relocation_visitor visitor(this);
+       iterate_relocations(compiled,visitor);
        compiled->flush_icache();
 }
 
index 4b6b9d4eacaeb0dc5b670f5a8dcb998b7a819df4..52814b8351ecaf0b798f6bfae72dbab0da34c5ef 100644 (file)
@@ -9,10 +9,7 @@ void factor_vm::update_fixup_set_for_compaction(mark_bits<code_block> *forwardin
 
        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;
 }
@@ -69,18 +66,15 @@ struct compaction_sizer {
 
 struct object_compaction_updater {
        factor_vm *parent;
-       slot_visitor<forwarder<object> > slot_forwarder;
-       code_block_visitor<forwarder<code_block> > code_forwarder;
+       mark_bits<code_block> *code_forwarding_map;
        mark_bits<object> *data_forwarding_map;
        object_start_map *starts;
 
        explicit object_compaction_updater(factor_vm *parent_,
-               slot_visitor<forwarder<object> > slot_forwarder_,
-               code_block_visitor<forwarder<code_block> > code_forwarder_,
-               mark_bits<object> *data_forwarding_map_) :
+               mark_bits<object> *data_forwarding_map_,
+               mark_bits<code_block> *code_forwarding_map_) :
                parent(parent_),
-               slot_forwarder(slot_forwarder_),
-               code_forwarder(code_forwarder_),
+               code_forwarding_map(code_forwarding_map_),
                data_forwarding_map(data_forwarding_map_),
                starts(&parent->data->tenured->starts) {}
 
@@ -94,44 +88,83 @@ struct object_compaction_updater {
 
                memmove(new_address,old_address,size);
 
+               slot_visitor<forwarder<object> > slot_forwarder(parent,forwarder<object>(data_forwarding_map));
                slot_forwarder.visit_slots(new_address,payload_start);
+
+               code_block_visitor<forwarder<code_block> > code_forwarder(parent,forwarder<code_block>(code_forwarding_map));
                code_forwarder.visit_object_code_block(new_address);
+
                starts->record_object_start_offset(new_address);
        }
 };
 
-struct relative_address_updater {
+template<typename SlotForwarder>
+struct code_block_compaction_relocation_visitor {
        factor_vm *parent;
        code_block *old_address;
+       slot_visitor<SlotForwarder> slot_forwarder;
+       code_block_visitor<forwarder<code_block> > code_forwarder;
 
-       explicit relative_address_updater(factor_vm *parent_, code_block *old_address_) :
-               parent(parent_), old_address(old_address_) {}
+       explicit code_block_compaction_relocation_visitor(factor_vm *parent_,
+               code_block *old_address_,
+               slot_visitor<SlotForwarder> slot_forwarder_,
+               code_block_visitor<forwarder<code_block> > code_forwarder_) :
+               parent(parent_),
+               old_address(old_address_),
+               slot_forwarder(slot_forwarder_),
+               code_forwarder(code_forwarder_) {}
 
        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());
+               instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt());
 
-               op.store_value(value);
+               array *literals = (parent->to_boolean(compiled->literals)
+                       ? untag<array>(compiled->literals) : NULL);
+
+               cell old_offset = rel.rel_offset() + (cell)old_address->xt();
+
+               switch(type)
+               {
+               case RT_IMMEDIATE:
+                       op.store_value(slot_forwarder.visit_pointer(op.load_value(old_offset)));
+                       break;
+               case RT_XT:
+               case RT_XT_PIC:
+               case RT_XT_PIC_TAIL:
+                       op.store_code_block(code_forwarder.visit_code_block(op.load_code_block(old_offset)));
+                       break;
+               case RT_HERE:
+                       op.store_value(parent->compute_here_relocation(array_nth(literals,index),rel.rel_offset(),compiled));
+                       break;
+               case RT_THIS:
+                       op.store_value((cell)compiled->xt());
+                       break;
+               case RT_CARDS_OFFSET:
+                       op.store_value(parent->cards_offset);
+                       break;
+               case RT_DECKS_OFFSET:
+                       op.store_value(parent->decks_offset);
+                       break;
+               default:
+                       op.store_value(op.load_value(old_offset));
+                       break;
+               }
        }
 };
 
-template<typename SlotForwarder, typename CodeBlockForwarder>
+template<typename SlotForwarder>
 struct code_block_compaction_updater {
        factor_vm *parent;
-       slot_visitor<forwarder<object> > slot_forwarder;
+       slot_visitor<SlotForwarder> slot_forwarder;
        code_block_visitor<forwarder<code_block> > code_forwarder;
 
        explicit code_block_compaction_updater(factor_vm *parent_,
-               slot_visitor<forwarder<object> > slot_forwarder_,
+               slot_visitor<SlotForwarder> slot_forwarder_,
                code_block_visitor<forwarder<code_block> > code_forwarder_) :
-               parent(parent_), slot_forwarder(slot_forwarder_), code_forwarder(code_forwarder_) {}
+               parent(parent_),
+               slot_forwarder(slot_forwarder_),
+               code_forwarder(code_forwarder_) {}
 
        void operator()(code_block *old_address, code_block *new_address, cell size)
        {
@@ -139,11 +172,8 @@ struct code_block_compaction_updater {
 
                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);
+               code_block_compaction_relocation_visitor<SlotForwarder> visitor(parent,old_address,slot_forwarder,code_forwarder);
+               parent->iterate_relocations(new_address,visitor);
        }
 };
 
@@ -170,13 +200,13 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p)
 
        /* 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);
+       object_compaction_updater object_updater(this,data_forwarding_map,code_forwarding_map);
        compaction_sizer object_sizer(data_forwarding_map);
        tenured->compact(object_updater,object_sizer);
 
        /* 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_visitor<forwarder<code_block> > > code_block_updater(this,slot_forwarder,code_forwarder);
+       code_block_compaction_updater<forwarder<object> > code_block_updater(this,slot_forwarder,code_forwarder);
        standard_sizer<code_block> code_block_sizer;
        code->allocator->compact(code_block_updater,code_block_sizer);
 
@@ -193,10 +223,10 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p)
        current_gc->event->ended_compaction();
 }
 
-struct object_code_block_updater {
+struct object_grow_heap_updater {
        code_block_visitor<forwarder<code_block> > code_forwarder;
 
-       explicit object_code_block_updater(code_block_visitor<forwarder<code_block> > code_forwarder_) :
+       explicit object_grow_heap_updater(code_block_visitor<forwarder<code_block> > code_forwarder_) :
                code_forwarder(code_forwarder_) {}
 
        void operator()(object *obj)
@@ -205,16 +235,8 @@ struct object_code_block_updater {
        }
 };
 
-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);
-       }
+struct dummy_slot_forwarder {
+       object *operator()(object *obj) { return obj; }
 };
 
 /* Compact just the code heap, after growing the data heap */
@@ -226,6 +248,7 @@ void factor_vm::collect_compact_code_impl(bool trace_contexts_p)
 
        update_fixup_set_for_compaction(code_forwarding_map);
 
+       slot_visitor<dummy_slot_forwarder> slot_forwarder(this,dummy_slot_forwarder());
        code_block_visitor<forwarder<code_block> > code_forwarder(this,forwarder<code_block>(code_forwarding_map));
 
        if(trace_contexts_p)
@@ -235,12 +258,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_grow_heap_updater updater(code_forwarder);
        each_object(updater);
 
        /* Slide everything in the code heap up, and update code heap
        pointers inside code blocks. */
-       code_block_grow_heap_updater code_block_updater(this);
+       code_block_compaction_updater<dummy_slot_forwarder> code_block_updater(this,slot_forwarder,code_forwarder);
        standard_sizer<code_block> code_block_sizer;
        code->allocator->compact(code_block_updater,code_block_sizer);
 
index 369bae3e63c2b2396dffd39b4fbd23b5efb2b9ca..e31d50a46332be713948a360583bc15c8b64e9eb 100755 (executable)
@@ -163,13 +163,13 @@ void factor_vm::fixup_data(cell data_offset, cell code_offset)
        data->tenured->iterate(fixupper,sizer);
 }
 
-struct code_block_updater {
+struct code_block_fixup_relocation_visitor {
        factor_vm *parent;
        cell code_offset;
        slot_visitor<data_fixupper> data_visitor;
        code_fixupper code_visitor;
 
-       code_block_updater(factor_vm *parent_, cell data_offset_, cell code_offset_) :
+       code_block_fixup_relocation_visitor(factor_vm *parent_, cell data_offset_, cell code_offset_) :
                parent(parent_),
                code_offset(code_offset_),
                data_visitor(slot_visitor<data_fixupper>(parent_,data_fixupper(data_offset_))),
@@ -247,8 +247,8 @@ struct code_block_fixupper {
                slot_visitor<data_fixupper> data_visitor(parent,data_fixupper(data_offset));
                data_visitor.visit_code_block_objects(compiled);
 
-               code_block_updater updater(parent,data_offset,code_offset);
-               parent->iterate_relocations(compiled,updater);
+               code_block_fixup_relocation_visitor code_visitor(parent,data_offset,code_offset);
+               parent->iterate_relocations(compiled,code_visitor);
        }
 };
 
index 01363f443bd25fc459b9033b616e842c18d3c7e5..0f25412609bf0d33c2be39204800cbfe1264253e 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -531,7 +531,6 @@ struct factor_vm
        }
 
        void update_word_references(code_block *compiled);
-       cell compute_relocation(relocation_entry rel, cell index, code_block *compiled);
        void check_code_address(cell address);
        void relocate_code_block(code_block *compiled);
        void fixup_labels(array *labels, code_block *compiled);