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<array>(objects);
}
void push()
{
parent->data_roots.push_back((cell)this);
+ parent->data_roots.push_back(1);
}
explicit data_root(cell value_, factor_vm *parent_)
~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
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);
}
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);
}
explicit slot_visitor<Visitor>(factor_vm *parent_, Visitor visitor_) :
parent(parent_), visitor(visitor_) {}
- void visit_handle(cell *handle)
+ cell visit_pointer(cell pointer)
{
- cell pointer = *handle;
-
- if(immediate_p(pointer)) return;
-
object *untagged = untag<object>(pointer);
untagged = visitor(untagged);
- *handle = RETAG(untagged,TAG(pointer));
+ return RETAG(untagged,TAG(pointer));
+ }
+
+ void visit_handle(cell *handle)
+ {
+ cell pointer = *handle;
+ if(!immediate_p(pointer))
+ *handle = visit_pointer(pointer);
}
void visit_slots(object *ptr, cell payload_start)
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));
+ 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()
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);