vm: faster data_root and <array> primitive

db4
Slava Pestov 2009-11-06 05:30:37 -06:00
parent a46671e3ad
commit 11075828e5
8 changed files with 24 additions and 31 deletions

View File

@ -7,9 +7,9 @@ namespace factor
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 */

View File

@ -245,13 +245,11 @@ cell factor_vm::instances(cell type)
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);

View File

@ -7,8 +7,7 @@ struct data_root : public tagged<Type> {
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_)
@ -28,13 +27,6 @@ struct data_root : public tagged<Type> {
~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();
}
};

View File

@ -218,18 +218,14 @@ 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)
{
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);
}

View File

@ -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);
}

View File

@ -373,4 +373,12 @@ struct tuple : public object {
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_) {}
};
}

View File

@ -43,15 +43,14 @@ template<typename Visitor> struct slot_visitor {
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);
}
}

View File

@ -62,7 +62,7 @@ struct factor_vm
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;
@ -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);