VM: Refactor collector.hpp to Factor style
parent
ef7c009d2a
commit
66976a12bf
395
vm/collector.hpp
395
vm/collector.hpp
|
@ -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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue