3 struct must_start_gc_again {
6 template <typename TargetGeneration, typename Policy>
7 struct gc_workhorse : no_fixup {
8 static const bool translated_code_block_map = false;
11 TargetGeneration* target;
15 gc_workhorse(factor_vm* parent, TargetGeneration* target, Policy policy)
16 : parent(parent), target(target), policy(policy), code(parent->code) {}
18 object* resolve_forwarding(object* untagged) {
19 parent->check_data_pointer(untagged);
21 /* is there another forwarding pointer? */
22 while (untagged->forwarding_pointer_p())
23 untagged = untagged->forwarding_pointer();
25 /* we've found the destination */
29 object* promote_object(object* untagged) {
30 cell size = untagged->size();
31 object* newpointer = target->allot(size);
33 throw must_start_gc_again();
35 memcpy(newpointer, untagged, size);
36 untagged->forward_to(newpointer);
38 policy.promoted_object(newpointer);
43 object* fixup_data(object* obj) {
44 parent->check_data_pointer(obj);
46 if (!policy.should_copy_p(obj)) {
47 policy.visited_object(obj);
51 object* forwarding = resolve_forwarding(obj);
53 if (forwarding == obj)
54 return promote_object(obj);
55 else if (policy.should_copy_p(forwarding))
56 return promote_object(forwarding);
58 policy.visited_object(forwarding);
63 code_block* fixup_code(code_block* compiled) {
64 if (!code->marked_p(compiled)) {
65 code->set_marked_p(compiled);
66 parent->mark_stack.push_back((cell) compiled + 1);
73 struct dummy_unmarker {
74 void operator()(card* ptr) {}
77 struct simple_unmarker {
79 explicit simple_unmarker(card unmask) : unmask(unmask) {}
80 void operator()(card* ptr) { *ptr &= ~unmask; }
83 struct full_unmarker {
85 void operator()(card* ptr) { *ptr = 0; }
88 template <typename TargetGeneration, typename Policy> struct collector {
92 TargetGeneration* target;
93 gc_workhorse<TargetGeneration, Policy> workhorse;
94 slot_visitor<gc_workhorse<TargetGeneration, Policy> > data_visitor;
97 cell code_blocks_scanned;
99 collector(factor_vm* parent, TargetGeneration* target, Policy policy)
104 workhorse(parent, target, policy),
105 data_visitor(parent, workhorse),
108 code_blocks_scanned(0) {}
110 void trace_handle(cell* handle) { data_visitor.visit_handle(handle); }
112 void trace_object(object* ptr) {
113 data_visitor.visit_slots(ptr);
114 if (ptr->type() == ALIEN_TYPE)
115 ((alien*)ptr)->update_address();
118 void trace_roots() { data_visitor.visit_roots(); }
120 void trace_contexts() { data_visitor.visit_contexts(); }
122 void trace_code_block_objects(code_block* compiled) {
123 data_visitor.visit_code_block_objects(compiled);
126 void trace_embedded_literals(code_block* compiled) {
127 data_visitor.visit_embedded_literals(compiled);
130 void trace_code_heap_roots(std::set<code_block*>* remembered_set) {
131 std::set<code_block*>::const_iterator iter = remembered_set->begin();
132 std::set<code_block*>::const_iterator end = remembered_set->end();
134 for (; iter != end; iter++) {
135 code_block* compiled = *iter;
136 trace_code_block_objects(compiled);
137 trace_embedded_literals(compiled);
138 compiled->flush_icache();
139 code_blocks_scanned++;
143 inline cell first_card_in_deck(cell deck) {
144 return deck << (deck_bits - card_bits);
147 inline cell last_card_in_deck(cell deck) {
148 return first_card_in_deck(deck + 1);
151 inline cell card_deck_for_address(cell a) {
152 return addr_to_deck(a - data->start);
155 inline cell card_start_address(cell card) {
156 return (card << card_bits) + data->start;
159 inline cell card_end_address(cell card) {
160 return ((card + 1) << card_bits) + data->start;
163 void trace_partial_objects(cell start, cell end, cell card_start,
165 if (card_start < end) {
166 start += sizeof(cell);
168 if (start < card_start)
173 cell* slot_ptr = (cell*)start;
174 cell* end_ptr = (cell*)end;
176 for (; slot_ptr < end_ptr; slot_ptr++)
177 data_visitor.visit_handle(slot_ptr);
181 template <typename SourceGeneration, typename Unmarker>
182 void trace_cards(SourceGeneration* gen, card mask, Unmarker unmarker) {
183 card_deck* decks = data->decks;
184 card_deck* cards = data->cards;
186 cell gen_start_card = addr_to_card(gen->start - data->start);
188 cell first_deck = card_deck_for_address(gen->start);
189 cell last_deck = card_deck_for_address(gen->end);
191 cell start = 0, binary_start = 0, end = 0;
193 for (cell deck_index = first_deck; deck_index < last_deck; deck_index++) {
194 if (decks[deck_index] & mask) {
197 cell first_card = first_card_in_deck(deck_index);
198 cell last_card = last_card_in_deck(deck_index);
200 for (cell card_index = first_card; card_index < last_card;
202 if (cards[card_index] & mask) {
205 if (end < card_start_address(card_index)) {
207 .find_object_containing_card(card_index - gen_start_card);
208 binary_start = start + ((object*)start)->binary_payload_start();
209 end = start + ((object*)start)->size();
213 if (start < card_end_address(card_index)) {
214 trace_partial_objects(start, binary_start,
215 card_start_address(card_index),
216 card_end_address(card_index));
217 if (end < card_end_address(card_index)) {
218 start = gen->next_object_after(start);
221 start + ((object*)start)->binary_payload_start();
222 end = start + ((object*)start)->size();
223 goto scan_next_object;
228 unmarker(&cards[card_index]);
235 unmarker(&decks[deck_index]);