moved data_gc and local_roots inline functions to vm.hpp

db4
Phil Dawes 2009-08-17 21:37:11 +01:00
parent 31905b68a7
commit 4dabd186c9
4 changed files with 176 additions and 175 deletions

View File

@ -22,19 +22,6 @@ void init_data_gc();
void gc(); void gc();
inline bool factorvm::collecting_accumulation_gen_p()
{
return ((data->have_aging_p()
&& collecting_gen == data->aging()
&& !collecting_aging_again)
|| collecting_gen == data->tenured());
}
inline bool collecting_accumulation_gen_p()
{
return vm->collecting_accumulation_gen_p();
}
void copy_handle(cell *handle); void copy_handle(cell *handle);
void garbage_collection(volatile cell gen, void garbage_collection(volatile cell gen,
@ -46,90 +33,6 @@ allocation (which does not call GC because of possible roots in volatile
registers) does not run out of memory */ registers) does not run out of memory */
static const cell allot_buffer_zone = 1024; static const cell allot_buffer_zone = 1024;
inline object *factorvm::allot_zone(zone *z, cell a)
{
cell h = z->here;
z->here = h + align8(a);
object *obj = (object *)h;
allot_barrier(obj);
return obj;
}
inline object *allot_zone(zone *z, cell a)
{
return vm->allot_zone(z,a);
}
/*
* It is up to the caller to fill in the object's fields in a meaningful
* fashion!
*/
inline object *factorvm::allot_object(header header, cell size)
{
#ifdef GC_DEBUG
if(!gc_off)
gc();
#endif
object *obj;
if(nursery.size - allot_buffer_zone > size)
{
/* If there is insufficient room, collect the nursery */
if(nursery.here + allot_buffer_zone + size > nursery.end)
garbage_collection(data->nursery(),false,0);
cell h = nursery.here;
nursery.here = h + align8(size);
obj = (object *)h;
}
/* If the object is bigger than the nursery, allocate it in
tenured space */
else
{
zone *tenured = &data->generations[data->tenured()];
/* If tenured space does not have enough room, collect */
if(tenured->here + size > tenured->end)
{
gc();
tenured = &data->generations[data->tenured()];
}
/* If it still won't fit, grow the heap */
if(tenured->here + size > tenured->end)
{
garbage_collection(data->tenured(),true,size);
tenured = &data->generations[data->tenured()];
}
obj = allot_zone(tenured,size);
/* Allows initialization code to store old->new pointers
without hitting the write barrier in the common case of
a nursery allocation */
write_barrier(obj);
}
obj->h = header;
return obj;
}
inline object *allot_object(header header, cell size)
{
return vm->allot_object(header,size);
}
template<typename TYPE> TYPE *factorvm::allot(cell size)
{
return (TYPE *)allot_object(header(TYPE::type_number),size);
}
template<typename TYPE> TYPE *allot(cell size)
{
return vm->allot<TYPE>(size);
}
void copy_reachable_objects(cell scan, cell *end); void copy_reachable_objects(cell scan, cell *end);
PRIMITIVE(gc); PRIMITIVE(gc);
@ -140,38 +43,6 @@ PRIMITIVE(become);
extern bool growing_data_heap; extern bool growing_data_heap;
inline void factorvm::check_data_pointer(object *pointer)
{
#ifdef FACTOR_DEBUG
if(!growing_data_heap)
{
assert((cell)pointer >= data->seg->start
&& (cell)pointer < data->seg->end);
}
#endif
}
inline void check_data_pointer(object *pointer)
{
return vm->check_data_pointer(pointer);
}
inline void factorvm::check_tagged_pointer(cell tagged)
{
#ifdef FACTOR_DEBUG
if(!immediate_p(tagged))
{
object *obj = untag<object>(tagged);
check_data_pointer(obj);
obj->h.hi_tag();
}
#endif
}
inline void check_tagged_pointer(cell tagged)
{
return vm->check_tagged_pointer(tagged);
}
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);

View File

@ -1,49 +1,4 @@
namespace factor namespace factor
{ {
struct factorvm;
template <typename TYPE>
struct gc_root : public tagged<TYPE>
{
factorvm *myvm;
void push() { check_tagged_pointer(tagged<TYPE>::value()); myvm->gc_locals.push_back((cell)this); }
//explicit gc_root(cell value_, factorvm *vm) : myvm(vm),tagged<TYPE>(value_) { push(); }
explicit gc_root(cell value_,factorvm *vm) : tagged<TYPE>(value_),myvm(vm) { push(); }
explicit gc_root(TYPE *value_, factorvm *vm) : tagged<TYPE>(value_),myvm(vm) { push(); }
const gc_root<TYPE>& operator=(const TYPE *x) { tagged<TYPE>::operator=(x); return *this; }
const gc_root<TYPE>& operator=(const cell &x) { tagged<TYPE>::operator=(x); return *this; }
~gc_root() {
#ifdef FACTOR_DEBUG
assert(myvm->gc_locals.back() == (cell)this);
#endif
myvm->gc_locals.pop_back();
}
};
/* A similar hack for the bignum implementation */
struct gc_bignum
{
bignum **addr;
factorvm *myvm;
gc_bignum(bignum **addr_, factorvm *vm) : addr(addr_), myvm(vm) {
if(*addr_)
check_data_pointer(*addr_);
myvm->gc_bignums.push_back((cell)addr);
}
~gc_bignum() {
#ifdef FACTOR_DEBUG
assert(myvm->gc_bignums.back() == (cell)addr);
#endif
myvm->gc_bignums.pop_back();
}
};
#define GC_BIGNUM(x,vm) gc_bignum x##__gc_root(&x,vm)
} }

