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() 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)) for(; iter < end; iter++)
copy_handle(*(cell **)scan); copy_handle((cell *)(*iter));
} }
static void copy_registered_bignums() 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; bignum *pointer = *handle;
if(pointer) if(pointer)
@ -683,12 +685,12 @@ PRIMITIVE(become)
VM_ASM_API void inline_gc(cell *gc_roots_base, cell gc_roots_size) VM_ASM_API void inline_gc(cell *gc_roots_base, cell gc_roots_size)
{ {
for(cell i = 0; i < gc_roots_size; i++) 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); garbage_collection(data->nursery(),false,0);
for(cell i = 0; i < gc_roots_size; i++) 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_) bool secure_gc_)
{ {
set_data_heap(alloc_data_heap(gens,young_size,aging_size,tenured_size)); 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_; secure_gc = secure_gc_;
init_data_gc(); init_data_gc();
} }

View File

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

View File

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

View File

@ -4,15 +4,12 @@ namespace factor
/* If a runtime function needs to call another function which potentially /* If a runtime function needs to call another function which potentially
allocates memory, it must wrap any local variable references to Factor allocates memory, it must wrap any local variable references to Factor
objects in gc_root instances */ objects in gc_root instances */
extern segment *gc_locals_region; extern std::vector<cell> gc_locals;
extern cell gc_locals;
DEFPUSHPOP(gc_local_,gc_locals)
template <typename T> template <typename T>
struct gc_root : public tagged<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(cell value_) : tagged<T>(value_) { push(); }
explicit gc_root(T *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() { ~gc_root() {
#ifdef FACTOR_DEBUG #ifdef FACTOR_DEBUG
cell old = gc_local_pop(); assert(gc_locals.back() == (cell)this);
assert(old == (cell)this);
#else #else
gc_local_pop(); gc_locals.pop_back();
#endif #endif
} }
}; };
/* A similar hack for the bignum implementation */ /* A similar hack for the bignum implementation */
extern segment *gc_bignums_region; extern std::vector<cell> gc_bignums;
extern cell gc_bignums;
DEFPUSHPOP(gc_bignum_,gc_bignums)
struct gc_bignum struct gc_bignum
{ {
@ -43,10 +36,15 @@ struct gc_bignum
gc_bignum(bignum **addr_) : addr(addr_) { gc_bignum(bignum **addr_) : addr(addr_) {
if(*addr_) if(*addr_)
check_data_pointer(*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) #define GC_BIGNUM(x) gc_bignum x##__gc_root(&x)

View File

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