]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: don't flush instruction cache twice per code block on a major GC on PowerPC
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Fri, 16 Oct 2009 03:31:41 +0000 (22:31 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Fri, 16 Oct 2009 03:31:41 +0000 (22:31 -0500)
vm/aging_collector.cpp
vm/code_block.cpp
vm/full_collector.cpp
vm/gc.cpp
vm/nursery_collector.cpp
vm/to_tenured_collector.cpp
vm/vm.hpp

index 9a856374f6c1232bd63dc2847354a27a4ce34f53..74372736492c53dddc6953d447b2175d6e81229c 100644 (file)
@@ -38,7 +38,7 @@ void factor_vm::collect_aging()
                collector.trace_contexts();
                collector.trace_code_heap_roots(&code->points_to_aging);
                collector.cheneys_algorithm();
-               update_dirty_code_blocks(&code->points_to_aging);
+               update_code_heap_for_minor_gc(&code->points_to_aging);
 
                nursery.here = nursery.start;
                code->points_to_nursery.clear();
index 7214aa235e38d1d72646a76040ad489f951b0042..bb05fe89335d823ad45891af7b8bc9baf2938de6 100755 (executable)
@@ -356,6 +356,41 @@ void factor_vm::update_word_references(code_block *compiled)
        }
 }
 
+/* This runs after a full collection */
+struct literal_and_word_references_updater {
+       factor_vm *myvm;
+
+       explicit literal_and_word_references_updater(factor_vm *myvm_) : myvm(myvm_) {}
+
+       void operator()(relocation_entry rel, cell index, code_block *compiled)
+       {
+               relocation_type type = myvm->relocation_type_of(rel);
+               switch(type)
+               {
+               case RT_IMMEDIATE:
+               case RT_XT:
+               case RT_XT_PIC:
+               case RT_XT_PIC_TAIL:
+                       myvm->relocate_code_block_step(rel,index,compiled);
+                       break;
+               default:
+                       break;
+               }
+       }
+};
+
+void factor_vm::update_code_block_for_full_gc(code_block *compiled)
+{
+       if(code->needs_fixup_p(compiled))
+               relocate_code_block(compiled);
+       else
+       {
+               literal_and_word_references_updater updater(this);
+               iterate_relocations(compiled,updater);
+               flush_icache_for(compiled);
+       }
+}
+
 void factor_vm::check_code_address(cell address)
 {
 #ifdef FACTOR_DEBUG
index db3d1dcc53c7a9e74801cc9b7514eedcf6dc4457..64d83df3f5d81a868e7a9c275759a1b7fb464eb2 100644 (file)
@@ -97,10 +97,12 @@ void full_collector::cheneys_algorithm()
        }
 }
 
