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()
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue