From: Erik Charlebois Date: Sun, 12 May 2013 01:52:27 +0000 (-0400) Subject: VM: Refactor collector.hpp to Factor style X-Git-Tag: 0.97~1308 X-Git-Url: https://gitweb.factorcode.org/gitweb.cgi?p=factor.git;a=commitdiff_plain;h=66976a12bf089bb543a8bd37d2cc2bf54ce470df VM: Refactor collector.hpp to Factor style --- diff --git a/vm/collector.hpp b/vm/collector.hpp index 454627f2ac..f19d165f58 100644 --- a/vm/collector.hpp +++ b/vm/collector.hpp @@ -1,274 +1,243 @@ -namespace factor -{ - -struct must_start_gc_again {}; - -template struct gc_workhorse : no_fixup { - static const bool translated_code_block_map = false; - - factor_vm *parent; - TargetGeneration *target; - Policy policy; - code_heap *code; - - explicit gc_workhorse(factor_vm *parent_, TargetGeneration *target_, Policy policy_) : - parent(parent_), - target(target_), - policy(policy_), - code(parent->code) {} - - object *resolve_forwarding(object *untagged) - { - parent->check_data_pointer(untagged); - - /* is there another forwarding pointer? */ - while(untagged->forwarding_pointer_p()) - untagged = untagged->forwarding_pointer(); - - /* we've found the destination */ - return untagged; - } - - object *promote_object(object *untagged) - { - cell size = untagged->size(); - object *newpointer = target->allot(size); - if(!newpointer) throw must_start_gc_again(); - - memcpy(newpointer,untagged,size); - untagged->forward_to(newpointer); - - policy.promoted_object(newpointer); - - return newpointer; - } - - object *fixup_data(object *obj) - { - parent->check_data_pointer(obj); - - if(!policy.should_copy_p(obj)) - { - policy.visited_object(obj); - return obj; - } - - object *forwarding = resolve_forwarding(obj); - - if(forwarding == obj) - return promote_object(obj); - else if(policy.should_copy_p(forwarding)) - return promote_object(forwarding); - else - { - policy.visited_object(forwarding); - return forwarding; - } - } - - code_block *fixup_code(code_block *compiled) - { - if(!code->marked_p(compiled)) - { - code->set_marked_p(compiled); - parent->mark_stack.push_back((cell)compiled + 1); - } - - return compiled; - } +namespace factor { + +struct must_start_gc_again { +}; + +template +struct gc_workhorse : no_fixup { + static const bool translated_code_block_map = false; + + factor_vm* parent; + TargetGeneration* target; + Policy policy; + code_heap* code; + + explicit gc_workhorse(factor_vm* parent_, TargetGeneration* target_, + Policy policy_) + : parent(parent_), target(target_), policy(policy_), code(parent->code) {} + + object* resolve_forwarding(object* untagged) { + parent->check_data_pointer(untagged); + + /* is there another forwarding pointer? */ + while (untagged->forwarding_pointer_p()) + untagged = untagged->forwarding_pointer(); + + /* we've found the destination */ + return untagged; + } + + object* promote_object(object* untagged) { + cell size = untagged->size(); + object* newpointer = target->allot(size); + if (!newpointer) + throw must_start_gc_again(); + + memcpy(newpointer, untagged, size); + untagged->forward_to(newpointer); + + policy.promoted_object(newpointer); + + return newpointer; + } + + object* fixup_data(object* obj) { + parent->check_data_pointer(obj); + + if (!policy.should_copy_p(obj)) { + policy.visited_object(obj); + return obj; + } + + object* forwarding = resolve_forwarding(obj); + + if (forwarding == obj) + return promote_object(obj); + else if (policy.should_copy_p(forwarding)) + return promote_object(forwarding); + else { + policy.visited_object(forwarding); + return forwarding; + } + } + + code_block* fixup_code(code_block* compiled) { + if (!code->marked_p(compiled)) { + code->set_marked_p(compiled); + parent->mark_stack.push_back((cell) compiled + 1); + } + + return compiled; + } }; struct dummy_unmarker { - void operator()(card *ptr) {} + void operator()(card* ptr) {} }; struct simple_unmarker { - card unmask; - explicit simple_unmarker(card unmask_) : unmask(unmask_) {} - void operator()(card *ptr) { *ptr &= ~unmask; } + card unmask; + explicit simple_unmarker(card unmask_) : unmask(unmask_) {} + void operator()(card* ptr) { *ptr &= ~unmask; } }; struct full_unmarker { - explicit full_unmarker() {} - void operator()(card *ptr) { *ptr = 0; } + explicit full_unmarker() {} + void operator()(card* ptr) { *ptr = 0; } }; -template -struct collector { - factor_vm *parent; - data_heap *data; - code_heap *code; - TargetGeneration *target; - gc_workhorse workhorse; - slot_visitor > data_visitor; - cell cards_scanned; - cell decks_scanned; - cell code_blocks_scanned; - - explicit collector(factor_vm *parent_, TargetGeneration *target_, Policy policy_) : - parent(parent_), - data(parent_->data), - code(parent_->code), - target(target_), - workhorse(parent,target,policy_), - data_visitor(parent,workhorse), - cards_scanned(0), - decks_scanned(0), - code_blocks_scanned(0) {} - - void trace_handle(cell *handle) - { - data_visitor.visit_handle(handle); - } - - void trace_object(object *ptr) - { - data_visitor.visit_slots(ptr); - if(ptr->type() == ALIEN_TYPE) - ((alien *)ptr)->update_address(); - } - - void trace_roots() - { - data_visitor.visit_roots(); - } - - void trace_contexts() - { - data_visitor.visit_contexts(); - } - - void trace_code_block_objects(code_block *compiled) - { - data_visitor.visit_code_block_objects(compiled); - } - - void trace_embedded_literals(code_block *compiled) - { - data_visitor.visit_embedded_literals(compiled); - } - - void trace_code_heap_roots(std::set *remembered_set) - { - std::set::const_iterator iter = remembered_set->begin(); - std::set::const_iterator end = remembered_set->end(); - - for(; iter != end; iter++) - { - code_block *compiled = *iter; - trace_code_block_objects(compiled); - trace_embedded_literals(compiled); - compiled->flush_icache(); - code_blocks_scanned++; - } - } - - inline cell first_card_in_deck(cell deck) - { - return deck << (deck_bits - card_bits); - } - - inline cell last_card_in_deck(cell deck) - { - return first_card_in_deck(deck + 1); - } - - inline cell card_deck_for_address(cell a) - { - return addr_to_deck(a - data->start); - } - - inline cell card_start_address(cell card) - { - return (card << card_bits) + data->start; - } - - inline cell card_end_address(cell card) - { - return ((card + 1) << card_bits) + data->start; - } - - void trace_partial_objects(cell start, cell end, cell card_start, cell card_end) - { - if(card_start < end) - { - start += sizeof(cell); - - if(start < card_start) start = card_start; - if(end > card_end) end = card_end; - - cell *slot_ptr = (cell *)start; - cell *end_ptr = (cell *)end; - - for(; slot_ptr < end_ptr; slot_ptr++) - data_visitor.visit_handle(slot_ptr); - } - } - - template - void trace_cards(SourceGeneration *gen, card mask, Unmarker unmarker) - { - card_deck *decks = data->decks; - card_deck *cards = data->cards; - - cell gen_start_card = addr_to_card(gen->start - data->start); - - cell first_deck = card_deck_for_address(gen->start); - cell last_deck = card_deck_for_address(gen->end); - - cell start = 0, binary_start = 0, end = 0; - - for(cell deck_index = first_deck; deck_index < last_deck; deck_index++) - { - if(decks[deck_index] & mask) - { - decks_scanned++; - - cell first_card = first_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++) - { - if(cards[card_index] & mask) - { - cards_scanned++; - - if(end < card_start_address(card_index)) - { - start = gen->starts.find_object_containing_card(card_index - gen_start_card); - binary_start = start + ((object *)start)->binary_payload_start(); - end = start + ((object *)start)->size(); - } - -scan_next_object: if(start < card_end_address(card_index)) - { - trace_partial_objects( - start, - binary_start, - card_start_address(card_index), - card_end_address(card_index)); - if(end < card_end_address(card_index)) - { - start = gen->next_object_after(start); - if(start) - { - binary_start = start + ((object *)start)->binary_payload_start(); - end = start + ((object *)start)->size(); - goto scan_next_object; - } - } - } - - unmarker(&cards[card_index]); - - if(!start) return; - } - } - - unmarker(&decks[deck_index]); - } - } - } +template struct collector { + factor_vm* parent; + data_heap* data; + code_heap* code; + TargetGeneration* target; + gc_workhorse workhorse; + slot_visitor > data_visitor; + cell cards_scanned; + cell decks_scanned; + cell code_blocks_scanned; + + explicit collector(factor_vm* parent_, TargetGeneration* target_, + Policy policy_) + : parent(parent_), + data(parent_->data), + code(parent_->code), + target(target_), + workhorse(parent, target, policy_), + data_visitor(parent, workhorse), + cards_scanned(0), + decks_scanned(0), + code_blocks_scanned(0) {} + + void trace_handle(cell* handle) { data_visitor.visit_handle(handle); } + + void trace_object(object* ptr) { + data_visitor.visit_slots(ptr); + if (ptr->type() == ALIEN_TYPE) + ((alien*)ptr)->update_address(); + } + + void trace_roots() { data_visitor.visit_roots(); } + + void trace_contexts() { data_visitor.visit_contexts(); } + + void trace_code_block_objects(code_block* compiled) { + data_visitor.visit_code_block_objects(compiled); + } + + void trace_embedded_literals(code_block* compiled) { + data_visitor.visit_embedded_literals(compiled); + } + + void trace_code_heap_roots(std::set* remembered_set) { + std::set::const_iterator iter = remembered_set->begin(); + std::set::const_iterator end = remembered_set->end(); + + for (; iter != end; iter++) { + code_block* compiled = *iter; + trace_code_block_objects(compiled); + trace_embedded_literals(compiled); + compiled->flush_icache(); + code_blocks_scanned++; + } + } + + inline cell first_card_in_deck(cell deck) { + return deck << (deck_bits - card_bits); + } + + inline cell last_card_in_deck(cell deck) { + return first_card_in_deck(deck + 1); + } + + inline cell card_deck_for_address(cell a) { + return addr_to_deck(a - data->start); + } + + inline cell card_start_address(cell card) { + return (card << card_bits) + data->start; + } + + inline cell card_end_address(cell card) { + return ((card + 1) << card_bits) + data->start; + } + + void trace_partial_objects(cell start, cell end, cell card_start, + cell card_end) { + if (card_start < end) { + start += sizeof(cell); + + if (start < card_start) + start = card_start; + if (end > card_end) + end = card_end; + + cell* slot_ptr = (cell*)start; + cell* end_ptr = (cell*)end; + + for (; slot_ptr < end_ptr; slot_ptr++) + data_visitor.visit_handle(slot_ptr); + } + } + + template + void trace_cards(SourceGeneration* gen, card mask, Unmarker unmarker) { + card_deck* decks = data->decks; + card_deck* cards = data->cards; + + cell gen_start_card = addr_to_card(gen->start - data->start); + + cell first_deck = card_deck_for_address(gen->start); + cell last_deck = card_deck_for_address(gen->end); + + cell start = 0, binary_start = 0, end = 0; + + for (cell deck_index = first_deck; deck_index < last_deck; deck_index++) { + if (decks[deck_index] & mask) { + decks_scanned++; + + cell first_card = first_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++) { + if (cards[card_index] & mask) { + cards_scanned++; + + if (end < card_start_address(card_index)) { + start = gen->starts + .find_object_containing_card(card_index - gen_start_card); + binary_start = start + ((object*)start)->binary_payload_start(); + end = start + ((object*)start)->size(); + } + + scan_next_object: + if (start < card_end_address(card_index)) { + trace_partial_objects(start, binary_start, + card_start_address(card_index), + card_end_address(card_index)); + if (end < card_end_address(card_index)) { + start = gen->next_object_after(start); + if (start) { + binary_start = + start + ((object*)start)->binary_payload_start(); + end = start + ((object*)start)->size(); + goto scan_next_object; + } + } + } + + unmarker(&cards[card_index]); + + if (!start) + return; + } + } + + unmarker(&decks[deck_index]); + } + } + } }; }