VM: Refactor collector.hpp to Factor style

db4
Erik Charlebois 2013-05-11 21:52:27 -04:00
parent ef7c009d2a
commit 66976a12bf
1 changed files with 182 additions and 213 deletions

View File

@ -1,274 +1,243 @@
namespace factor namespace factor {
{
struct must_start_gc_again {}; struct must_start_gc_again {
};
template<typename TargetGeneration, typename Policy> struct gc_workhorse : no_fixup { template <typename TargetGeneration, typename Policy>
static const bool translated_code_block_map = false; struct gc_workhorse : no_fixup {
static const bool translated_code_block_map = false;
factor_vm *parent; factor_vm* parent;
TargetGeneration *target; TargetGeneration* target;
Policy policy; Policy policy;
code_heap *code; code_heap* code;
explicit gc_workhorse(factor_vm *parent_, TargetGeneration *target_, Policy policy_) : explicit gc_workhorse(factor_vm* parent_, TargetGeneration* target_,
parent(parent_), Policy policy_)
target(target_), : parent(parent_), target(target_), policy(policy_), code(parent->code) {}
policy(policy_),
code(parent->code) {}
object *resolve_forwarding(object *untagged) object* resolve_forwarding(object* untagged) {
{ parent->check_data_pointer(untagged);
parent->check_data_pointer(untagged);
/* is there another forwarding pointer? */ /* is there another forwarding pointer? */
while(untagged->forwarding_pointer_p()) while (untagged->forwarding_pointer_p())
untagged = untagged->forwarding_pointer(); untagged = untagged->forwarding_pointer();
/* we've found the destination */ /* we've found the destination */
return untagged; return untagged;
} }
object *promote_object(object *untagged) object* promote_object(object* untagged) {
{ cell size = untagged->size();
cell size = untagged->size(); object* newpointer = target->allot(size);
object *newpointer = target->allot(size); if (!newpointer)
if(!newpointer) throw must_start_gc_again(); throw must_start_gc_again();
memcpy(newpointer,untagged,size); memcpy(newpointer, untagged, size);
untagged->forward_to(newpointer); untagged->forward_to(newpointer);
policy.promoted_object(newpointer); policy.promoted_object(newpointer);
return newpointer; return newpointer;
} }
object *fixup_data(object *obj) object* fixup_data(object* obj) {
{ parent->check_data_pointer(obj);
parent->check_data_pointer(obj);
if(!policy.should_copy_p(obj)) if (!policy.should_copy_p(obj)) {
{ policy.visited_object(obj);
policy.visited_object(obj); return obj;
return obj; }
}
object *forwarding = resolve_forwarding(obj); object* forwarding = resolve_forwarding(obj);
if(forwarding == obj) if (forwarding == obj)
return promote_object(obj); return promote_object(obj);
else if(policy.should_copy_p(forwarding)) else if (policy.should_copy_p(forwarding))
return promote_object(forwarding); return promote_object(forwarding);
else else {
{ policy.visited_object(forwarding);
policy.visited_object(forwarding); return forwarding;
return forwarding; }
} }
}
code_block *fixup_code(code_block *compiled) code_block* fixup_code(code_block* compiled) {
{ if (!code->marked_p(compiled)) {
if(!code->marked_p(compiled)) code->set_marked_p(compiled);
{ parent->mark_stack.push_back((cell) compiled + 1);
code->set_marked_p(compiled); }
parent->mark_stack.push_back((cell)compiled + 1);
}
return compiled; return compiled;
} }
}; };
struct dummy_unmarker { struct dummy_unmarker {
void operator()(card *ptr) {} void operator()(card* ptr) {}
}; };
struct simple_unmarker { struct simple_unmarker {
card unmask; card unmask;
explicit simple_unmarker(card unmask_) : unmask(unmask_) {} explicit simple_unmarker(card unmask_) : unmask(unmask_) {}
void operator()(card *ptr) { *ptr &= ~unmask; } void operator()(card* ptr) { *ptr &= ~unmask; }
}; };
struct full_unmarker { struct full_unmarker {
explicit full_unmarker() {} explicit full_unmarker() {}
void operator()(card *ptr) { *ptr = 0; } void operator()(card* ptr) { *ptr = 0; }
}; };
template<typename TargetGeneration, typename Policy> template <typename TargetGeneration, typename Policy> struct collector {
struct collector { factor_vm* parent;
factor_vm *parent; data_heap* data;
data_heap *data; code_heap* code;
code_heap *code; TargetGeneration* target;
TargetGeneration *target; gc_workhorse<TargetGeneration, Policy> workhorse;
gc_workhorse<TargetGeneration,Policy> workhorse; slot_visitor<gc_workhorse<TargetGeneration, Policy> > data_visitor;
slot_visitor<gc_workhorse<TargetGeneration,Policy> > data_visitor; cell cards_scanned;
cell cards_scanned; cell decks_scanned;
cell decks_scanned; cell code_blocks_scanned;
cell code_blocks_scanned;
explicit collector(factor_vm *parent_, TargetGeneration *target_, Policy policy_) : explicit collector(factor_vm* parent_, TargetGeneration* target_,
parent(parent_), Policy policy_)
data(parent_->data), : parent(parent_),
code(parent_->code), data(parent_->data),
target(target_), code(parent_->code),
workhorse(parent,target,policy_), target(target_),
data_visitor(parent,workhorse), workhorse(parent, target, policy_),
cards_scanned(0), data_visitor(parent, workhorse),
decks_scanned(0), cards_scanned(0),
code_blocks_scanned(0) {} decks_scanned(0),
code_blocks_scanned(0) {}
void trace_handle(cell *handle) void trace_handle(cell* handle) { data_visitor.visit_handle(handle); }
{
data_visitor.visit_handle(handle);
}
void trace_object(object *ptr) void trace_object(object* ptr) {
{ data_visitor.visit_slots(ptr);
data_visitor.visit_slots(ptr); if (ptr->type() == ALIEN_TYPE)
if(ptr->type() == ALIEN_TYPE) ((alien*)ptr)->update_address();
((alien *)ptr)->update_address(); }
}
void trace_roots() void trace_roots() { data_visitor.visit_roots(); }
{
data_visitor.visit_roots();
}
void trace_contexts() void trace_contexts() { data_visitor.visit_contexts(); }
{
data_visitor.visit_contexts();
}
void trace_code_block_objects(code_block *compiled) void trace_code_block_objects(code_block* compiled) {
{ data_visitor.visit_code_block_objects(compiled);
data_visitor.visit_code_block_objects(compiled); }
}
void trace_embedded_literals(code_block *compiled) void trace_embedded_literals(code_block* compiled) {
{ data_visitor.visit_embedded_literals(compiled);
data_visitor.visit_embedded_literals(compiled); }
}
void trace_code_heap_roots(std::set<code_block *> *remembered_set) void trace_code_heap_roots(std::set<code_block*>* remembered_set) {
{ std::set<code_block*>::const_iterator iter = remembered_set->begin();
std::set<code_block *>::const_iterator iter = remembered_set->begin(); std::set<code_block*>::const_iterator end = remembered_set->end();
std::set<code_block *>::const_iterator end = remembered_set->end();
for(; iter != end; iter++) for (; iter != end; iter++) {
{ code_block* compiled = *iter;
code_block *compiled = *iter; trace_code_block_objects(compiled);
trace_code_block_objects(compiled); trace_embedded_literals(compiled);
trace_embedded_literals(compiled); compiled->flush_icache();
compiled->flush_icache(); code_blocks_scanned++;
code_blocks_scanned++; }
} }
}
inline cell first_card_in_deck(cell deck) inline cell first_card_in_deck(cell deck) {
{ return deck << (deck_bits - card_bits);
return deck << (deck_bits - card_bits); }
}
inline cell last_card_in_deck(cell deck) inline cell last_card_in_deck(cell deck) {
{ return first_card_in_deck(deck + 1);
return first_card_in_deck(deck + 1); }
}
inline cell card_deck_for_address(cell a) inline cell card_deck_for_address(cell a) {
{ return addr_to_deck(a - data->start);
return addr_to_deck(a - data->start); }
}
inline cell card_start_address(cell card) inline cell card_start_address(cell card) {
{ return (card << card_bits) + data->start;
return (card << card_bits) + data->start; }
}
inline cell card_end_address(cell card) inline cell card_end_address(cell card) {
{ return ((card + 1) << card_bits) + data->start;
return ((card + 1) << card_bits) + data->start; }
}
void 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) {
if(card_start < end) if (card_start < end) {
{ start += sizeof(cell);
start += sizeof(cell);
if(start < card_start) start = card_start; if (start < card_start)
if(end > card_end) end = card_end; start = card_start;
if (end > card_end)
end = card_end;
cell *slot_ptr = (cell *)start; cell* slot_ptr = (cell*)start;
cell *end_ptr = (cell *)end; cell* end_ptr = (cell*)end;
for(; slot_ptr < end_ptr; slot_ptr++) for (; slot_ptr < end_ptr; slot_ptr++)
data_visitor.visit_handle(slot_ptr); data_visitor.visit_handle(slot_ptr);
} }
} }
template<typename SourceGeneration, typename Unmarker> template <typename SourceGeneration, typename Unmarker>
void trace_cards(SourceGeneration *gen, card mask, Unmarker unmarker) void trace_cards(SourceGeneration* gen, card mask, Unmarker unmarker) {
{ card_deck* decks = data->decks;
card_deck *decks = data->decks; card_deck* cards = data->cards;
card_deck *cards = data->cards;
cell gen_start_card = addr_to_card(gen->start - data->start); cell gen_start_card = addr_to_card(gen->start - data->start);
cell first_deck = card_deck_for_address(gen->start); cell first_deck = card_deck_for_address(gen->start);
cell last_deck = card_deck_for_address(gen->end); cell last_deck = card_deck_for_address(gen->end);
cell start = 0, binary_start = 0, end = 0; cell start = 0, binary_start = 0, end = 0;
for(cell deck_index = first_deck; deck_index < last_deck; deck_index++) for (cell deck_index = first_deck; deck_index < last_deck; deck_index++) {
{ if (decks[deck_index] & mask) {
if(decks[deck_index] & mask) decks_scanned++;
{
decks_scanned++;
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);
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) {
{ cards_scanned++;
cards_scanned++;
if(end < card_start_address(card_index)) if (end < card_start_address(card_index)) {
{ start = gen->starts
start = gen->starts.find_object_containing_card(card_index - gen_start_card); .find_object_containing_card(card_index - gen_start_card);
binary_start = start + ((object *)start)->binary_payload_start(); binary_start = start + ((object*)start)->binary_payload_start();
end = start + ((object *)start)->size(); end = start + ((object*)start)->size();
} }
scan_next_object: if(start < card_end_address(card_index)) scan_next_object:
{ if (start < card_end_address(card_index)) {
trace_partial_objects( trace_partial_objects(start, binary_start,
start, card_start_address(card_index),
binary_start, card_end_address(card_index));
card_start_address(card_index), if (end < card_end_address(card_index)) {
card_end_address(card_index)); start = gen->next_object_after(start);
if(end < card_end_address(card_index)) if (start) {
{ binary_start =
start = gen->next_object_after(start); start + ((object*)start)->binary_payload_start();
if(start) end = start + ((object*)start)->size();
{ goto scan_next_object;
binary_start = start + ((object *)start)->binary_payload_start(); }
end = start + ((object *)start)->size(); }
goto scan_next_object; }
}
}
}
unmarker(&cards[card_index]); unmarker(&cards[card_index]);
if(!start) return; if (!start)
} return;
} }
}
unmarker(&decks[deck_index]); unmarker(&decks[deck_index]);
} }
} }
} }
}; };
} }