vm: during an aging collection, promote objects referenced from tenured directly to tenured

db4
Slava Pestov 2009-10-14 06:03:52 -05:00
parent 6343f0d722
commit 1796688acd
3 changed files with 33 additions and 58 deletions

View File

@ -8,6 +8,14 @@ aging_collector::aging_collector(factor_vm *myvm_) :
(myvm_,myvm_->data->aging,aging_policy(myvm_)) {} (myvm_,myvm_->data->aging,aging_policy(myvm_)) {}
void factor_vm::collect_aging() void factor_vm::collect_aging()
{
{
to_tenured_collector collector(this);
collector.trace_cards(data->tenured,
card_points_to_aging,
simple_unmarker(card_mark_mask));
collector.cheneys_algorithm();
}
{ {
std::swap(data->aging,data->aging_semispace); std::swap(data->aging,data->aging_semispace);
reset_generation(data->aging); reset_generation(data->aging);
@ -16,9 +24,6 @@ void factor_vm::collect_aging()
collector.trace_roots(); collector.trace_roots();
collector.trace_contexts(); collector.trace_contexts();
collector.trace_cards(data->tenured,
card_points_to_aging,
complex_unmarker(card_mark_mask,card_points_to_nursery));
collector.trace_code_heap_roots(&code->points_to_aging); collector.trace_code_heap_roots(&code->points_to_aging);
collector.cheneys_algorithm(); collector.cheneys_algorithm();
update_dirty_code_blocks(&code->points_to_aging); update_dirty_code_blocks(&code->points_to_aging);
@ -26,5 +31,6 @@ void factor_vm::collect_aging()
nursery.here = nursery.start; nursery.here = nursery.start;
code->points_to_nursery.clear(); code->points_to_nursery.clear();
} }
}
} }

View File

