VM: use an std::vector instead of a fixed-size buffer for GC roots
parent
8b6ec8e030
commit
81c4670619
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue