array *factor_vm::allot_array(cell capacity, cell fill_)
{
data_root<object> fill(fill_,this);
- data_root<array> new_array(allot_uninitialized_array<array>(capacity),this);
+ array *new_array = allot_uninitialized_array<array>(capacity);
memset_cell(new_array->data(),fill.value(),capacity * sizeof(cell));
- return new_array.untagged();
+ return new_array;
}
/* push a new array on the stack */
each_object(accum);
cell object_count = accum.objects.size();
- data_roots.push_back((cell)&accum.objects[0]);
- data_roots.push_back(object_count);
+ data_roots.push_back(data_root_range(&accum.objects[0],object_count));
array *objects = allot_array(object_count,false_object);
memcpy(objects->data(),&accum.objects[0],object_count * sizeof(cell));
- 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);
+ parent->data_roots.push_back(data_root_range(&this->value_,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
parent->data_roots.pop_back();
}
};
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)
{
- data_roots.push_back(data_roots_base);
- data_roots.push_back(data_roots_size);
-
+ data_roots.push_back(data_root_range(data_roots_base,data_roots_size));
primitive_minor_gc();
-
- 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);
}
cell *data() const { return (cell *)(this + 1); }
};
+struct data_root_range {
+ cell *start;
+ cell len;
+
+ explicit data_root_range(cell *start_, cell len_) :
+ start(start_), len(len_) {}
+};
+
}
void visit_data_roots()
{
- std::vector<cell>::const_iterator iter = parent->data_roots.begin();
- std::vector<cell>::const_iterator end = parent->data_roots.end();
+ std::vector<data_root_range>::const_iterator iter = parent->data_roots.begin();
+ std::vector<data_root_range>::const_iterator end = parent->data_roots.end();
- while(iter < end)
+ for(; iter < end; iter++)
{
- cell start = *iter++;
- cell len = *iter++;
- for(cell index = 0; index < len; index++)
- visit_handle((cell *)start + index);
+ data_root_range r = *iter;
+ for(cell index = 0; index < r.len; index++)
+ visit_handle(r.start + index);
}
}
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<data_root_range> data_roots;
std::vector<cell> bignum_roots;
std::vector<code_root *> code_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);