]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: rename gc_root to data_root, add code_root to fix a problem where code blocks...
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 3 Nov 2009 00:10:34 +0000 (18:10 -0600)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 3 Nov 2009 00:10:34 +0000 (18:10 -0600)
34 files changed:
vm/alien.cpp
vm/arrays.cpp
vm/arrays.hpp
vm/byte_arrays.cpp
vm/byte_arrays.hpp
vm/callstack.cpp
vm/callstack.hpp
vm/code_block.cpp
vm/code_heap.cpp
vm/compaction.cpp
vm/dispatch.cpp
vm/errors.cpp
vm/full_collector.cpp
vm/gc.cpp
vm/gc.hpp
vm/generic_arrays.hpp
vm/image.cpp
vm/inline_cache.cpp
vm/io.cpp
vm/jit.cpp
vm/jit.hpp
vm/layouts.hpp
vm/local_roots.hpp [deleted file]
vm/master.hpp
vm/profiler.cpp
vm/quotations.cpp
vm/quotations.hpp
vm/run.cpp
vm/slot_visitor.hpp
vm/strings.cpp
vm/tagged.hpp
vm/tuples.cpp
vm/vm.hpp
vm/words.cpp

index 4171c99d62cf387a88df123d9cc2a7020dadaff7..d07b6e353b9c6f255326cfa91e5e87b02b1891e0 100755 (executable)
@@ -30,8 +30,8 @@ char *factor_vm::pinned_alien_offset(cell obj)
 /* make an alien */
 cell factor_vm::allot_alien(cell delegate_, cell displacement)
 {
-       gc_root<object> delegate(delegate_,this);
-       gc_root<alien> new_alien(allot<alien>(sizeof(alien)),this);
+       data_root<object> delegate(delegate_,this);
+       data_root<alien> new_alien(allot<alien>(sizeof(alien)),this);
 
        if(delegate.type_p(ALIEN_TYPE))
        {
@@ -117,9 +117,9 @@ DEFINE_ALIEN_ACCESSOR(cell,void *,box_alien,pinned_alien_offset)
 /* open a native library and push a handle */
 void factor_vm::primitive_dlopen()
 {
-       gc_root<byte_array> path(dpop(),this);
+       data_root<byte_array> path(dpop(),this);
        path.untag_check(this);
-       gc_root<dll> library(allot<dll>(sizeof(dll)),this);
+       data_root<dll> library(allot<dll>(sizeof(dll)),this);
        library->path = path.value();
        ffi_dlopen(library.untagged());
        dpush(library.value());
@@ -128,8 +128,8 @@ void factor_vm::primitive_dlopen()
 /* look up a symbol in a native library */
 void factor_vm::primitive_dlsym()
 {
-       gc_root<object> library(dpop(),this);
-       gc_root<byte_array> name(dpop(),this);
+       data_root<object> library(dpop(),this);
+       data_root<byte_array> name(dpop(),this);
        name.untag_check(this);
 
        symbol_char *sym = name->data<symbol_char>();
index 3c69368f29152847f31153ec297918649e9e13bb..3060ac70a348004f22af63c596514068db6fe707 100644 (file)
@@ -6,8 +6,8 @@ namespace factor
 /* make a new array with an initial element */
 array *factor_vm::allot_array(cell capacity, cell fill_)
 {
-       gc_root<object> fill(fill_,this);
-       gc_root<array> new_array(allot_uninitialized_array<array>(capacity),this);
+       data_root<object> fill(fill_,this);
+       data_root<array> new_array(allot_uninitialized_array<array>(capacity),this);
        memset_cell(new_array->data(),fill.value(),capacity * sizeof(cell));
        return new_array.untagged();
 }
@@ -22,17 +22,17 @@ void factor_vm::primitive_array()
 
 cell factor_vm::allot_array_1(cell obj_)
 {
-       gc_root<object> obj(obj_,this);
-       gc_root<array> a(allot_uninitialized_array<array>(1),this);
+       data_root<object> obj(obj_,this);
+       data_root<array> a(allot_uninitialized_array<array>(1),this);
        set_array_nth(a.untagged(),0,obj.value());
        return a.value();
 }
 
 cell factor_vm::allot_array_2(cell v1_, cell v2_)
 {
-       gc_root<object> v1(v1_,this);
-       gc_root<object> v2(v2_,this);
-       gc_root<array> a(allot_uninitialized_array<array>(2),this);
+       data_root<object> v1(v1_,this);
+       data_root<object> v2(v2_,this);
+       data_root<array> a(allot_uninitialized_array<array>(2),this);
        set_array_nth(a.untagged(),0,v1.value());
        set_array_nth(a.untagged(),1,v2.value());
        return a.value();
@@ -40,11 +40,11 @@ cell factor_vm::allot_array_2(cell v1_, cell v2_)
 
 cell factor_vm::allot_array_4(cell v1_, cell v2_, cell v3_, cell v4_)
 {
-       gc_root<object> v1(v1_,this);
-       gc_root<object> v2(v2_,this);
-       gc_root<object> v3(v3_,this);
-       gc_root<object> v4(v4_,this);
-       gc_root<array> a(allot_uninitialized_array<array>(4),this);
+       data_root<object> v1(v1_,this);
+       data_root<object> v2(v2_,this);
+       data_root<object> v3(v3_,this);
+       data_root<object> v4(v4_,this);
+       data_root<array> a(allot_uninitialized_array<array>(4),this);
        set_array_nth(a.untagged(),0,v1.value());
        set_array_nth(a.untagged(),1,v2.value());
        set_array_nth(a.untagged(),2,v3.value());
@@ -62,7 +62,7 @@ void factor_vm::primitive_resize_array()
 void growable_array::add(cell elt_)
 {
        factor_vm *parent = elements.parent;
-       gc_root<object> elt(elt_,parent);
+       data_root<object> elt(elt_,parent);
        if(count == array_capacity(elements.untagged()))
                elements = parent->reallot_array(elements.untagged(),count * 2);
 
@@ -72,7 +72,7 @@ void growable_array::add(cell elt_)
 void growable_array::append(array *elts_)
 {
        factor_vm *parent = elements.parent;
-       gc_root<array> elts(elts_,parent);
+       data_root<array> elts(elts_,parent);
        cell capacity = array_capacity(elts.untagged());
        if(count + capacity > array_capacity(elements.untagged()))
        {
index 6063269e7f944c68475667853e10cf56f868b3a6..8eb2b530b0686944d44c34255c657fc9bf7ad6d4 100755 (executable)
@@ -23,7 +23,7 @@ inline void factor_vm::set_array_nth(array *array, cell slot, cell value)
 
 struct growable_array {
        cell count;
-       gc_root<array> elements;
+       data_root<array> elements;
 
        explicit growable_array(factor_vm *parent, cell capacity = 10) :
                count(0), elements(parent->allot_array(capacity,false_object),parent) {}
index fa02ede6c34c1f5c8a4c3a976ca10bbb1e89cf01..b317c39f62e21e274740db5fe4d626bb7454d8ed 100644 (file)
@@ -43,7 +43,7 @@ void growable_byte_array::append_bytes(void *elts, cell len)
 
 void growable_byte_array::append_byte_array(cell byte_array_)
 {
-       gc_root<byte_array> byte_array(byte_array_,elements.parent);
+       data_root<byte_array> byte_array(byte_array_,elements.parent);
 
        cell len = array_capacity(byte_array.untagged());
        cell new_size = count + len;
index 0817f7dcdcd6ca132fada7c85cf7164ddedf9fc2..a3d6fcf94168654646704d454472cce9678ef345 100755 (executable)
@@ -3,7 +3,7 @@ namespace factor
 
 struct growable_byte_array {
        cell count;
-       gc_root<byte_array> elements;
+       data_root<byte_array> elements;
 
        explicit growable_byte_array(factor_vm *parent,cell capacity = 40) : count(0), elements(parent->allot_byte_array(capacity),parent) { }
 
index 623db8a3fe485c136cd4624efdfae87f7464c4d1..85f392af0e6cafbed634bf3c6f3169a86ac5dbe3 100755 (executable)
@@ -130,8 +130,8 @@ struct stack_frame_accumulator {
 
        void operator()(stack_frame *frame)
        {
-               gc_root<object> executing(parent->frame_executing(frame),parent);
-               gc_root<object> scan(parent->frame_scan(frame),parent);
+               data_root<object> executing(parent->frame_executing(frame),parent);
+               data_root<object> scan(parent->frame_scan(frame),parent);
 
                frames.add(executing.value());
                frames.add(scan.value());
@@ -142,7 +142,7 @@ struct stack_frame_accumulator {
 
 void factor_vm::primitive_callstack_to_array()
 {
-       gc_root<callstack> callstack(dpop(),this);
+       data_root<callstack> callstack(dpop(),this);
 
        stack_frame_accumulator accum(this);
        iterate_callstack_object(callstack.untagged(),accum);
@@ -184,8 +184,8 @@ void factor_vm::primitive_innermost_stack_frame_scan()
 
 void factor_vm::primitive_set_innermost_stack_frame_quot()
 {
-       gc_root<callstack> callstack(dpop(),this);
-       gc_root<quotation> quot(dpop(),this);
+       data_root<callstack> callstack(dpop(),this);
+       data_root<quotation> quot(dpop(),this);
 
        callstack.untag_check(this);
        quot.untag_check(this);
index 4d449042816e03f9e2b3609c5232677a7a46f76c..76bf3ecea49754997eeb99789691575abdc077f1 100755 (executable)
@@ -12,7 +12,7 @@ VM_ASM_API void save_callstack_bottom(stack_frame *callstack_bottom, factor_vm *
 keep the callstack in a GC root and use relative offsets */
 template<typename Iterator> void factor_vm::iterate_callstack_object(callstack *stack_, Iterator &iterator)
 {
-       gc_root<callstack> stack(stack_,this);
+       data_root<callstack> stack(stack_,this);
        fixnum frame_offset = untag_fixnum(stack->length) - sizeof(stack_frame);
 
        while(frame_offset >= 0)
index d3670af3c0b1782ebe280d2962a72ca330eb3062..98696307320c6deec1c0c75bb831642d9acc18f2 100755 (executable)
@@ -467,11 +467,11 @@ code_block *factor_vm::allot_code_block(cell size, code_block_type type)
 /* Might GC */
 code_block *factor_vm::add_code_block(code_block_type type, cell code_, cell labels_, cell owner_, cell relocation_, cell literals_)
 {
-       gc_root<byte_array> code(code_,this);
-       gc_root<object> labels(labels_,this);
-       gc_root<object> owner(owner_,this);
-       gc_root<byte_array> relocation(relocation_,this);
-       gc_root<array> literals(literals_,this);
+       data_root<byte_array> code(code_,this);
+       data_root<object> labels(labels_,this);
+       data_root<object> owner(owner_,this);
+       data_root<byte_array> relocation(relocation_,this);
+       data_root<array> literals(literals_,this);
 
        cell code_length = array_capacity(code.untagged());
        code_block *compiled = allot_code_block(code_length,type);
index f3d36527b53687fe4710d04de366e0d7c654af90..b4e071d64462a3145e753517fd4416ebc83c0079 100755 (executable)
@@ -73,8 +73,8 @@ bool factor_vm::in_code_heap_p(cell ptr)
 /* Compile a word definition with the non-optimizing compiler. Allocates memory */
 void factor_vm::jit_compile_word(cell word_, cell def_, bool relocate)
 {
-       gc_root<word> word(word_,this);
-       gc_root<quotation> def(def_,this);
+       data_root<word> word(word_,this);
+       data_root<quotation> def(def_,this);
 
        jit_compile(def.value(),relocate);
 
@@ -145,7 +145,7 @@ void factor_vm::relocate_code_heap()
 
 void factor_vm::primitive_modify_code_heap()
 {
-       gc_root<array> alist(dpop(),this);
+       data_root<array> alist(dpop(),this);
 
        cell count = array_capacity(alist.untagged());
 
@@ -155,10 +155,10 @@ void factor_vm::primitive_modify_code_heap()
        cell i;
        for(i = 0; i < count; i++)
        {
-               gc_root<array> pair(array_nth(alist.untagged(),i),this);
+               data_root<array> pair(array_nth(alist.untagged(),i),this);
 
-               gc_root<word> word(array_nth(pair.untagged(),0),this);
-               gc_root<object> data(array_nth(pair.untagged(),1),this);
+               data_root<word> word(array_nth(pair.untagged(),0),this);
+               data_root<object> data(array_nth(pair.untagged(),1),this);
 
                switch(data.type())
                {
index 86d3efd3d6595910cde5ec796d4fbbdab3447d9d..10e37db263ac9c080903acec7c17813e03c51ea1 100644 (file)
@@ -139,6 +139,8 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p)
                code_forwarder.visit_callback_code_blocks();
        }
 
+       update_code_roots_for_compaction();
+
        current_gc->event->ended_compaction();
 }
 
@@ -182,6 +184,8 @@ void factor_vm::collect_compact_code_impl(bool trace_contexts_p)
        code_block_compaction_updater<dummy_slot_forwarder> code_block_updater(this,slot_forwarder);
        standard_sizer<code_block> code_block_sizer;
        code->allocator->compact(code_block_updater,code_block_sizer);
+
+       update_code_roots_for_compaction();
 }
 
 }
index 30c4617cf0889951e5e9627b2062f60a7a272e03..6bef9709444162a666db59e0e2bbc41c7638a58e 100755 (executable)
@@ -149,8 +149,8 @@ void factor_vm::primitive_dispatch_stats()
 
 void quotation_jit::emit_mega_cache_lookup(cell methods_, fixnum index, cell cache_)
 {
-       gc_root<array> methods(methods_,parent);
-       gc_root<array> cache(cache_,parent);
+       data_root<array> methods(methods_,parent);
+       data_root<array> cache(cache_,parent);
 
        /* Generate machine code to determine the object's class. */
        emit_class_lookup(index,PIC_TUPLE);
index 3161f625cd8b99a23bd2d26a6aa9886bf6a4dd72..2bbe3e5328e6eac42444876735f89f86bab8607c 100755 (executable)
@@ -37,8 +37,8 @@ void factor_vm::throw_error(cell error, stack_frame *callstack_top)
                gc_off = false;
 
                /* Reset local roots */
-               gc_locals.clear();
-               gc_bignums.clear();
+               data_roots.clear();
+               bignum_roots.clear();
 
                /* If we had an underflow or overflow, stack pointers might be
                out of bounds */
index 369fc38f09c8e59fc6688b8e8000bd833cae2c31..acce7773018d44840045b157852d7974c12719ab 100644 (file)
@@ -9,6 +9,56 @@ full_collector::full_collector(factor_vm *parent_) :
                parent_->data->tenured,
                full_policy(parent_)) {}
 
+/* After a sweep, invalidate any code heap roots which are not marked,
+so that if a block makes a tail call to a generic word, and the PIC
+compiler triggers a GC, and the caller block gets gets GCd as a result,
+the PIC code won't try to overwrite the call site */
+void factor_vm::update_code_roots_for_sweep()
+{
+       std::vector<code_root *>::const_iterator iter = code_roots.begin();
+       std::vector<code_root *>::const_iterator end = code_roots.end();
+
+       mark_bits<code_block> *state = &code->allocator->state;
+
+       for(; iter < end; iter++)
+       {
+               printf("We have a code root!\n");
+               code_root *root = *iter;
+               code_block *block = (code_block *)(root->value & -block_granularity);
+               if(root->valid && !state->marked_p(block))
+                       root->valid = false;
+       }
+}
+
+/* After a compaction, invalidate any code heap roots which are not
+marked as above, and also slide the valid roots up so that call sites
+can be updated correctly. */
+void factor_vm::update_code_roots_for_compaction()
+{
+       std::vector<code_root *>::const_iterator iter = code_roots.begin();
+       std::vector<code_root *>::const_iterator end = code_roots.end();
+
+       mark_bits<code_block> *state = &code->allocator->state;
+
+       for(; iter < end; iter++)
+       {
+               printf("We have a code root - compaction!\n");
+               code_root *root = *iter;
+               code_block *block = (code_block *)(root->value & -block_granularity);
+
+               /* Offset of return address within 16-byte allocation line */
+               cell offset = root->value - (cell)block;
+
+               if(root->valid && state->marked_p((code_block *)root->value))
+               {
+                       block = state->forward_block(block);
+                       root->value = (cell)block + offset;
+               }
+               else
+                       root->valid = false;
+       }
+}
+
 struct code_block_marker {
        code_heap *code;
        full_collector *collector;
@@ -66,6 +116,7 @@ void factor_vm::collect_sweep_impl()
 {
        current_gc->event->started_data_sweep();
        data->tenured->sweep();
+       update_code_roots_for_sweep();
        current_gc->event->ended_data_sweep();
 }
 
index afc1798911836f318f656fca404dc084a8b09572..06e9d78ce28d0386a8ba6c3af6680ec7af7d4466 100755 (executable)
--- a/vm/gc.cpp
+++ b/vm/gc.cpp
@@ -249,20 +249,20 @@ void factor_vm::primitive_become()
        compile_all_words();
 }
 
-void factor_vm::inline_gc(cell *gc_roots_base, cell gc_roots_size)
+void factor_vm::inline_gc(cell *data_roots_base, cell data_roots_size)
 {
-       for(cell i = 0; i < gc_roots_size; i++)
-               gc_locals.push_back((cell)&gc_roots_base[i]);
+       for(cell i = 0; i < data_roots_size; i++)
+               data_roots.push_back((cell)&data_roots_base[i]);
 
        primitive_minor_gc();
 
-       for(cell i = 0; i < gc_roots_size; i++)
-               gc_locals.pop_back();
+       for(cell i = 0; i < data_roots_size; i++)
+               data_roots.pop_back();
 }
 
-VM_C_API void inline_gc(cell *gc_roots_base, cell gc_roots_size, factor_vm *parent)
+VM_C_API void inline_gc(cell *data_roots_base, cell data_roots_size, factor_vm *parent)
 {
-       parent->inline_gc(gc_roots_base,gc_roots_size);
+       parent->inline_gc(data_roots_base,data_roots_size);
 }
 
 /*
index 7ad7e71524dea5b140f5f2787d2a8b3596370f6a..a9250eddb20e17f3123d5a96fb5779fa1e099078 100755 (executable)
--- a/vm/gc.hpp
+++ b/vm/gc.hpp
@@ -53,6 +53,6 @@ struct gc_state {
        void start_again(gc_op op_, factor_vm *parent);
 };
 
-VM_C_API void inline_gc(cell *gc_roots_base, cell gc_roots_size, factor_vm *parent);
+VM_C_API void inline_gc(cell *data_roots_base, cell data_roots_size, factor_vm *parent);
 
 }
index 89eb56a70d37a76b198fb42600894d3dde360671..f45785f9ef69d45e10ebb546bc8eeebbd81b0c4f 100755 (executable)
@@ -33,7 +33,7 @@ template<typename Array> bool factor_vm::reallot_array_in_place_p(Array *array,
 
 template<typename Array> Array *factor_vm::reallot_array(Array *array_, cell capacity)
 {
-       gc_root<Array> array(array_,this);
+       data_root<Array> array(array_,this);
 
        if(reallot_array_in_place_p(array.untagged(),capacity))
        {
index 0524a145a8862bc34af1fe36e8cebb7e3eafa635..b3a9eae7a5ea41a13a67a791f082ceea8205b09b 100755 (executable)
@@ -311,7 +311,7 @@ void factor_vm::primitive_save_image()
        /* do a full GC to push everything into tenured space */
        primitive_compact_gc();
 
-       gc_root<byte_array> path(dpop(),this);
+       data_root<byte_array> path(dpop(),this);
        path.untag_check(this);
        save_image((vm_char *)(path.untagged() + 1));
 }
@@ -321,7 +321,7 @@ void factor_vm::primitive_save_image_and_exit()
        /* We unbox this before doing anything else. This is the only point
        where we might throw an error, so we have to throw an error here since
        later steps destroy the current image. */
-       gc_root<byte_array> path(dpop(),this);
+       data_root<byte_array> path(dpop(),this);
        path.untag_check(this);
 
        /* strip out special_objects data which is set on startup anyway */
index 3542a92b78f66d164ae2a82460f6a5ff453763a9..fd5e93560b301b4d192ae379f6a32202bd48dffe 100755 (executable)
@@ -83,9 +83,9 @@ void inline_cache_jit::compile_inline_cache(fixnum index,
                                            cell cache_entries_,
                                            bool tail_call_p)
 {
-       gc_root<word> generic_word(generic_word_,parent);
-       gc_root<array> methods(methods_,parent);
-       gc_root<array> cache_entries(cache_entries_,parent);
+       data_root<word> generic_word(generic_word_,parent);
+       data_root<array> methods(methods_,parent);
+       data_root<array> cache_entries(cache_entries_,parent);
 
        cell inline_cache_type = parent->determine_inline_cache_type(cache_entries.untagged());
        parent->update_pic_count(inline_cache_type);
@@ -118,11 +118,15 @@ void inline_cache_jit::compile_inline_cache(fixnum index,
        word_special(parent->special_objects[tail_call_p ? PIC_MISS_TAIL_WORD : PIC_MISS_WORD]);
 }
 
-code_block *factor_vm::compile_inline_cache(fixnum index,cell generic_word_,cell methods_,cell cache_entries_,bool tail_call_p)
+code_block *factor_vm::compile_inline_cache(fixnum index,
+       cell generic_word_,
+       cell methods_,
+       cell cache_entries_,
+       bool tail_call_p)
 {
-       gc_root<word> generic_word(generic_word_,this);
-       gc_root<array> methods(methods_,this);
-       gc_root<array> cache_entries(cache_entries_,this);
+       data_root<word> generic_word(generic_word_,this);
+       data_root<array> methods(methods_,this);
+       data_root<array> cache_entries(cache_entries_,this);
 
        inline_cache_jit jit(generic_word.value(),this);
        jit.compile_inline_cache(index,
@@ -149,12 +153,12 @@ cell factor_vm::inline_cache_size(cell cache_entries)
 /* Allocates memory */
 cell factor_vm::add_inline_cache_entry(cell cache_entries_, cell klass_, cell method_)
 {
-       gc_root<array> cache_entries(cache_entries_,this);
-       gc_root<object> klass(klass_,this);
-       gc_root<word> method(method_,this);
+       data_root<array> cache_entries(cache_entries_,this);
+       data_root<object> klass(klass_,this);
+       data_root<word> method(method_,this);
 
        cell pic_size = array_capacity(cache_entries.untagged());
-       gc_root<array> new_cache_entries(reallot_array(cache_entries.untagged(),pic_size + 2),this);
+       data_root<array> new_cache_entries(reallot_array(cache_entries.untagged(),pic_size + 2),this);
        set_array_nth(new_cache_entries.untagged(),pic_size,klass.value());
        set_array_nth(new_cache_entries.untagged(),pic_size + 1,method.value());
        return new_cache_entries.value();
@@ -170,22 +174,27 @@ void factor_vm::update_pic_transitions(cell pic_size)
                ic_to_pic_transitions++;
 }
 
-/* The cache_entries parameter is either f (on cold call site) or an array (on cache miss).
-Called from assembly with the actual return address */
-void *factor_vm::inline_cache_miss(cell return_address)
+/* The cache_entries parameter is either f (on cold call site) or an array
+(on cache miss). Called from assembly with the actual return address.
+Compilation of the inline cache may trigger a GC, which may trigger a compaction;
+also, the block containing the return address may now be dead. Use a code_root
+to take care of the details. */
+void *factor_vm::inline_cache_miss(cell return_address_)
 {
-       check_code_pointer(return_address);
+       code_root return_address(return_address_,this);
+
+       check_code_pointer(return_address.value);
 
        /* Since each PIC is only referenced from a single call site,
           if the old call target was a PIC, we can deallocate it immediately,
           instead of leaving dead PICs around until the next GC. */
-       deallocate_inline_cache(return_address);
+       deallocate_inline_cache(return_address.value);
 
-       gc_root<array> cache_entries(dpop(),this);
+       data_root<array> cache_entries(dpop(),this);
        fixnum index = untag_fixnum(dpop());
-       gc_root<array> methods(dpop(),this);
-       gc_root<word> generic_word(dpop(),this);
-       gc_root<object> object(((cell *)ds)[-index],this);
+       data_root<array> methods(dpop(),this);
+       data_root<word> generic_word(dpop(),this);
+       data_root<object> object(((cell *)ds)[-index],this);
 
        void *xt;
 
@@ -200,7 +209,7 @@ void *factor_vm::inline_cache_miss(cell return_address)
                cell klass = object_class(object.value());
                cell method = lookup_method(object.value(),methods.value());
 
-               gc_root<array> new_cache_entries(add_inline_cache_entry(
+               data_root<array> new_cache_entries(add_inline_cache_entry(
                                                           cache_entries.value(),
                                                           klass,
                                                           method),this);
@@ -208,18 +217,21 @@ void *factor_vm::inline_cache_miss(cell return_address)
                                          generic_word.value(),
                                          methods.value(),
                                          new_cache_entries.value(),
-                                         tail_call_site_p(return_address))->xt();
+                                         tail_call_site_p(return_address.value))->xt();
        }
 
        /* Install the new stub. */
-       set_call_target(return_address,xt);
+       if(return_address.valid)
+       {
+               set_call_target(return_address.value,xt);
 
 #ifdef PIC_DEBUG
-       std::cout << "Updated "
-               << (tail_call_site_p(return_address) ? "tail" : "non-tail")
-               << " call site 0x" << std::hex << return_address << std::dec
-               << " with " << std::hex << (cell)xt << std::dec;
+               std::cout << "Updated "
+                       << (tail_call_site_p(return_address) ? "tail" : "non-tail")
+                       << " call site 0x" << std::hex << return_address << std::dec
+                       << " with " << std::hex << (cell)xt << std::dec;
 #endif
+       }
 
        return xt;
 }
index bbcac0b849416372a37a31313e2229de72908e6a..a8f9cb6897f4507fb05ab931ab68ef071e43bb1a 100755 (executable)
--- a/vm/io.cpp
+++ b/vm/io.cpp
@@ -33,8 +33,8 @@ void factor_vm::io_error()
 
 void factor_vm::primitive_fopen()
 {
-       gc_root<byte_array> mode(dpop(),this);
-       gc_root<byte_array> path(dpop(),this);
+       data_root<byte_array> mode(dpop(),this);
+       data_root<byte_array> path(dpop(),this);
        mode.untag_check(this);
        path.untag_check(this);
 
@@ -88,7 +88,7 @@ void factor_vm::primitive_fread()
                return;
        }
 
-       gc_root<byte_array> buf(allot_uninitialized_array<byte_array>(size),this);
+       data_root<byte_array> buf(allot_uninitialized_array<byte_array>(size),this);
 
        for(;;)
        {
index 2fa948e4d65ad6dcee274484a3bf98a189fa03aa..e72e88bfdff70c6c45945cdbfc34bbfec1b32c49 100644 (file)
@@ -24,7 +24,7 @@ jit::jit(code_block_type type_, cell owner_, factor_vm *vm)
 
 void jit::emit_relocation(cell code_template_)
 {
-       gc_root<array> code_template(code_template_,parent);
+       data_root<array> code_template(code_template_,parent);
        cell capacity = array_capacity(code_template.untagged());
        for(cell i = 1; i < capacity; i += 3)
        {
@@ -43,11 +43,11 @@ void jit::emit_relocation(cell code_template_)
 /* Allocates memory */
 void jit::emit(cell code_template_)
 {
-       gc_root<array> code_template(code_template_,parent);
+       data_root<array> code_template(code_template_,parent);
 
        emit_relocation(code_template.value());
 
-       gc_root<byte_array> insns(array_nth(code_template.untagged(),0),parent);
+       data_root<byte_array> insns(array_nth(code_template.untagged(),0),parent);
 
        if(computing_offset_p)
        {
@@ -71,8 +71,8 @@ void jit::emit(cell code_template_)
 }
 
 void jit::emit_with(cell code_template_, cell argument_) {
-       gc_root<array> code_template(code_template_,parent);
-       gc_root<object> argument(argument_,parent);
+       data_root<array> code_template(code_template_,parent);
+       data_root<object> argument(argument_,parent);
        literal(argument.value());
        emit(code_template.value());
 }
index 9feade4cc1a127b3b70faeaf049bfa8b415782d5..b5a2457d570b4495ecc10b904b96e6d8dd13d082 100644 (file)
@@ -3,7 +3,7 @@ namespace factor
 
 struct jit {
        code_block_type type;
-       gc_root<object> owner;
+       data_root<object> owner;
        growable_byte_array code;
        growable_byte_array relocation;
        growable_array literals;
@@ -28,7 +28,7 @@ struct jit {
 
        void word_jump(cell word_)
        {
-               gc_root<word> word(word_,parent);
+               data_root<word> word(word_,parent);
                literal(tag_fixnum(xt_tail_pic_offset));
                literal(word.value());
                emit(parent->special_objects[JIT_WORD_JUMP]);
@@ -46,8 +46,8 @@ struct jit {
 
        void emit_subprimitive(cell word_)
        {
-               gc_root<word> word(word_,parent);
-               gc_root<array> code_pair(word->subprimitive,parent);
+               data_root<word> word(word_,parent);
+               data_root<array> code_pair(word->subprimitive,parent);
                literals.append(untag<array>(array_nth(code_pair.untagged(),0)));
                emit(array_nth(code_pair.untagged(),1));
        }
index 2e4a90cc0e68145f3f1f8e7f98b0c8c6e77307ca..6b96ade8f5780a1f33a367c8d2a650a4cef9a4bc 100644 (file)
@@ -51,7 +51,7 @@ static const cell data_alignment = 16;
 
 #define TYPE_COUNT 14
 
-#define GC_COLLECTED 5 /* can be anything other than FIXNUM_TYPE */
+#define FORWARDING_POINTER 5 /* can be anything other than FIXNUM_TYPE */
 
 enum code_block_type
 {
@@ -117,7 +117,7 @@ struct header {
 
        bool forwarding_pointer_p() const
        {
-               return TAG(value) == GC_COLLECTED;
+               return TAG(value) == FORWARDING_POINTER;
        }
 
        object *forwarding_pointer() const
@@ -127,7 +127,7 @@ struct header {
 
        void forward_to(object *pointer)
        {
-               value = RETAG(pointer,GC_COLLECTED);
+               value = RETAG(pointer,FORWARDING_POINTER);
        }
 };
 
@@ -344,8 +344,7 @@ struct dll : public object {
        void *dll;
 };
 
-struct stack_frame
-{
+struct stack_frame {
        void *xt;
        /* Frame size in bytes */
        cell size;
diff --git a/vm/local_roots.hpp b/vm/local_roots.hpp
deleted file mode 100644 (file)
index 442a91f..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-namespace factor
-{
-
-template<typename Type>
-struct gc_root : public tagged<Type>
-{
-       factor_vm *parent;
-
-       void push() { parent->gc_locals.push_back((cell)this); }
-
-       explicit gc_root(cell value_,factor_vm *vm) : tagged<Type>(value_),parent(vm) { push(); }
-       explicit gc_root(Type *value_, factor_vm *vm) : tagged<Type>(value_),parent(vm) { push(); }
-
-       const gc_root<Type>& operator=(const Type *x) { tagged<Type>::operator=(x); return *this; }
-       const gc_root<Type>& operator=(const cell &x) { tagged<Type>::operator=(x); return *this; }
-
-       ~gc_root() {
-#ifdef FACTOR_DEBUG
-               assert(parent->gc_locals.back() == (cell)this);
-#endif
-               parent->gc_locals.pop_back();
-       }
-};
-
-/* A similar hack for the bignum implementation */
-struct gc_bignum
-{
-       bignum **addr;
-       factor_vm *parent;
-       gc_bignum(bignum **addr_, factor_vm *vm) : addr(addr_), parent(vm) {
-               if(*addr_)
-                       parent->check_data_pointer(*addr_);
-               parent->gc_bignums.push_back((cell)addr);
-       }
-
-       ~gc_bignum() {
-#ifdef FACTOR_DEBUG
-               assert(parent->gc_bignums.back() == (cell)addr);
-#endif
-               parent->gc_bignums.pop_back();
-       }
-};
-
-#define GC_BIGNUM(x) gc_bignum x##__gc_root(&x,this)
-
-}
index 0f8276cf6698c4976e51a900a1019fbe3b12d363..0654e63bcb01a744e1bdebef8d90f3461431fc6d 100755 (executable)
@@ -74,7 +74,8 @@ namespace factor
 #include "vm.hpp"
 #include "allot.hpp"
 #include "tagged.hpp"
-#include "local_roots.hpp"
+#include "data_roots.hpp"
+#include "code_roots.hpp"
 #include "slot_visitor.hpp"
 #include "collector.hpp"
 #include "copying_collector.hpp"
index 2f5fc6fcf49d03d6961029247874d9ac744ba9f6..50e88cc57ad9c55f2a1d261a22593f37341752d4 100755 (executable)
@@ -11,7 +11,7 @@ void factor_vm::init_profiler()
 /* Allocates memory */
 code_block *factor_vm::compile_profiling_stub(cell word_)
 {
-       gc_root<word> word(word_,this);
+       data_root<word> word(word_,this);
 
        jit jit(code_block_profiling,word.value(),this);
        jit.emit_with(special_objects[JIT_PROFILING],word.value());
@@ -31,7 +31,7 @@ void factor_vm::set_profiling(bool profiling)
        and allocate profiling blocks if necessary */
        primitive_full_gc();
 
-       gc_root<array> words(find_all_words(),this);
+       data_root<array> words(find_all_words(),this);
 
        cell i;
        cell length = array_capacity(words.untagged());
index 17b7c4328b7018145965fb7aa04c8c4a086d698f..2c5e401ad9b4685b0960d9ab77511c196303977a 100755 (executable)
@@ -110,7 +110,7 @@ bool quotation_jit::trivial_quotation_p(array *elements)
 
 void quotation_jit::emit_quot(cell quot_)
 {
-       gc_root<quotation> quot(quot_,parent);
+       data_root<quotation> quot(quot_,parent);
 
        array *elements = untag<array>(quot->array);
 
@@ -143,7 +143,7 @@ void quotation_jit::iterate_quotation()
        {
                set_position(i);
 
-               gc_root<object> obj(array_nth(elements.untagged(),i),parent);
+               data_root<object> obj(array_nth(elements.untagged(),i),parent);
 
                switch(obj.type())
                {
@@ -290,7 +290,7 @@ void factor_vm::set_quot_xt(quotation *quot, code_block *code)
 /* Allocates memory */
 void factor_vm::jit_compile(cell quot_, bool relocating)
 {
-       gc_root<quotation> quot(quot_,this);
+       data_root<quotation> quot(quot_,this);
        if(quot->code) return;
 
        quotation_jit compiler(quot.value(),true,relocating,this);
@@ -327,13 +327,13 @@ void factor_vm::primitive_quotation_xt()
 
 void factor_vm::compile_all_words()
 {
-       gc_root<array> words(find_all_words(),this);
+       data_root<array> words(find_all_words(),this);
 
        cell i;
        cell length = array_capacity(words.untagged());
        for(i = 0; i < length; i++)
        {
-               gc_root<word> word(array_nth(words.untagged(),i),this);
+               data_root<word> word(array_nth(words.untagged(),i),this);
 
                if(!word->code || !word->code->optimized_p())
                        jit_compile_word(word.value(),word->def,false);
@@ -348,8 +348,8 @@ void factor_vm::compile_all_words()
 /* Allocates memory */
 fixnum factor_vm::quot_code_offset_to_scan(cell quot_, cell offset)
 {
-       gc_root<quotation> quot(quot_,this);
-       gc_root<array> array(quot->array,this);
+       data_root<quotation> quot(quot_,this);
+       data_root<array> array(quot->array,this);
 
        quotation_jit compiler(quot.value(),false,false,this);
        compiler.compute_position(offset);
@@ -360,7 +360,7 @@ fixnum factor_vm::quot_code_offset_to_scan(cell quot_, cell offset)
 
 cell factor_vm::lazy_jit_compile_impl(cell quot_, stack_frame *stack)
 {
-       gc_root<quotation> quot(quot_,this);
+       data_root<quotation> quot(quot_,this);
        ctx->callstack_top = stack;
        jit_compile(quot.value(),true);
        return quot.value();
index e6e6afcd0b1a95e2aa7a5481e48c084c6b143b0f..6d04d80de3d872ad4a33f9288db2fe96d21f0eba 100755 (executable)
@@ -2,7 +2,7 @@ namespace factor
 {
 
 struct quotation_jit : public jit {
-       gc_root<array> elements;
+       data_root<array> elements;
        bool compiling, relocate;
 
        explicit quotation_jit(cell quot, bool compiling_, bool relocate_, factor_vm *vm)
index b6e33245023644c538a7332fe0c7b05565f7886c..6d3e9f7374695e18d08744989b3ea6a23e6d5e5e 100755 (executable)
@@ -52,7 +52,7 @@ void factor_vm::primitive_load_locals()
 
 cell factor_vm::clone_object(cell obj_)
 {
-       gc_root<object> obj(obj_,this);
+       data_root<object> obj(obj_,this);
 
        if(immediate_p(obj.value()))
                return obj.value();
index 38d0081c0adf7c7c1bce0fe62aed080aab3273e9..e777347622b3ccc9970d6e73f2f15dbe087a6145 100644 (file)
@@ -42,19 +42,19 @@ template<typename Visitor> struct slot_visitor {
                        visit_handle(ptr);
        }
 
-       void visit_registered_locals()
+       void visit_data_roots()
        {
-               std::vector<cell>::const_iterator iter = parent->gc_locals.begin();
-               std::vector<cell>::const_iterator end = parent->gc_locals.end();
+               std::vector<cell>::const_iterator iter = parent->data_roots.begin();
+               std::vector<cell>::const_iterator end = parent->data_roots.end();
 
                for(; iter < end; iter++)
                        visit_handle((cell *)(*iter));
        }
 
-       void visit_registered_bignums()
+       void visit_bignum_roots()
        {
-               std::vector<cell>::const_iterator iter = parent->gc_bignums.begin();
-               std::vector<cell>::const_iterator end = parent->gc_bignums.end();
+               std::vector<cell>::const_iterator iter = parent->bignum_roots.begin();
+               std::vector<cell>::const_iterator end = parent->bignum_roots.end();
 
                for(; iter < end; iter++)
                {
@@ -72,8 +72,8 @@ template<typename Visitor> struct slot_visitor {
                visit_handle(&parent->bignum_pos_one);
                visit_handle(&parent->bignum_neg_one);
 
-               visit_registered_locals();
-               visit_registered_bignums();
+               visit_data_roots();
+               visit_bignum_roots();
 
                for(cell i = 0; i < special_object_count; i++)
                        visit_handle(&parent->special_objects[i]);
index 3022611319b91b2aa7ce1d26aa29566355204ed3..9e135e6779d501bfe47d53bcf973eb823dd48ac0 100644 (file)
@@ -29,7 +29,7 @@ void factor_vm::set_string_nth_fast(string *str, cell index, cell ch)
 
 void factor_vm::set_string_nth_slow(string *str_, cell index, cell ch)
 {
-       gc_root<string> str(str_,this);
+       data_root<string> str(str_,this);
 
        byte_array *aux;
 
@@ -78,7 +78,7 @@ string *factor_vm::allot_string_internal(cell capacity)
 /* Allocates memory */
 void factor_vm::fill_string(string *str_, cell start, cell capacity, cell fill)
 {
-       gc_root<string> str(str_,this);
+       data_root<string> str(str_,this);
 
        if(fill <= 0x7f)
                memset(&str->data()[start],fill,capacity - start);
@@ -94,7 +94,7 @@ void factor_vm::fill_string(string *str_, cell start, cell capacity, cell fill)
 /* Allocates memory */
 string *factor_vm::allot_string(cell capacity, cell fill)
 {
-       gc_root<string> str(allot_string_internal(capacity),this);
+       data_root<string> str(allot_string_internal(capacity),this);
        fill_string(str.untagged(),0,capacity,fill);
        return str.untagged();
 }
@@ -115,7 +115,7 @@ bool factor_vm::reallot_string_in_place_p(string *str, cell capacity)
 
 string* factor_vm::reallot_string(string *str_, cell capacity)
 {
-       gc_root<string> str(str_,this);
+       data_root<string> str(str_,this);
 
        if(reallot_string_in_place_p(str.untagged(),capacity))
        {
@@ -135,7 +135,7 @@ string* factor_vm::reallot_string(string *str_, cell capacity)
                if(capacity < to_copy)
                        to_copy = capacity;
 
-               gc_root<string> new_str(allot_string_internal(capacity),this);
+               data_root<string> new_str(allot_string_internal(capacity),this);
 
                memcpy(new_str->data(),str->data(),to_copy);
 
index 77cb6e5287a41abe8aa4a5bc999ba303ebb9354a..e520e326fa95325787f947d0366844552a77ba8f 100755 (executable)
@@ -16,7 +16,8 @@ struct tagged
 {
        cell value_;
 
-       cell type() const {
+       cell type() const
+       {
                return TAG(value_);
        }
 
@@ -33,20 +34,24 @@ struct tagged
                        return type_p(Type::type_number);
        }
 
-       cell value() const {
+       cell value() const
+       {
 #ifdef FACTOR_DEBUG
                assert(type_p());
 #endif
                return value_;
        }
-       Type *untagged() const {
+
+       Type *untagged() const
+       {
 #ifdef FACTOR_DEBUG
                assert(type_p());
 #endif
                return (Type *)(UNTAG(value_));
        }
 
-       Type *untag_check(factor_vm *parent) const {
+       Type *untag_check(factor_vm *parent) const
+       {
                if(!type_p())
                        parent->type_error(Type::type_number,value_);
                return untagged();
index 8c759b4884ca9032d552cc8310c026356fa4e4d6..eaac437753d90e41e4ca1e159b0bb5fc81403e97 100755 (executable)
@@ -6,7 +6,7 @@ namespace factor
 /* push a new tuple on the stack, filling its slots with f */
 void factor_vm::primitive_tuple()
 {
-       gc_root<tuple_layout> layout(dpop(),this);
+       data_root<tuple_layout> layout(dpop(),this);
        tagged<tuple> t(allot<tuple>(tuple_size(layout.untagged())));
        t->layout = layout.value();
 
@@ -18,7 +18,7 @@ void factor_vm::primitive_tuple()
 /* push a new tuple on the stack, filling its slots from the stack */
 void factor_vm::primitive_tuple_boa()
 {
-       gc_root<tuple_layout> layout(dpop(),this);
+       data_root<tuple_layout> layout(dpop(),this);
        tagged<tuple> t(allot<tuple>(tuple_size(layout.untagged())));
        t->layout = layout.value();
 
index d58ce37742baec7904b5c23b916109f33de5ca91..0789590c492c62feed975371e58210a520147351 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -2,6 +2,7 @@ namespace factor
 {
 
 struct growable_array;
+struct code_root;
 
 struct factor_vm
 {
@@ -62,10 +63,12 @@ struct factor_vm
        std::vector<gc_event> *gc_events;
 
        /* If a runtime function needs to call another function which potentially
-          allocates memory, it must wrap any local variable references to Factor
-          objects in gc_root instances */
-       std::vector<cell> gc_locals;
-       std::vector<cell> gc_bignums;
+          allocates memory, it must wrap any references to the data and code
+          heaps with data_root and code_root smart pointers, which register
+          themselves here. See data_roots.hpp and code_roots.hpp */
+       std::vector<cell> data_roots;
+       std::vector<cell> bignum_roots;
+       std::vector<code_root *> code_roots;
 
        /* Debugger */
        bool fep_disabled;
@@ -255,6 +258,8 @@ struct factor_vm
        void collect_nursery();
        void collect_aging();
        void collect_to_tenured();
+       void update_code_roots_for_sweep();
+       void update_code_roots_for_compaction();
        void collect_mark_impl(bool trace_contexts_p);
        void collect_sweep_impl();
        void collect_compact_impl(bool trace_contexts_p);
@@ -265,7 +270,7 @@ struct factor_vm
        void primitive_full_gc();
        void primitive_compact_gc();
        void primitive_become();
-       void inline_gc(cell *gc_roots_base, cell gc_roots_size);
+       void inline_gc(cell *data_roots_base, cell data_roots_size);
        void primitive_enable_gc_events();
        void primitive_disable_gc_events();
        object *allot_object(header header, cell size);
index 4248c14b7dcea1e35c8dbc797663fb72fc6c2ea4..c375ec217444b84c33a72cfcaf3d2db6b039f7fb 100644 (file)
@@ -5,10 +5,10 @@ namespace factor
 
 word *factor_vm::allot_word(cell name_, cell vocab_, cell hashcode_)
 {
-       gc_root<object> vocab(vocab_,this);
-       gc_root<object> name(name_,this);
+       data_root<object> vocab(vocab_,this);
+       data_root<object> name(name_,this);
 
-       gc_root<word> new_word(allot<word>(sizeof(word)),this);
+       data_root<word> new_word(allot<word>(sizeof(word)),this);
 
        new_word->hashcode = hashcode_;
        new_word->vocabulary = vocab.value();
@@ -43,7 +43,7 @@ void factor_vm::primitive_word()
 /* word-xt ( word -- start end ) */
 void factor_vm::primitive_word_xt()
 {
-       gc_root<word> w(dpop(),this);
+       data_root<word> w(dpop(),this);
        w.untag_check(this);
 
        if(profiling_p)
@@ -61,7 +61,7 @@ void factor_vm::primitive_word_xt()
 /* Allocates memory */
 void factor_vm::update_word_xt(word *w_)
 {
-       gc_root<word> w(w_,this);
+       data_root<word> w(w_,this);
 
        if(profiling_p)
        {