@ -30,15 +30,15 @@ template<typename TargetGeneration, typename Policy> struct collector {
return untagged; return untagged;
} }
bool trace_handle(cell *handle) void trace_handle(cell *handle)
{ {
cell pointer = *handle; cell pointer = *handle;
if(immediate_p(pointer)) return false; if(immediate_p(pointer)) return;
object *untagged = myvm->untag<object>(pointer); object *untagged = myvm->untag<object>(pointer);
if(!policy.should_copy_p(untagged)) if(!policy.should_copy_p(untagged))
return false; return;
object *forwarding = resolve_forwarding(untagged); object *forwarding = resolve_forwarding(untagged);
@ -50,24 +50,18 @@ template<typename TargetGeneration, typename Policy> struct collector {
untagged = forwarding; untagged = forwarding;
*handle = RETAG(untagged,TAG(pointer)); *handle = RETAG(untagged,TAG(pointer));
return true;
} }
bool trace_slots(object *ptr) void trace_slots(object *ptr)
{ {
cell *slot = (cell *)ptr; cell *slot = (cell *)ptr;
cell *end = (cell *)((cell)ptr + myvm->binary_payload_start(ptr)); cell *end = (cell *)((cell)ptr + myvm->binary_payload_start(ptr));
bool copied = false;
if(slot != end) if(slot != end)
{ {
slot++; slot++;
for(; slot < end; slot++) copied |= trace_handle(slot); for(; slot < end; slot++) trace_handle(slot);
} }
return copied;
} }
object *promote_object(object *untagged) object *promote_object(object *untagged)

View File

@ -2,24 +2,13 @@ namespace factor
{ {
struct dummy_unmarker { struct dummy_unmarker {
void operator()(bool result, card *ptr) {} void operator()(card *ptr) {}
}; };
struct simple_unmarker { struct simple_unmarker {
card unmask; card unmask;
simple_unmarker(card unmask_) : unmask(unmask_) {} simple_unmarker(card unmask_) : unmask(unmask_) {}
void operator()(bool result, card *ptr) { *ptr &= ~unmask; } void operator()(card *ptr) { *ptr &= ~unmask; }
};
struct complex_unmarker {
card unmask_none, unmask_some;
complex_unmarker(card unmask_none_, card unmask_some_) :
unmask_none(unmask_none_), unmask_some(unmask_some_) {}
void operator()(bool result, card *ptr)
{
*ptr &= (result ? ~unmask_some : ~unmask_none);
}
}; };
template<typename TargetGeneration, typename Policy> template<typename TargetGeneration, typename Policy>
@ -59,10 +48,8 @@ struct copying_collector : collector<TargetGeneration,Policy> {
return ((card + 1) << card_bits) + this->data->start; return ((card + 1) << card_bits) + this->data->start;
} }
bool trace_partial_objects(cell start, cell end, cell card_start, cell card_end) void trace_partial_objects(cell start, cell end, cell card_start, cell card_end)
{ {
bool copied = false;
if(card_start < end) if(card_start < end)
{ {
start += sizeof(cell); start += sizeof(cell);
@ -76,11 +63,9 @@ struct copying_collector : collector<TargetGeneration,Policy> {
if(slot_ptr != end_ptr) if(slot_ptr != end_ptr)
{ {
for(; slot_ptr < end_ptr; slot_ptr++) for(; slot_ptr < end_ptr; slot_ptr++)
copied |= this->trace_handle(slot_ptr); this->trace_handle(slot_ptr);
} }
} }
return copied;
} }
template<typename SourceGeneration, typename Unmarker> template<typename SourceGeneration, typename Unmarker>
@ -107,8 +92,6 @@ struct copying_collector : collector<TargetGeneration,Policy> {
cell first_card = first_card_in_deck(deck_index); cell first_card = first_card_in_deck(deck_index);
cell last_card = last_card_in_deck(deck_index); cell last_card = last_card_in_deck(deck_index);
bool deck_dirty = false;
for(cell card_index = first_card; card_index < last_card; card_index++) for(cell card_index = first_card; card_index < last_card; card_index++)
{ {
if(cards[card_index] & mask) if(cards[card_index] & mask)
@ -122,15 +105,13 @@ struct copying_collector : collector<TargetGeneration,Policy> {
end = start + this->myvm->untagged_object_size((object *)start); end = start + this->myvm->untagged_object_size((object *)start);
} }
bool card_dirty = false;
#ifdef FACTOR_DEBUG #ifdef FACTOR_DEBUG
assert(addr_to_card(start - this->data->start) <= card_index); assert(addr_to_card(start - this->data->start) <= card_index);
assert(start < card_end_address(card_index)); assert(start < card_end_address(card_index));
#endif #endif
scan_next_object: { scan_next_object: {
card_dirty |= trace_partial_objects( trace_partial_objects(
start, start,
binary_start, binary_start,
card_start_address(card_index), card_start_address(card_index),
@ -147,15 +128,13 @@ scan_next_object: {
} }
} }
unmarker(card_dirty,&cards[card_index]); unmarker(&cards[card_index]);
deck_dirty |= card_dirty;
if(!start) goto end; if(!start) goto end;
} }
} }
unmarker(deck_dirty,&decks[deck_index]); unmarker(&decks[deck_index]);
} }
} }
@ -180,17 +159,13 @@ end: this->myvm->gc_stats.card_scan_time += (current_micros() - start_time);
} }
template<typename SourceGeneration> template<typename SourceGeneration>
bool trace_objects_between(SourceGeneration *gen, cell scan, cell *end) void trace_objects_between(SourceGeneration *gen, cell scan, cell *end)
{ {
bool copied = false;
while(scan && scan < *end) while(scan && scan < *end)
{ {
copied |= this->trace_slots((object *)scan); this->trace_slots((object *)scan);
scan = gen->next_object_after(this->myvm,scan); scan = gen->next_object_after(this->myvm,scan);
} }
return copied;
} }
void cheneys_algorithm() void cheneys_algorithm()