From 81c46706195b89c278009c4511a47daf45203bbc Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 8 Sep 2009 14:21:09 -0500 Subject: [PATCH] VM: use an std::vector instead of a fixed-size buffer for GC roots --- vm/data_gc.cpp | 18 ++++++++++-------- vm/data_heap.cpp | 8 -------- vm/errors.cpp | 4 ++-- vm/local_roots.cpp | 6 ++---- vm/local_roots.hpp | 26 ++++++++++++-------------- vm/master.hpp | 2 ++ 6 files changed, 28 insertions(+), 36 deletions(-) diff --git a/vm/data_gc.cpp b/vm/data_gc.cpp index a075cd0eb1..458a437e37 100644 --- a/vm/data_gc.cpp +++ b/vm/data_gc.cpp @@ -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::const_iterator iter = gc_locals.begin(); + std::vector::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::const_iterator iter = gc_bignums.begin(); + std::vector::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(); } } diff --git a/vm/data_heap.cpp b/vm/data_heap.cpp index 5b20ec890f..5c1c8079c7 100644 --- a/vm/data_heap.cpp +++ b/vm/data_heap.cpp @@ -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(); } diff --git a/vm/errors.cpp b/vm/errors.cpp index 610482f576..410886e88a 100644 --- a/vm/errors.cpp +++ b/vm/errors.cpp @@ -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 */ diff --git a/vm/local_roots.cpp b/vm/local_roots.cpp index 717beb32c7..7e1b2da76a 100644 --- a/vm/local_roots.cpp +++ b/vm/local_roots.cpp @@ -3,10 +3,8 @@ namespace factor { -segment *gc_locals_region; -cell gc_locals; +std::vector gc_locals; -segment *gc_bignums_region; -cell gc_bignums; +std::vector gc_bignums; } diff --git a/vm/local_roots.hpp b/vm/local_roots.hpp index 4cee1c8e09..3526b95876 100644 --- a/vm/local_roots.hpp +++ b/vm/local_roots.hpp @@ -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 gc_locals; template struct gc_root : public tagged { - void push() { check_tagged_pointer(tagged::value()); gc_local_push((cell)this); } + void push() { check_tagged_pointer(tagged::value()); gc_locals.push_back((cell)this); } explicit gc_root(cell value_) : tagged(value_) { push(); } explicit gc_root(T *value_) : tagged(value_) { push(); } @@ -22,19 +19,15 @@ struct gc_root : public tagged ~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 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) diff --git a/vm/master.hpp b/vm/master.hpp index 83f0920f5b..9d84c8b75c 100644 --- a/vm/master.hpp +++ b/vm/master.hpp @@ -21,6 +21,8 @@ #include /* C++ headers */ +#include + #if __GNUC__ == 4 #include #define unordered_map std::tr1::unordered_map