]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: more GC refactoring
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 6 Oct 2009 05:13:54 +0000 (00:13 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 6 Oct 2009 05:13:54 +0000 (00:13 -0500)
vm/data_gc.cpp
vm/data_gc.hpp
vm/inline_cache.cpp
vm/vm.cpp
vm/vm.hpp

index dad6b9c9eb057cde0521bc1d06bf7a750d9babb0..35a5ba07def882f8bedb2d82fa02475d6e2f23e3 100755 (executable)
@@ -17,68 +17,6 @@ gc_state::gc_state(data_heap *data_, bool growing_data_heap_, cell collecting_ge
 
 gc_state::~gc_state() { }
 
-/* Given a pointer to oldspace, copy it to newspace */
-object *factor_vm::copy_untagged_object_impl(object *pointer, cell size)
-{
-       if(current_gc->newspace->here + size >= current_gc->newspace->end)
-               longjmp(current_gc->gc_unwind,1);
-
-       object *newpointer = allot_zone(current_gc->newspace,size);
-
-       gc_stats *s = &stats[current_gc->collecting_gen];
-       s->object_count++;
-       s->bytes_copied += size;
-
-       memcpy(newpointer,pointer,size);
-       return newpointer;
-}
-
-object *factor_vm::copy_object_impl(object *untagged)
-{
-       object *newpointer = copy_untagged_object_impl(untagged,untagged_object_size(untagged));
-       untagged->h.forward_to(newpointer);
-       return newpointer;
-}
-
-/* Follow a chain of forwarding pointers */
-template<typename Strategy> object *factor_vm::resolve_forwarding(object *untagged, Strategy &strategy)
-{
-       check_data_pointer(untagged);
-
-       /* is there another forwarding pointer? */
-       if(untagged->h.forwarding_pointer_p())
-               return resolve_forwarding(untagged->h.forwarding_pointer(),strategy);
-       /* we've found the destination */
-       else
-       {
-               untagged->h.check_header();
-               if(strategy.should_copy_p(untagged))
-                       return copy_object_impl(untagged);
-               else
-                       return untagged;
-       }
-}
-
-template<typename Type, typename Strategy> Type *factor_vm::copy_untagged_object(Type *untagged, Strategy &strategy)
-{
-       check_data_pointer(untagged);
-
-       if(untagged->h.forwarding_pointer_p())
-               untagged = (Type *)resolve_forwarding(untagged->h.forwarding_pointer(),strategy);
-       else
-       {
-               untagged->h.check_header();
-               untagged = (Type *)copy_object_impl(untagged);
-       }
-
-       return untagged;
-}
-
-template<typename Strategy> cell factor_vm::copy_object(cell pointer, Strategy &strategy)
-{
-       return RETAG(copy_untagged_object(untag<object>(pointer),strategy),TAG(pointer));
-}
-
 template<typename Strategy> void factor_vm::trace_handle(cell *handle, Strategy &strategy)
 {
        cell pointer = *handle;
@@ -88,7 +26,7 @@ template<typename Strategy> void factor_vm::trace_handle(cell *handle, Strategy
                object *obj = untag<object>(pointer);
                check_data_pointer(obj);
                if(strategy.should_copy_p(obj))
-                       *handle = copy_object(pointer,strategy);
+                       *handle = strategy.copy_object(pointer);
        }
 }
 
@@ -247,7 +185,7 @@ template<typename Strategy> void factor_vm::trace_registered_bignums(Strategy &s
                {
                        check_data_pointer(pointer);
                        if(strategy.should_copy_p(pointer))
-                               *handle = copy_untagged_object(pointer,strategy);
+                               *handle = untag<bignum>(strategy.copy_object(tag<bignum>(pointer)));
 #ifdef FACTOR_DEBUG
                        assert((*handle)->h.hi_tag() == BIGNUM_TYPE);
 #endif
@@ -383,15 +321,18 @@ template<typename Strategy> struct literal_reference_tracer {
 aging and nursery collections */
 template<typename Strategy> void factor_vm::trace_code_heap_roots(Strategy &strategy)
 {
-       literal_reference_tracer<Strategy> tracer(this,strategy);
-       iterate_code_heap(tracer);
+       if(current_gc->collecting_gen >= last_code_heap_scan)
+       {
+               literal_reference_tracer<Strategy> tracer(this,strategy);
+               iterate_code_heap(tracer);
 
-       if(current_gc->collecting_accumulation_gen_p())
-               last_code_heap_scan = current_gc->collecting_gen;
-       else
-               last_code_heap_scan = current_gc->collecting_gen + 1;
-       
-       code_heap_scans++;
+               if(current_gc->collecting_accumulation_gen_p())
+                       last_code_heap_scan = current_gc->collecting_gen;
+               else
+                       last_code_heap_scan = current_gc->collecting_gen + 1;
+
+               code_heap_scans++;
+       }
 }
 
 /* Mark all literals referenced from a word XT. Only for tenured
@@ -406,37 +347,6 @@ template<typename Strategy> void factor_vm::mark_code_block(code_block *compiled
        trace_handle(&compiled->relocation,strategy);
 }
 
-template<typename Strategy> cell factor_vm::copy_next(cell scan, Strategy &strategy)
-{
-       cell *obj = (cell *)scan;
-       cell *end = (cell *)(scan + binary_payload_start((object *)scan));
-
-       if(obj != end)
-       {
-               obj++;
-
-               for(; obj < end; obj++)
-                       trace_handle(obj,strategy);
-       }
-
-       return scan + untagged_object_size((object *)scan);
-}
-
-template<typename Strategy> void factor_vm::update_code_heap_roots(Strategy &strategy)
-{
-       if(current_gc->collecting_gen >= last_code_heap_scan)
-       {
-               code_heap_scans++;
-
-               trace_code_heap_roots(strategy);
-
-               if(current_gc->collecting_accumulation_gen_p())
-                       last_code_heap_scan = current_gc->collecting_gen;
-               else
-                       last_code_heap_scan = current_gc->collecting_gen + 1;
-       }
-}
-
 struct literal_and_word_reference_updater {
        factor_vm *myvm;
 
@@ -502,12 +412,107 @@ void factor_vm::begin_gc(cell requested_bytes)
        }
 }
 
-struct nursery_collector
+template<typename Strategy>
+copying_collector<Strategy>::copying_collector(factor_vm *myvm_)
+: myvm(myvm_), current_gc(myvm_->current_gc)
 {
-       factor_vm *myvm;
+       scan = current_gc->newspace->here;
+}
+
+template<typename Strategy> Strategy &copying_collector<Strategy>::strategy()
+{
+       return static_cast<Strategy &>(*this);
+}
+
+/* Given a pointer to oldspace, copy it to newspace */
+template<typename Strategy> object *copying_collector<Strategy>::copy_untagged_object_impl(object *pointer, cell size)
+{
+       if(current_gc->newspace->here + size >= current_gc->newspace->end)
+               longjmp(current_gc->gc_unwind,1);
+
+       object *newpointer = myvm->allot_zone(current_gc->newspace,size);
+
+       gc_stats *s = &myvm->stats[current_gc->collecting_gen];
+       s->object_count++;
+       s->bytes_copied += size;
+
+       memcpy(newpointer,pointer,size);
+       return newpointer;
+}
+
+template<typename Strategy> object *copying_collector<Strategy>::copy_object_impl(object *untagged)
+{
+       object *newpointer = copy_untagged_object_impl(untagged,myvm->untagged_object_size(untagged));
+       untagged->h.forward_to(newpointer);
+       return newpointer;
+}
+
+/* Follow a chain of forwarding pointers */
+template<typename Strategy> object *copying_collector<Strategy>::resolve_forwarding(object *untagged)
+{
+       myvm->check_data_pointer(untagged);
+
+       /* is there another forwarding pointer? */
+       if(untagged->h.forwarding_pointer_p())
+               return resolve_forwarding(untagged->h.forwarding_pointer());
+       /* we've found the destination */
+       else
+       {
+               untagged->h.check_header();
+               if(should_copy_p(untagged))
+                       return copy_object_impl(untagged);
+               else
+                       return untagged;
+       }
+}
+
+template<typename Strategy> cell copying_collector<Strategy>::copy_object(cell pointer)
+{
+       object *untagged = myvm->untag<object>(pointer);
+
+       myvm->check_data_pointer(untagged);
+
+       if(untagged->h.forwarding_pointer_p())
+               untagged = resolve_forwarding(untagged->h.forwarding_pointer());
+       else
+       {
+               untagged->h.check_header();
+               untagged = copy_object_impl(untagged);
+       }
+
+       return RETAG(untagged,TAG(pointer));
+}
+
+template<typename Strategy> bool copying_collector<Strategy>::should_copy_p(object *pointer)
+{
+       return strategy().should_copy_p(pointer);
+}
+
+template<typename Strategy> cell copying_collector<Strategy>::copy_next(cell scan)
+{
+       cell *obj = (cell *)scan;
+       cell *end = (cell *)(scan + myvm->binary_payload_start((object *)scan));
+
+       if(obj != end)
+       {
+               obj++;
+
+               for(; obj < end; obj++)
+                       myvm->trace_handle(obj,strategy());
+       }
+
+       return scan + myvm->untagged_object_size((object *)scan);
+}
+
+template<typename Strategy> void copying_collector<Strategy>::go()
+{
+       strategy().copy_reachable_objects(scan,&current_gc->newspace->here);
+}
+
+struct nursery_collector : copying_collector<nursery_collector>
+{
+       explicit nursery_collector(factor_vm *myvm_) : copying_collector<nursery_collector>(myvm_) {}
 
-       explicit nursery_collector(factor_vm *myvm_) : myvm(myvm_) {}
-       
        bool should_copy_p(object *untagged)
        {
                if(myvm->current_gc->newspace->contains_p(untagged))
@@ -515,11 +520,10 @@ struct nursery_collector
                else
                        return myvm->nursery.contains_p(untagged);
        }
-       
+
        void copy_reachable_objects(cell scan, cell *end)
        {
-               while(scan < myvm->current_gc->newspace->here)
-                       scan = myvm->copy_next(scan,*this);
+               while(scan < *end) scan = copy_next(scan);
        }
 };
 
@@ -527,26 +531,18 @@ void factor_vm::collect_nursery()
 {
        nursery_collector collector(this);
 
-        cell scan = current_gc->newspace->here;
-
         trace_roots(collector);
         trace_contexts(collector);
         trace_cards(collector);
-
-        if(current_gc->collecting_gen >= last_code_heap_scan)
-                update_code_heap_roots(collector);
-
-        collector.copy_reachable_objects(scan,&current_gc->newspace->here);
-
+       trace_code_heap_roots(collector);
+        collector.go();
         update_dirty_code_blocks();
 }
 
-struct aging_collector
+struct aging_collector : copying_collector<aging_collector>
 {
-       factor_vm *myvm;
+       explicit aging_collector(factor_vm *myvm_) : copying_collector<aging_collector>(myvm_) {}
 
-       explicit aging_collector(factor_vm *myvm_) : myvm(myvm_) {}
-       
        bool should_copy_p(object *untagged)
        {
                if(myvm->current_gc->newspace->contains_p(untagged))
@@ -557,8 +553,7 @@ struct aging_collector
        
        void copy_reachable_objects(cell scan, cell *end)
        {
-               while(scan < myvm->current_gc->newspace->here)
-                       scan = myvm->copy_next(scan,*this);
+               while(scan < *end) scan = copy_next(scan);
        }
 };
 
@@ -566,25 +561,17 @@ void factor_vm::collect_aging()
 {
        aging_collector collector(this);
 
-        cell scan = current_gc->newspace->here;
-
         trace_roots(collector);
         trace_contexts(collector);
         trace_cards(collector);
-
-        if(current_gc->collecting_gen >= last_code_heap_scan)
-                update_code_heap_roots(collector);
-
-        collector.copy_reachable_objects(scan,&current_gc->newspace->here);
-
+       trace_code_heap_roots(collector);
+        collector.go();
         update_dirty_code_blocks();
 }
 
-struct tenured_collector
+struct tenured_collector : copying_collector<tenured_collector>
 {
-       factor_vm *myvm;
-
-       explicit tenured_collector(factor_vm *myvm_) : myvm(myvm_) {}
+       explicit tenured_collector(factor_vm *myvm_) : copying_collector<tenured_collector>(myvm_) {}
        
        bool should_copy_p(object *untagged)
        {
@@ -593,10 +580,10 @@ struct tenured_collector
        
        void copy_reachable_objects(cell scan, cell *end)
        {
-               while(scan < myvm->current_gc->newspace->here)
+               while(scan < *end)
                {
                        myvm->mark_object_code_block(myvm->untag<object>(scan),*this);
-                       scan = myvm->copy_next(scan,*this);
+                       scan = copy_next(scan);
                }
        }
 };
@@ -605,14 +592,9 @@ void factor_vm::collect_tenured(bool trace_contexts_)
 {
        tenured_collector collector(this);
 
-        cell scan = current_gc->newspace->here;
-
         trace_roots(collector);
-        if(trace_contexts_)
-               trace_contexts(collector);
-
-        collector.copy_reachable_objects(scan,&current_gc->newspace->here);
-
+        if(trace_contexts_) trace_contexts(collector);
+        collector.go();
         free_unmarked_code_blocks();
 }
 
index 14825c054f784164a22354bd065b575e0fc78921..95c72498230f6f0ce55e959ac0a092496c647c2e 100755 (executable)
@@ -63,6 +63,22 @@ struct gc_state {
        }
 };
 
+template<typename Strategy> struct copying_collector {
+       factor_vm *myvm;
+       gc_state *current_gc;
+       cell scan;
+
+       explicit copying_collector(factor_vm *myvm_);
+       Strategy &strategy();
+       object *copy_untagged_object_impl(object *pointer, cell size);
+       cell copy_next(cell scan);
+       object *copy_object_impl(object *untagged);
+       object *resolve_forwarding(object *untagged);
+       cell copy_object(cell pointer);
+       bool should_copy_p(object *pointer);
+       void go();
+};
+
 VM_C_API void inline_gc(cell *gc_roots_base, cell gc_roots_size, factor_vm *myvm);
 
 }
index e278c0d461239abf140b6dd397750d7cd45c6bd8..1626af1965a2a154ccdd819d2794f95925624e34 100755 (executable)
@@ -6,6 +6,10 @@ namespace factor
 void factor_vm::init_inline_caching(int max_size)
 {
        max_pic_size = max_size;
+       cold_call_to_ic_transitions = 0;
+       ic_to_pic_transitions = 0;
+       pic_to_mega_transitions = 0;
+       for(int i = 0; i < 4; i++) pic_counts[i] = 0;
 }
 
 void factor_vm::deallocate_inline_cache(cell return_address)
index 45cf05075ce58aa891ae802e54b3822587075a07..15df6cc18a656413c559bec666640c7a5e130a54 100755 (executable)
--- a/vm/vm.cpp
+++ b/vm/vm.cpp
@@ -3,6 +3,13 @@
 namespace factor\r
 {\r
 \r
-factor_vm::factor_vm() { }\r
+factor_vm::factor_vm() :\r
+       profiling_p(false),\r
+       secure_gc(false),\r
+       gc_off(false),\r
+       current_gc(NULL),\r
+       fep_disabled(false),\r
+       full_output(false)\r
+       { }\r
 \r
 }\r
index c7176dd6ed0beeb0f935c32c0fe61b7fec51fe55..ad0931112ef52cfcd07f2db93297c3a2d47b0c4e 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -243,13 +243,6 @@ struct factor_vm
        cell last_code_heap_scan;
 
        void init_data_gc();
-       object *copy_untagged_object_impl(object *pointer, cell size);
-       object *copy_object_impl(object *untagged);
-       object *resolve_forwarding(object *untagged);
-       template<typename Type> Type *copy_untagged_object(Type *untagged);
-       template<typename Strategy> object *resolve_forwarding(object *untagged, Strategy &strategy);
-       template<typename Type, typename Strategy> Type *copy_untagged_object(Type *untagged, Strategy &strategy);
-       template<typename Strategy> cell copy_object(cell pointer, Strategy &strategy);
        template<typename Strategy> void trace_handle(cell *handle, Strategy &strategy);
        template<typename Strategy> void trace_card(card *ptr, cell gen, cell here, Strategy &strategy);
        template<typename Strategy> void trace_card_deck(card_deck *deck, cell gen, card mask, card unmask, Strategy &strategy);
@@ -265,8 +258,6 @@ struct factor_vm
        template<typename Strategy> void trace_code_heap_roots(Strategy &strategy);
        template<typename Strategy> void mark_code_block(code_block *compiled, Strategy &strategy);
        template<typename Strategy> void mark_object_code_block(object *object, Strategy &strategy);
-       template<typename Strategy> cell copy_next(cell scan, Strategy &strategy);
-       template<typename Strategy> void update_code_heap_roots(Strategy &strategy);
        void free_unmarked_code_blocks();
        void update_dirty_code_blocks();
        void begin_gc(cell requested_bytes);