4 struct must_start_gc_again {};
6 template<typename TargetGeneration, typename Policy> struct gc_workhorse : no_fixup {
8 TargetGeneration *target;
12 explicit gc_workhorse(factor_vm *parent_, TargetGeneration *target_, Policy policy_) :
18 object *resolve_forwarding(object *untagged)
20 parent->check_data_pointer(untagged);
22 /* is there another forwarding pointer? */
23 while(untagged->forwarding_pointer_p())
24 untagged = untagged->forwarding_pointer();
26 /* we've found the destination */
30 object *promote_object(object *untagged)
32 cell size = untagged->size();
33 object *newpointer = target->allot(size);
34 if(!newpointer) throw must_start_gc_again();
36 memcpy(newpointer,untagged,size);
37 untagged->forward_to(newpointer);
39 policy.promoted_object(newpointer);
44 object *fixup_data(object *obj)
46 if(!policy.should_copy_p(obj))
48 policy.visited_object(obj);
52 object *forwarding = resolve_forwarding(obj);
55 return promote_object(obj);
56 else if(policy.should_copy_p(forwarding))
57 return promote_object(forwarding);
60 policy.visited_object(forwarding);
65 code_block *fixup_code(code_block *compiled)
67 if(!code->marked_p(compiled))
69 code->set_marked_p(compiled);
70 parent->mark_stack.push_back((cell)compiled + 1);
77 struct dummy_unmarker {
78 void operator()(card *ptr) {}
81 struct simple_unmarker {
83 explicit simple_unmarker(card unmask_) : unmask(unmask_) {}
84 void operator()(card *ptr) { *ptr &= ~unmask; }
87 struct full_unmarker {
88 explicit full_unmarker() {}
89 void operator()(card *ptr) { *ptr = 0; }
92 template<typename TargetGeneration, typename Policy>
97 TargetGeneration *target;
98 gc_workhorse<TargetGeneration,Policy> workhorse;
99 slot_visitor<gc_workhorse<TargetGeneration,Policy> > data_visitor;
102 cell code_blocks_scanned;
104 explicit collector(factor_vm *parent_, TargetGeneration *target_, Policy policy_) :
109 workhorse(parent,target,policy_),
110 data_visitor(parent,workhorse),
113 code_blocks_scanned(0) {}
115 void trace_handle(cell *handle)
117 data_visitor.visit_handle(handle);
120 void trace_object(object *ptr)
122 data_visitor.visit_slots(ptr);
123 if(ptr->type() == ALIEN_TYPE)
124 ((alien *)ptr)->update_address();
129 data_visitor.visit_roots();
132 void trace_contexts()
134 data_visitor.visit_contexts();
137 void trace_code_block_objects(code_block *compiled)
139 data_visitor.visit_code_block_objects(compiled);
142 void trace_embedded_literals(code_block *compiled)
144 data_visitor.visit_embedded_literals(compiled);
147 void trace_code_heap_roots(std::set<code_block *> *remembered_set)
149 std::set<code_block *>::const_iterator iter = remembered_set->begin();
150 std::set<code_block *>::const_iterator end = remembered_set->end();
152 for(; iter != end; iter++)
154 code_block *compiled = *iter;
155 trace_code_block_objects(compiled);
156 trace_embedded_literals(compiled);
157 compiled->flush_icache();
158 code_blocks_scanned++;
162 inline cell first_card_in_deck(cell deck)
164 return deck << (deck_bits - card_bits);
167 inline cell last_card_in_deck(cell deck)
169 return first_card_in_deck(deck + 1);
172 inline cell card_deck_for_address(cell a)
174 return addr_to_deck(a - data->start);
177 inline cell card_start_address(cell card)
179 return (card << card_bits) + data->start;
182 inline cell card_end_address(cell card)
184 return ((card + 1) << card_bits) + data->start;
187 void trace_partial_objects(cell start, cell end, cell card_start, cell card_end)
191 start += sizeof(cell);
193 if(start < card_start) start = card_start;
194 if(end > card_end) end = card_end;
196 cell *slot_ptr = (cell *)start;
197 cell *end_ptr = (cell *)end;
199 for(; slot_ptr < end_ptr; slot_ptr++)
200 data_visitor.visit_handle(slot_ptr);
204 template<typename SourceGeneration, typename Unmarker>
205 void trace_cards(SourceGeneration *gen, card mask, Unmarker unmarker)
207 card_deck *decks = data->decks;
208 card_deck *cards = data->cards;
210 cell gen_start_card = addr_to_card(gen->start - data->start);
212 cell first_deck = card_deck_for_address(gen->start);
213 cell last_deck = card_deck_for_address(gen->end);
215 cell start = 0, binary_start = 0, end = 0;
217 for(cell deck_index = first_deck; deck_index < last_deck; deck_index++)
219 if(decks[deck_index] & mask)
223 cell first_card = first_card_in_deck(deck_index);
224 cell last_card = last_card_in_deck(deck_index);
226 for(cell card_index = first_card; card_index < last_card; card_index++)
228 if(cards[card_index] & mask)
232 if(end < card_start_address(card_index))
234 start = gen->starts.find_object_containing_card(card_index - gen_start_card);
235 binary_start = start + ((object *)start)->binary_payload_start();
236 end = start + ((object *)start)->size();
239 scan_next_object: if(start < card_end_address(card_index))
241 trace_partial_objects(
244 card_start_address(card_index),
245 card_end_address(card_index));
246 if(end < card_end_address(card_index))
248 start = gen->next_object_after(start);
251 binary_start = start + ((object *)start)->binary_payload_start();
252 end = start + ((object *)start)->size();
253 goto scan_next_object;
258 unmarker(&cards[card_index]);
264 unmarker(&decks[deck_index]);