View File

@ -49,9 +49,9 @@
#include "code_block.hpp" #include "code_block.hpp"
#include "data_heap.hpp" #include "data_heap.hpp"
#include "write_barrier.hpp" #include "write_barrier.hpp"
#include "vm.hpp"
#include "data_gc.hpp" #include "data_gc.hpp"
#include "local_roots.hpp" #include "local_roots.hpp"
#include "vm.hpp"
#include "generic_arrays.hpp" #include "generic_arrays.hpp"
#include "debug.hpp" #include "debug.hpp"
#include "arrays.hpp" #include "arrays.hpp"

175
vm/vm.hpp
View File

@ -678,6 +678,181 @@ inline void allot_barrier(object *address)
return vm->allot_barrier(address); return vm->allot_barrier(address);
} }
//data_gc.hpp
inline bool factorvm::collecting_accumulation_gen_p()
{
return ((data->have_aging_p()
&& collecting_gen == data->aging()
&& !collecting_aging_again)
|| collecting_gen == data->tenured());
}
inline bool collecting_accumulation_gen_p()
{
return vm->collecting_accumulation_gen_p();
}
inline object *factorvm::allot_zone(zone *z, cell a)
{
cell h = z->here;
z->here = h + align8(a);
object *obj = (object *)h;
allot_barrier(obj);
return obj;
}
inline object *allot_zone(zone *z, cell a)
{
return vm->allot_zone(z,a);
}
/*
* It is up to the caller to fill in the object's fields in a meaningful
* fashion!
*/
inline object *factorvm::allot_object(header header, cell size)
{
#ifdef GC_DEBUG
if(!gc_off)
gc();
#endif
object *obj;
if(nursery.size - allot_buffer_zone > size)
{
/* If there is insufficient room, collect the nursery */
if(nursery.here + allot_buffer_zone + size > nursery.end)
garbage_collection(data->nursery(),false,0);
cell h = nursery.here;
nursery.here = h + align8(size);
obj = (object *)h;
}
/* If the object is bigger than the nursery, allocate it in
tenured space */
else
{
zone *tenured = &data->generations[data->tenured()];
/* If tenured space does not have enough room, collect */
if(tenured->here + size > tenured->end)
{
gc();
tenured = &data->generations[data->tenured()];
}
/* If it still won't fit, grow the heap */
if(tenured->here + size > tenured->end)
{
garbage_collection(data->tenured(),true,size);
tenured = &data->generations[data->tenured()];
}
obj = allot_zone(tenured,size);
/* Allows initialization code to store old->new pointers
without hitting the write barrier in the common case of
a nursery allocation */
write_barrier(obj);
}
obj->h = header;
return obj;
}
inline object *allot_object(header header, cell size)
{
return vm->allot_object(header,size);
}
template<typename TYPE> TYPE *factorvm::allot(cell size)
{
return (TYPE *)allot_object(header(TYPE::type_number),size);
}
template<typename TYPE> TYPE *allot(cell size)
{
return vm->allot<TYPE>(size);
}
inline void factorvm::check_data_pointer(object *pointer)
{
#ifdef FACTOR_DEBUG
if(!growing_data_heap)
{
assert((cell)pointer >= data->seg->start
&& (cell)pointer < data->seg->end);
}
#endif
}
inline void check_data_pointer(object *pointer)
{
return vm->check_data_pointer(pointer);
}
inline void factorvm::check_tagged_pointer(cell tagged)
{
#ifdef FACTOR_DEBUG
if(!immediate_p(tagged))
{
object *obj = untag<object>(tagged);
check_data_pointer(obj);
obj->h.hi_tag();
}
#endif
}
inline void check_tagged_pointer(cell tagged)
{
return vm->check_tagged_pointer(tagged);
}
//local_roots.hpp
template <typename TYPE>
struct gc_root : public tagged<TYPE>
{
factorvm *myvm;
void push() { check_tagged_pointer(tagged<TYPE>::value()); myvm->gc_locals.push_back((cell)this); }
//explicit gc_root(cell value_, factorvm *vm) : myvm(vm),tagged<TYPE>(value_) { push(); }
explicit gc_root(cell value_,factorvm *vm) : tagged<TYPE>(value_),myvm(vm) { push(); }
explicit gc_root(TYPE *value_, factorvm *vm) : tagged<TYPE>(value_),myvm(vm) { push(); }
const gc_root<TYPE>& operator=(const TYPE *x) { tagged<TYPE>::operator=(x); return *this; }
const gc_root<TYPE>& operator=(const cell &x) { tagged<TYPE>::operator=(x); return *this; }
~gc_root() {
#ifdef FACTOR_DEBUG
assert(myvm->gc_locals.back() == (cell)this);
#endif
myvm->gc_locals.pop_back();
}
};
/* A similar hack for the bignum implementation */
struct gc_bignum
{
bignum **addr;
factorvm *myvm;
gc_bignum(bignum **addr_, factorvm *vm) : addr(addr_), myvm(vm) {
if(*addr_)
check_data_pointer(*addr_);
myvm->gc_bignums.push_back((cell)addr);
}
~gc_bignum() {
#ifdef FACTOR_DEBUG
assert(myvm->gc_bignums.back() == (cell)addr);
#endif
myvm->gc_bignums.pop_back();
}
};
#define GC_BIGNUM(x,vm) gc_bignum x##__gc_root(&x,vm)
// next method here: // next method here: