VM: use an std::vector instead of a fixed-size buffer for GC roots

db4
Slava Pestov 2009-09-08 14:21:09 -05:00
parent 8b6ec8e030
commit 81c4670619
6 changed files with 28 additions and 36 deletions

View File

@ -266,19 +266,21 @@ static void copy_stack_elements(segment *region, cell top)
static void copy_registered_locals()
{
cell scan = gc_locals_region->start;
std::vector<cell>::const_iterator iter = gc_locals.begin();
std::vector<cell>::const_iterator end = gc_locals.end();
for(; scan <= gc_locals; scan += sizeof(cell))
copy_handle(*(cell **)scan);
for(; iter < end; iter++)
copy_handle((cell *)(*iter));
}
static void copy_registered_bignums()
{
cell scan = gc_bignums_region->start;
std::vector<cell>::const_iterator iter = gc_bignums.begin();
std::vector<cell>::const_iterator end = gc_bignums.end();
for(; scan <= gc_bignums; scan += sizeof(cell))
for(; iter < end; iter++)
{
bignum **handle = *(bignum ***)scan;
bignum **handle = (bignum **)(*iter);
bignum *pointer = *handle;
if(pointer)
@ -683,12 +685,12 @@ PRIMITIVE(become)
VM_ASM_API void inline_gc(cell *gc_roots_base, cell gc_roots_size)
{
for(cell i = 0; i < gc_roots_size; i++)
gc_local_push((cell)&gc_roots_base[i]);
gc_locals.push_back((cell)&gc_roots_base[i]);
garbage_collection(data->nursery(),false,0);
for(cell i = 0; i < gc_roots_size; i++)
gc_local_pop();
gc_locals.pop_back();
}
}

View File

@ -183,15 +183,7 @@ void init_data_heap(cell gens,
bool secure_gc_)
{
set_data_heap(alloc_data_heap(gens,young_size,aging_size,tenured_size));
gc_locals_region = alloc_segment(getpagesize());
gc_locals = gc_locals_region->start - sizeof(cell);
gc_bignums_region = alloc_segment(getpagesize());
gc_bignums = gc_bignums_region->start - sizeof(cell);
secure_gc = secure_gc_;
init_data_gc();
}

View File

@ -41,8 +41,8 @@ void throw_error(cell error, stack_frame *callstack_top)
gc_off = false;
/* Reset local roots */
gc_locals = gc_locals_region->start - sizeof(cell);
gc_bignums = gc_bignums_region->start - sizeof(cell);
gc_locals.clear();
gc_bignums.clear();
/* If we had an underflow or overflow, stack pointers might be
out of bounds */

View File

@ -3,10 +3,8 @@
namespace factor
{
segment *gc_locals_region;
cell gc_locals;
std::vector<cell> gc_locals;
segment *gc_bignums_region;
cell gc_bignums;
std::vector<cell> gc_bignums;
}

View File

@ -4,15 +4,12 @@ namespace factor
/* 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 */
extern segment *gc_locals_region;
extern cell gc_locals;
DEFPUSHPOP(gc_local_,gc_locals)
extern std::vector<cell> gc_locals;
template <typename T>
struct gc_root : public tagged<T>
{
void push() { check_tagged_pointer(tagged<T>::value()); gc_local_push((cell)this); }
void push() { check_tagged_pointer(tagged<T>::value()); gc_locals.push_back((cell)this); }
explicit gc_root(cell value_) : tagged<T>(value_) { push(); }
explicit gc_root(T *value_) : tagged<T>(value_) { push(); }
@ -22,19 +19,15 @@ struct gc_root : public tagged<T>
~gc_root() {
#ifdef FACTOR_DEBUG
cell old = gc_local_pop();
assert(old == (cell)this);
assert(gc_locals.back() == (cell)this);
#else
gc_local_pop();
gc_locals.pop_back();
#endif
}
};
/* A similar hack for the bignum implementation */
extern segment *gc_bignums_region;
extern cell gc_bignums;
DEFPUSHPOP(gc_bignum_,gc_bignums)
extern std::vector<cell> gc_bignums;
struct gc_bignum
{
@ -43,10 +36,15 @@ struct gc_bignum
gc_bignum(bignum **addr_) : addr(addr_) {
if(*addr_)
check_data_pointer(*addr_);
gc_bignum_push((cell)addr);
gc_bignums.push_back((cell)addr);
}
~gc_bignum() { assert((cell)addr == gc_bignum_pop()); }
~gc_bignum() {
#ifdef FACTOR_DEBUG
assert(gc_bignums.back() == (cell)addr);
#endif
gc_bignums.pop_back();
}
};
#define GC_BIGNUM(x) gc_bignum x##__gc_root(&x)

View File

@ -21,6 +21,8 @@
#include <time.h>
/* C++ headers */
#include <vector>
#if __GNUC__ == 4
#include <tr1/unordered_map>
#define unordered_map std::tr1::unordered_map