-namespace factor
-{
-
-struct must_start_gc_again {};
-
-template<typename TargetGeneration, typename Policy> 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 <typename TargetGeneration, typename Policy>
+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<typename TargetGeneration, typename Policy>
-struct collector {
- factor_vm *parent;
- data_heap *data;
- code_heap *code;
- TargetGeneration *target;
- gc_workhorse<TargetGeneration,Policy> workhorse;
- slot_visitor<gc_workhorse<TargetGeneration,Policy> > 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<code_block *> *remembered_set)
- {
- std::set<code_block *>::const_iterator iter = remembered_set->begin();
- std::set<code_block *>::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<typename SourceGeneration, typename Unmarker>
- 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 <typename TargetGeneration, typename Policy> struct collector {
+ factor_vm* parent;
+ data_heap* data;
+ code_heap* code;
+ TargetGeneration* target;
+ gc_workhorse<TargetGeneration, Policy> workhorse;
+ slot_visitor<gc_workhorse<TargetGeneration, Policy> > 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<code_block*>* remembered_set) {
+ std::set<code_block*>::const_iterator iter = remembered_set->begin();
+ std::set<code_block*>::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 <typename SourceGeneration, typename Unmarker>
+ 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]);
+ }
+ }
+ }
};
}