-struct full_updater {
+/* After growing the heap, we have to perform a full relocation to update
+references to card and deck arrays. */
+struct after_growing_heap_updater {
        factor_vm *myvm;
 
-       full_updater(factor_vm *myvm_) : myvm(myvm_) {}
+       after_growing_heap_updater(factor_vm *myvm_) : myvm(myvm_) {}
 
        void operator()(heap_block *block)
        {
@@ -108,29 +110,29 @@ struct full_updater {
        }
 };
 
-struct literal_and_word_reference_updater {
+/* After a full GC that did not grow the heap, we have to update references
+to literals and other words. */
+struct after_full_updater {
        factor_vm *myvm;
 
-       literal_and_word_reference_updater(factor_vm *myvm_) : myvm(myvm_) {}
+       after_full_updater(factor_vm *myvm_) : myvm(myvm_) {}
 
        void operator()(heap_block *block)
        {
-               code_block *compiled = (code_block *)block;
-               myvm->update_literal_references(compiled);
-               myvm->update_word_references(compiled);
+               myvm->update_code_block_for_full_gc((code_block *)block);
        }
 };
 
-void factor_vm::free_unmarked_code_blocks(bool growing_data_heap)
+void factor_vm::update_code_heap_for_full_gc(bool growing_data_heap)
 {
        if(growing_data_heap)
        {
-               full_updater updater(this);
+               after_growing_heap_updater updater(this);
                code->free_unmarked(updater);
        }
        else
        {
-               literal_and_word_reference_updater updater(this);
+               after_full_updater updater(this);
                code->free_unmarked(updater);
        }
 
@@ -160,7 +162,7 @@ void factor_vm::collect_growing_heap(cell requested_bytes, bool trace_contexts_p
        data_heap *old = data;
        set_data_heap(data->grow(requested_bytes));
        collect_full_impl(trace_contexts_p);
-       free_unmarked_code_blocks(true);
+       update_code_heap_for_full_gc(true);
        delete old;
 }
 
@@ -169,7 +171,7 @@ void factor_vm::collect_full(bool trace_contexts_p)
        std::swap(data->tenured,data->tenured_semispace);
        reset_generation(data->tenured);
        collect_full_impl(trace_contexts_p);
-       free_unmarked_code_blocks(false);
+       update_code_heap_for_full_gc(false);
 }
 
 }
index c4e8d25e209338d71f4dc3ec0def1fbf78225b00..a087a49b1c702f2294d173f5487f0d7e1f20a20d 100755 (executable)
--- a/vm/gc.cpp
+++ b/vm/gc.cpp
@@ -7,7 +7,7 @@ gc_state::gc_state(gc_op op_) : op(op_), start_time(current_micros()) {}
 
 gc_state::~gc_state() {}
 
-void factor_vm::update_dirty_code_blocks(std::set<code_block *> *remembered_set)
+void factor_vm::update_code_heap_for_minor_gc(std::set<code_block *> *remembered_set)
 {
        /* The youngest generation that any code block can now reference */
        std::set<code_block *>::const_iterator iter = remembered_set->begin();
index 85f04dbb2d8a9663334d45ba97928a970287d498..0cb231417ead6c03db05d0cc9a991f871033f2f0 100644 (file)
@@ -24,7 +24,7 @@ void factor_vm::collect_nursery()
                simple_unmarker(card_mark_mask));
        collector.trace_code_heap_roots(&code->points_to_nursery);
        collector.cheneys_algorithm();
-       update_dirty_code_blocks(&code->points_to_nursery);
+       update_code_heap_for_minor_gc(&code->points_to_nursery);
 
        nursery.here = nursery.start;
        code->points_to_nursery.clear();
index 6689411684056a64d4ae59cf942452dd15f431de..68038703c58e762ba5bf8eb67da6e247f8897d05 100644 (file)
@@ -21,7 +21,7 @@ void factor_vm::collect_to_tenured()
                dummy_unmarker());
        collector.trace_code_heap_roots(&code->points_to_aging);
        collector.cheneys_algorithm();
-       update_dirty_code_blocks(&code->points_to_aging);
+       update_code_heap_for_minor_gc(&code->points_to_aging);
 
        nursery.here = nursery.start;
        reset_generation(data->aging);
index ce2acfab458bfbd613135f7a25dfbc35dc07a0f2..e2fc589cd27f1eb7b85a09379f2144fa2a752646 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -234,11 +234,11 @@ struct factor_vm
        }
 
        // gc
-       void update_dirty_code_blocks(std::set<code_block *> *remembered_set);
+       void update_code_heap_for_minor_gc(std::set<code_block *> *remembered_set);
        void collect_nursery();
        void collect_aging();
        void collect_to_tenured();
-       void free_unmarked_code_blocks(bool growing_data_heap);
+       void update_code_heap_for_full_gc(bool growing_data_heap);
        void collect_full_impl(bool trace_contexts_p);
        void collect_growing_heap(cell requested_bytes, bool trace_contexts_p);
        void collect_full(bool trace_contexts_p);
@@ -479,6 +479,7 @@ struct factor_vm
        void update_literal_references(code_block *compiled);
        void relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled);
        void update_word_references(code_block *compiled);
+       void update_code_block_for_full_gc(code_block *compiled);
        void check_code_address(cell address);
        void relocate_code_block(code_block *compiled);
        void fixup_labels(array *labels, code_block *compiled);