4 struct must_start_gc_again {};
6 template<typename TargetGeneration, typename Policy> struct data_workhorse {
8 TargetGeneration *target;
11 explicit data_workhorse(factor_vm *parent_, TargetGeneration *target_, Policy policy_) :
16 object *resolve_forwarding(object *untagged)
18 parent->check_data_pointer(untagged);
20 /* is there another forwarding pointer? */
21 while(untagged->forwarding_pointer_p())
22 untagged = untagged->forwarding_pointer();
24 /* we've found the destination */
28 object *promote_object(object *untagged)
30 cell size = untagged->size();
31 object *newpointer = target->allot(size);
32 if(!newpointer) throw must_start_gc_again();
34 memcpy(newpointer,untagged,size);
35 untagged->forward_to(newpointer);
37 policy.promoted_object(newpointer);
42 object *operator()(object *obj)
44 if(!policy.should_copy_p(obj))
46 policy.visited_object(obj);
50 object *forwarding = resolve_forwarding(obj);
53 return promote_object(obj);
54 else if(policy.should_copy_p(forwarding))
55 return promote_object(forwarding);
58 policy.visited_object(forwarding);
64 template<typename TargetGeneration, typename Policy>
65 inline static slot_visitor<data_workhorse<TargetGeneration,Policy> > make_data_visitor(
67 TargetGeneration *target,
70 return slot_visitor<data_workhorse<TargetGeneration,Policy> >(parent,
71 data_workhorse<TargetGeneration,Policy>(parent,target,policy));
74 struct dummy_unmarker {
75 void operator()(card *ptr) {}
78 struct simple_unmarker {
80 explicit simple_unmarker(card unmask_) : unmask(unmask_) {}
81 void operator()(card *ptr) { *ptr &= ~unmask; }
84 struct full_unmarker {
85 explicit full_unmarker() {}
86 void operator()(card *ptr) { *ptr = 0; }
89 template<typename TargetGeneration, typename Policy>
94 TargetGeneration *target;
95 slot_visitor<data_workhorse<TargetGeneration,Policy> > data_visitor;
98 cell code_blocks_scanned;
100 explicit collector(factor_vm *parent_, TargetGeneration *target_, Policy policy_) :
105 data_visitor(make_data_visitor(parent_,target_,policy_)),
108 code_blocks_scanned(0) {}
110 void trace_handle(cell *handle)
112 data_visitor.visit_handle(handle);
115 void trace_object(object *ptr)
117 data_visitor.visit_slots(ptr);
118 if(ptr->type() == ALIEN_TYPE)
119 ((alien *)ptr)->update_address();
124 data_visitor.visit_roots();
127 void trace_contexts()
129 data_visitor.visit_contexts();
132 void trace_code_block_objects(code_block *compiled)
134 data_visitor.visit_code_block_objects(compiled);
137 void trace_embedded_literals(code_block *compiled)
139 data_visitor.visit_embedded_literals(compiled);
142 void trace_code_heap_roots(std::set<code_block *> *remembered_set)
144 std::set<code_block *>::const_iterator iter = remembered_set->begin();
145 std::set<code_block *>::const_iterator end = remembered_set->end();
147 for(; iter != end; iter++)
149 code_block *compiled = *iter;
150 trace_code_block_objects(compiled);
151 trace_embedded_literals(compiled);
152 compiled->flush_icache();
153 code_blocks_scanned++;
157 inline cell first_card_in_deck(cell deck)
159 return deck << (deck_bits - card_bits);
162 inline cell last_card_in_deck(cell deck)
164 return first_card_in_deck(deck + 1);
167 inline cell card_deck_for_address(cell a)
169 return addr_to_deck(a - data->start);
172 inline cell card_start_address(cell card)
174 return (card << card_bits) + data->start;
177 inline cell card_end_address(cell card)
179 return ((card + 1) << card_bits) + data->start;
182 void trace_partial_objects(cell start, cell end, cell card_start, cell card_end)
186 start += sizeof(cell);
188 if(start < card_start) start = card_start;
189 if(end > card_end) end = card_end;
191 cell *slot_ptr = (cell *)start;
192 cell *end_ptr = (cell *)end;
194 for(; slot_ptr < end_ptr; slot_ptr++)
195 data_visitor.visit_handle(slot_ptr);
199 template<typename SourceGeneration, typename Unmarker>
200 void trace_cards(SourceGeneration *gen, card mask, Unmarker unmarker)
202 card_deck *decks = data->decks;
203 card_deck *cards = data->cards;
205 cell gen_start_card = addr_to_card(gen->start - data->start);
207 cell first_deck = card_deck_for_address(gen->start);
208 cell last_deck = card_deck_for_address(gen->end);
210 cell start = 0, binary_start = 0, end = 0;
212 for(cell deck_index = first_deck; deck_index < last_deck; deck_index++)
214 if(decks[deck_index] & mask)
218 cell first_card = first_card_in_deck(deck_index);
219 cell last_card = last_card_in_deck(deck_index);
221 for(cell card_index = first_card; card_index < last_card; card_index++)
223 if(cards[card_index] & mask)
227 if(end < card_start_address(card_index))
229 start = gen->starts.find_object_containing_card(card_index - gen_start_card);
230 binary_start = start + ((object *)start)->binary_payload_start();
231 end = start + ((object *)start)->size();
234 scan_next_object: if(start < card_end_address(card_index))
236 trace_partial_objects(
239 card_start_address(card_index),
240 card_end_address(card_index));
241 if(end < card_end_address(card_index))
243 start = gen->next_object_after(start);
246 binary_start = start + ((object *)start)->binary_payload_start();
247 end = start + ((object *)start)->size();
248 goto scan_next_object;
253 unmarker(&cards[card_index]);
259 unmarker(&decks[deck_index]);