diff --git a/vm/data_heap.cpp b/vm/data_heap.cpp index 9791c33892..e13d0dbae1 100755 --- a/vm/data_heap.cpp +++ b/vm/data_heap.cpp @@ -245,10 +245,14 @@ cell factor_vm::instances(cell type) each_object(accum); cell object_count = accum.objects.size(); - gc_off = true; + data_roots.push_back(accum.objects[0]); + data_roots.push_back(object_count); + array *objects = allot_array(object_count,false_object); memcpy(objects->data(),&accum.objects[0],object_count * sizeof(cell)); - gc_off = false; + + data_roots.pop_back(); + data_roots.pop_back(); return tag(objects); } diff --git a/vm/data_roots.hpp b/vm/data_roots.hpp index 52654c49f0..1b3eb888ef 100644 --- a/vm/data_roots.hpp +++ b/vm/data_roots.hpp @@ -8,6 +8,7 @@ struct data_root : public tagged { void push() { parent->data_roots.push_back((cell)this); + parent->data_roots.push_back(1); } explicit data_root(cell value_, factor_vm *parent_) @@ -27,6 +28,10 @@ struct data_root : public tagged { ~data_root() { +#ifdef FACTOR_DEBUG + assert(parent->data_roots.back() == 1); +#endif + parent->data_roots.pop_back(); #ifdef FACTOR_DEBUG assert(parent->data_roots.back() == (cell)this); #endif diff --git a/vm/gc.cpp b/vm/gc.cpp index 79f04db802..98266ecc91 100755 --- a/vm/gc.cpp +++ b/vm/gc.cpp @@ -218,18 +218,18 @@ void factor_vm::primitive_compact_gc() true /* trace contexts? */); } -void factor_vm::inline_gc(cell *data_roots_base, cell data_roots_size) +void factor_vm::inline_gc(cell data_roots_base, cell data_roots_size) { - for(cell i = 0; i < data_roots_size; i++) - data_roots.push_back((cell)&data_roots_base[i]); + data_roots.push_back(data_roots_base); + data_roots.push_back(data_roots_size); primitive_minor_gc(); - for(cell i = 0; i < data_roots_size; i++) - data_roots.pop_back(); + data_roots.pop_back(); + data_roots.pop_back(); } -VM_C_API void inline_gc(cell *data_roots_base, cell data_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(data_roots_base,data_roots_size); } diff --git a/vm/gc.hpp b/vm/gc.hpp index a9250eddb2..83e5da8aa1 100755 --- 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 *data_roots_base, cell data_roots_size, factor_vm *parent); +VM_C_API void inline_gc(cell data_roots_base, cell data_roots_size, factor_vm *parent); } diff --git a/vm/slot_visitor.hpp b/vm/slot_visitor.hpp index e777347622..c0263ebf11 100644 --- a/vm/slot_visitor.hpp +++ b/vm/slot_visitor.hpp @@ -8,15 +8,18 @@ template struct slot_visitor { explicit slot_visitor(factor_vm *parent_, Visitor visitor_) : parent(parent_), visitor(visitor_) {} + cell visit_pointer(cell pointer) + { + object *untagged = untag(pointer); + untagged = visitor(untagged); + return RETAG(untagged,TAG(pointer)); + } + void visit_handle(cell *handle) { cell pointer = *handle; - - if(immediate_p(pointer)) return; - - object *untagged = untag(pointer); - untagged = visitor(untagged); - *handle = RETAG(untagged,TAG(pointer)); + if(!immediate_p(pointer)) + *handle = visit_pointer(pointer); } void visit_slots(object *ptr, cell payload_start) @@ -47,8 +50,13 @@ template struct slot_visitor { std::vector::const_iterator iter = parent->data_roots.begin(); std::vector::const_iterator end = parent->data_roots.end(); - for(; iter < end; iter++) - visit_handle((cell *)(*iter)); + while(iter < end) + { + cell start = *iter++; + cell len = *iter++; + for(cell index = 0; index < len; index++) + visit_handle((cell *)start + index); + } } void visit_bignum_roots() diff --git a/vm/vm.hpp b/vm/vm.hpp index b89dda4085..cb0d0968a0 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -281,7 +281,7 @@ struct factor_vm void primitive_minor_gc(); void primitive_full_gc(); void primitive_compact_gc(); - void inline_gc(cell *data_roots_base, cell data_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);