vm: more GC refactoring

db4
Slava Pestov 2009-10-06 00:13:54 -05:00
parent bae2240f62
commit 47c735d81d
5 changed files with 155 additions and 155 deletions

View File

@ -17,68 +17,6 @@ gc_state::gc_state(data_heap *data_, bool growing_data_heap_, cell collecting_ge
gc_state::~gc_state() { }
/* Given a pointer to oldspace, copy it to newspace */
object *factor_vm::copy_untagged_object_impl(object *pointer, cell size)
{
if(current_gc->newspace->here + size >= current_gc->newspace->end)
longjmp(current_gc->gc_unwind,1);
object *newpointer = allot_zone(current_gc->newspace,size);
gc_stats *s = &stats[current_gc->collecting_gen];
s->object_count++;
s->bytes_copied += size;
memcpy(newpointer,pointer,size);
return newpointer;
}
object *factor_vm::copy_object_impl(object *untagged)
{
object *newpointer = copy_untagged_object_impl(untagged,untagged_object_size(untagged));
untagged->h.forward_to(newpointer);
return newpointer;
}
/* Follow a chain of forwarding pointers */
template<typename Strategy> object *factor_vm::resolve_forwarding(object *untagged, Strategy &strategy)
{
check_data_pointer(untagged);
/* is there another forwarding pointer? */
if(untagged->h.forwarding_pointer_p())
return resolve_forwarding(untagged->h.forwarding_pointer(),strategy);
/* we've found the destination */
else
{
untagged->h.check_header();
if(strategy.should_copy_p(untagged))
return copy_object_impl(untagged);
else
return untagged;
}
}
template<typename Type, typename Strategy> Type *factor_vm::copy_untagged_object(Type *untagged, Strategy &strategy)
{
check_data_pointer(untagged);
if(untagged->h.forwarding_pointer_p())
untagged = (Type *)resolve_forwarding(untagged->h.forwarding_pointer(),strategy);
else
{
untagged->h.check_header();
untagged = (Type *)copy_object_impl(untagged);
}
return untagged;
}
template<typename Strategy> cell factor_vm::copy_object(cell pointer, Strategy &strategy)
{
return RETAG(copy_untagged_object(untag<object>(pointer),strategy),TAG(pointer));
}
template<typename Strategy> void factor_vm::trace_handle(cell *handle, Strategy &strategy)
{
cell pointer = *handle;
@ -88,7 +26,7 @@ template<typename Strategy> void factor_vm::trace_handle(cell *handle, Strategy
object *obj = untag<object>(pointer);
check_data_pointer(obj);
if(strategy.should_copy_p(obj))
*handle = copy_object(pointer,strategy);
*handle = strategy.copy_object(pointer);
}
}
@ -247,7 +185,7 @@ template<typename Strategy> void factor_vm::trace_registered_bignums(Strategy &s
{
check_data_pointer(pointer);
if(strategy.should_copy_p(pointer))
*handle = copy_untagged_object(pointer,strategy);
*handle = untag<bignum>(strategy.copy_object(tag<bignum>(pointer)));
#ifdef FACTOR_DEBUG
assert((*handle)->h.hi_tag() == BIGNUM_TYPE);
#endif
@ -383,15 +321,18 @@ template<typename Strategy> struct literal_reference_tracer {
aging and nursery collections */
template<typename Strategy> void factor_vm::trace_code_heap_roots(Strategy &strategy)
{
literal_reference_tracer<Strategy> tracer(this,strategy);
iterate_code_heap(tracer);
if(current_gc->collecting_gen >= last_code_heap_scan)
{
literal_reference_tracer<Strategy> tracer(this,strategy);
iterate_code_heap(tracer);
if(current_gc->collecting_accumulation_gen_p())
last_code_heap_scan = current_gc->collecting_gen;
else
last_code_heap_scan = current_gc->collecting_gen + 1;
code_heap_scans++;
if(current_gc->collecting_accumulation_gen_p())
last_code_heap_scan = current_gc->collecting_gen;
else
last_code_heap_scan = current_gc->collecting_gen + 1;
code_heap_scans++;
}
}
/* Mark all literals referenced from a word XT. Only for tenured
@ -406,37 +347,6 @@ template<typename Strategy> void factor_vm::mark_code_block(code_block *compiled
trace_handle(&compiled->relocation,strategy);
}
template<typename Strategy> cell factor_vm::copy_next(cell scan, Strategy &strategy)
{
cell *obj = (cell *)scan;
cell *end = (cell *)(scan + binary_payload_start((object *)scan));
if(obj != end)
{
obj++;
for(; obj < end; obj++)
trace_handle(obj,strategy);
}
return scan + untagged_object_size((object *)scan);
}
template<typename Strategy> void factor_vm::update_code_heap_roots(Strategy &strategy)
{
if(current_gc->collecting_gen >= last_code_heap_scan)
{
code_heap_scans++;
trace_code_heap_roots(strategy);
if(current_gc->collecting_accumulation_gen_p())
last_code_heap_scan = current_gc->collecting_gen;
else
last_code_heap_scan = current_gc->collecting_gen + 1;
}
}
struct literal_and_word_reference_updater {
factor_vm *myvm;
@ -502,12 +412,107 @@ void factor_vm::begin_gc(cell requested_bytes)
}
}
struct nursery_collector
template<typename Strategy>
copying_collector<Strategy>::copying_collector(factor_vm *myvm_)
: myvm(myvm_), current_gc(myvm_->current_gc)
{
factor_vm *myvm;
scan = current_gc->newspace->here;
}
template<typename Strategy> Strategy &copying_collector<Strategy>::strategy()
{
return static_cast<Strategy &>(*this);
}
/* Given a pointer to oldspace, copy it to newspace */
template<typename Strategy> object *copying_collector<Strategy>::copy_untagged_object_impl(object *pointer, cell size)
{
if(current_gc->newspace->here + size >= current_gc->newspace->end)
longjmp(current_gc->gc_unwind,1);
object *newpointer = myvm->allot_zone(current_gc->newspace,size);
gc_stats *s = &myvm->stats[current_gc->collecting_gen];
s->object_count++;
s->bytes_copied += size;
memcpy(newpointer,pointer,size);
return newpointer;
}
template<typename Strategy> object *copying_collector<Strategy>::copy_object_impl(object *untagged)
{
object *newpointer = copy_untagged_object_impl(untagged,myvm->untagged_object_size(untagged));
untagged->h.forward_to(newpointer);
return newpointer;
}
/* Follow a chain of forwarding pointers */
template<typename Strategy> object *copying_collector<Strategy>::resolve_forwarding(object *untagged)
{
myvm->check_data_pointer(untagged);
/* is there another forwarding pointer? */
if(untagged->h.forwarding_pointer_p())
return resolve_forwarding(untagged->h.forwarding_pointer());
/* we've found the destination */
else
{
untagged->h.check_header();
if(should_copy_p(untagged))
return copy_object_impl(untagged);
else
return untagged;
}
}
template<typename Strategy> cell copying_collector<Strategy>::copy_object(cell pointer)
{
object *untagged = myvm->untag<object>(pointer);
myvm->check_data_pointer(untagged);
if(untagged->h.forwarding_pointer_p())
untagged = resolve_forwarding(untagged->h.forwarding_pointer());
else
{
untagged->h.check_header();
untagged = copy_object_impl(untagged);
}
return RETAG(untagged,TAG(pointer));
}
template<typename Strategy> bool copying_collector<Strategy>::should_copy_p(object *pointer)
{
return strategy().should_copy_p(pointer);
}
template<typename Strategy> cell copying_collector<Strategy>::copy_next(cell scan)
{
cell *obj = (cell *)scan;
cell *end = (cell *)(scan + myvm->binary_payload_start((object *)scan));
if(obj != end)
{
obj++;
for(; obj < end; obj++)
myvm->trace_handle(obj,strategy());
}
return scan + myvm->untagged_object_size((object *)scan);
}
template<typename Strategy> void copying_collector<Strategy>::go()
{
strategy().copy_reachable_objects(scan,&current_gc->newspace->here);
}
struct nursery_collector : copying_collector<nursery_collector>
{
explicit nursery_collector(factor_vm *myvm_) : copying_collector<nursery_collector>(myvm_) {}
explicit nursery_collector(factor_vm *myvm_) : myvm(myvm_) {}
bool should_copy_p(object *untagged)
{
if(myvm->current_gc->newspace->contains_p(untagged))
@ -515,11 +520,10 @@ struct nursery_collector
else
return myvm->nursery.contains_p(untagged);
}
void copy_reachable_objects(cell scan, cell *end)
{
while(scan < myvm->current_gc->newspace->here)
scan = myvm->copy_next(scan,*this);
while(scan < *end) scan = copy_next(scan);
}
};
@ -527,26 +531,18 @@ void factor_vm::collect_nursery()
{
nursery_collector collector(this);
cell scan = current_gc->newspace->here;
trace_roots(collector);
trace_contexts(collector);
trace_cards(collector);
if(current_gc->collecting_gen >= last_code_heap_scan)
update_code_heap_roots(collector);
collector.copy_reachable_objects(scan,&current_gc->newspace->here);
trace_code_heap_roots(collector);
collector.go();
update_dirty_code_blocks();
}
struct aging_collector
struct aging_collector : copying_collector<aging_collector>
{
factor_vm *myvm;
explicit aging_collector(factor_vm *myvm_) : copying_collector<aging_collector>(myvm_) {}
explicit aging_collector(factor_vm *myvm_) : myvm(myvm_) {}
bool should_copy_p(object *untagged)
{
if(myvm->current_gc->newspace->contains_p(untagged))
@ -557,8 +553,7 @@ struct aging_collector
void copy_reachable_objects(cell scan, cell *end)
{
while(scan < myvm->current_gc->newspace->here)
scan = myvm->copy_next(scan,*this);
while(scan < *end) scan = copy_next(scan);
}
};
@ -566,25 +561,17 @@ void factor_vm::collect_aging()
{
aging_collector collector(this);
cell scan = current_gc->newspace->here;
trace_roots(collector);
trace_contexts(collector);
trace_cards(collector);
if(current_gc->collecting_gen >= last_code_heap_scan)
update_code_heap_roots(collector);
collector.copy_reachable_objects(scan,&current_gc->newspace->here);
trace_code_heap_roots(collector);
collector.go();
update_dirty_code_blocks();
}
struct tenured_collector
struct tenured_collector : copying_collector<tenured_collector>
{
factor_vm *myvm;
explicit tenured_collector(factor_vm *myvm_) : myvm(myvm_) {}
explicit tenured_collector(factor_vm *myvm_) : copying_collector<tenured_collector>(myvm_) {}
bool should_copy_p(object *untagged)
{
@ -593,10 +580,10 @@ struct tenured_collector
void copy_reachable_objects(cell scan, cell *end)
{
while(scan < myvm->current_gc->newspace->here)
while(scan < *end)
{
myvm->mark_object_code_block(myvm->untag<object>(scan),*this);
scan = myvm->copy_next(scan,*this);
scan = copy_next(scan);
}
}
};
@ -605,14 +592,9 @@ void factor_vm::collect_tenured(bool trace_contexts_)
{
tenured_collector collector(this);
cell scan = current_gc->newspace->here;
trace_roots(collector);
if(trace_contexts_)
trace_contexts(collector);
collector.copy_reachable_objects(scan,&current_gc->newspace->here);
if(trace_contexts_) trace_contexts(collector);
collector.go();
free_unmarked_code_blocks();
}

View File

@ -63,6 +63,22 @@ struct gc_state {
}
};
template<typename Strategy> struct copying_collector {
factor_vm *myvm;
gc_state *current_gc;
cell scan;
explicit copying_collector(factor_vm *myvm_);
Strategy &strategy();
object *copy_untagged_object_impl(object *pointer, cell size);
cell copy_next(cell scan);
object *copy_object_impl(object *untagged);
object *resolve_forwarding(object *untagged);
cell copy_object(cell pointer);
bool should_copy_p(object *pointer);
void go();
};
VM_C_API void inline_gc(cell *gc_roots_base, cell gc_roots_size, factor_vm *myvm);
}

View File

@ -6,6 +6,10 @@ namespace factor
void factor_vm::init_inline_caching(int max_size)
{
max_pic_size = max_size;
cold_call_to_ic_transitions = 0;
ic_to_pic_transitions = 0;
pic_to_mega_transitions = 0;
for(int i = 0; i < 4; i++) pic_counts[i] = 0;
}
void factor_vm::deallocate_inline_cache(cell return_address)

View File

@ -3,6 +3,13 @@
namespace factor
{
factor_vm::factor_vm() { }
factor_vm::factor_vm() :
profiling_p(false),
secure_gc(false),
gc_off(false),
current_gc(NULL),
fep_disabled(false),
full_output(false)
{ }
}

View File

@ -243,13 +243,6 @@ struct factor_vm
cell last_code_heap_scan;
void init_data_gc();
object *copy_untagged_object_impl(object *pointer, cell size);
object *copy_object_impl(object *untagged);
object *resolve_forwarding(object *untagged);
template<typename Type> Type *copy_untagged_object(Type *untagged);
template<typename Strategy> object *resolve_forwarding(object *untagged, Strategy &strategy);
template<typename Type, typename Strategy> Type *copy_untagged_object(Type *untagged, Strategy &strategy);
template<typename Strategy> cell copy_object(cell pointer, Strategy &strategy);
template<typename Strategy> void trace_handle(cell *handle, Strategy &strategy);
template<typename Strategy> void trace_card(card *ptr, cell gen, cell here, Strategy &strategy);
template<typename Strategy> void trace_card_deck(card_deck *deck, cell gen, card mask, card unmask, Strategy &strategy);
@ -265,8 +258,6 @@ struct factor_vm
template<typename Strategy> void trace_code_heap_roots(Strategy &strategy);
template<typename Strategy> void mark_code_block(code_block *compiled, Strategy &strategy);
template<typename Strategy> void mark_object_code_block(object *object, Strategy &strategy);
template<typename Strategy> cell copy_next(cell scan, Strategy &strategy);
template<typename Strategy> void update_code_heap_roots(Strategy &strategy);
void free_unmarked_code_blocks();
void update_dirty_code_blocks();
void begin_gc(cell requested_bytes);