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() { } 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) template<typename Strategy> void factor_vm::trace_handle(cell *handle, Strategy &strategy)
{ {
cell pointer = *handle; cell pointer = *handle;
@ -88,7 +26,7 @@ template<typename Strategy> void factor_vm::trace_handle(cell *handle, Strategy
object *obj = untag<object>(pointer); object *obj = untag<object>(pointer);
check_data_pointer(obj); check_data_pointer(obj);
if(strategy.should_copy_p(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); check_data_pointer(pointer);
if(strategy.should_copy_p(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 #ifdef FACTOR_DEBUG
assert((*handle)->h.hi_tag() == BIGNUM_TYPE); assert((*handle)->h.hi_tag() == BIGNUM_TYPE);
#endif #endif
@ -383,15 +321,18 @@ template<typename Strategy> struct literal_reference_tracer {
aging and nursery collections */ aging and nursery collections */
template<typename Strategy> void factor_vm::trace_code_heap_roots(Strategy &strategy) template<typename Strategy> void factor_vm::trace_code_heap_roots(Strategy &strategy)
{ {
literal_reference_tracer<Strategy> tracer(this,strategy); if(current_gc->collecting_gen >= last_code_heap_scan)
iterate_code_heap(tracer); {
literal_reference_tracer<Strategy> tracer(this,strategy);
iterate_code_heap(tracer);
if(current_gc->collecting_accumulation_gen_p()) if(current_gc->collecting_accumulation_gen_p())
last_code_heap_scan = current_gc->collecting_gen; last_code_heap_scan = current_gc->collecting_gen;
else else
last_code_heap_scan = current_gc->collecting_gen + 1; last_code_heap_scan = current_gc->collecting_gen + 1;
code_heap_scans++; code_heap_scans++;
}
} }
/* Mark all literals referenced from a word XT. Only for tenured /* 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); 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 { struct literal_and_word_reference_updater {
factor_vm *myvm; 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) bool should_copy_p(object *untagged)
{ {
if(myvm->current_gc->newspace->contains_p(untagged)) if(myvm->current_gc->newspace->contains_p(untagged))
@ -515,11 +520,10 @@ struct nursery_collector
else else
return myvm->nursery.contains_p(untagged); return myvm->nursery.contains_p(untagged);
} }
void copy_reachable_objects(cell scan, cell *end) void copy_reachable_objects(cell scan, cell *end)
{ {
while(scan < myvm->current_gc->newspace->here) while(scan < *end) scan = copy_next(scan);
scan = myvm->copy_next(scan,*this);
} }
}; };
@ -527,26 +531,18 @@ void factor_vm::collect_nursery()
{ {
nursery_collector collector(this); nursery_collector collector(this);
cell scan = current_gc->newspace->here;
trace_roots(collector); trace_roots(collector);
trace_contexts(collector); trace_contexts(collector);
trace_cards(collector); trace_cards(collector);
trace_code_heap_roots(collector);
if(current_gc->collecting_gen >= last_code_heap_scan) collector.go();
update_code_heap_roots(collector);
collector.copy_reachable_objects(scan,&current_gc->newspace->here);
update_dirty_code_blocks(); 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) bool should_copy_p(object *untagged)
{ {
if(myvm->current_gc->newspace->contains_p(untagged)) if(myvm->current_gc->newspace->contains_p(untagged))
@ -557,8 +553,7 @@ struct aging_collector
void copy_reachable_objects(cell scan, cell *end) void copy_reachable_objects(cell scan, cell *end)
{ {
while(scan < myvm->current_gc->newspace->here) while(scan < *end) scan = copy_next(scan);
scan = myvm->copy_next(scan,*this);
} }
}; };
@ -566,25 +561,17 @@ void factor_vm::collect_aging()
{ {
aging_collector collector(this); aging_collector collector(this);
cell scan = current_gc->newspace->here;
trace_roots(collector); trace_roots(collector);
trace_contexts(collector); trace_contexts(collector);
trace_cards(collector); trace_cards(collector);
trace_code_heap_roots(collector);
if(current_gc->collecting_gen >= last_code_heap_scan) collector.go();
update_code_heap_roots(collector);
collector.copy_reachable_objects(scan,&current_gc->newspace->here);
update_dirty_code_blocks(); update_dirty_code_blocks();
} }
struct tenured_collector struct tenured_collector : copying_collector<tenured_collector>
{ {
factor_vm *myvm; explicit tenured_collector(factor_vm *myvm_) : copying_collector<tenured_collector>(myvm_) {}
explicit tenured_collector(factor_vm *myvm_) : myvm(myvm_) {}
bool should_copy_p(object *untagged) bool should_copy_p(object *untagged)
{ {
@ -593,10 +580,10 @@ struct tenured_collector
void copy_reachable_objects(cell scan, cell *end) 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); 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); tenured_collector collector(this);
cell scan = current_gc->newspace->here;
trace_roots(collector); trace_roots(collector);
if(trace_contexts_) if(trace_contexts_) trace_contexts(collector);
trace_contexts(collector); collector.go();
collector.copy_reachable_objects(scan,&current_gc->newspace->here);
free_unmarked_code_blocks(); 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); 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) void factor_vm::init_inline_caching(int max_size)
{ {
max_pic_size = 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) void factor_vm::deallocate_inline_cache(cell return_address)

View File

@ -3,6 +3,13 @@
namespace factor 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; cell last_code_heap_scan;
void init_data_gc(); 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_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(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); 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 trace_code_heap_roots(Strategy &strategy);
template<typename Strategy> void mark_code_block(code_block *compiled, 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> 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 free_unmarked_code_blocks();
void update_dirty_code_blocks(); void update_dirty_code_blocks();
void begin_gc(cell requested_bytes); void begin_gc(cell requested_bytes);