4 template<typename TargetGeneration, typename Policy> struct collector {
9 generation_statistics *stats;
10 TargetGeneration *target;
13 explicit collector(factor_vm *parent_, generation_statistics *stats_, TargetGeneration *target_, Policy policy_) :
17 current_gc(parent_->current_gc),
22 object *resolve_forwarding(object *untagged)
24 parent->check_data_pointer(untagged);
26 /* is there another forwarding pointer? */
27 while(untagged->h.forwarding_pointer_p())
28 untagged = untagged->h.forwarding_pointer();
30 /* we've found the destination */
31 untagged->h.check_header();
35 void trace_handle(cell *handle)
37 cell pointer = *handle;
39 if(immediate_p(pointer)) return;
41 object *untagged = parent->untag<object>(pointer);
42 if(!policy.should_copy_p(untagged))
45 object *forwarding = resolve_forwarding(untagged);
47 if(forwarding == untagged)
48 untagged = promote_object(untagged);
49 else if(policy.should_copy_p(forwarding))
50 untagged = promote_object(forwarding);
52 untagged = forwarding;
54 *handle = RETAG(untagged,TAG(pointer));
57 void trace_slots(object *ptr)
59 cell *slot = (cell *)ptr;
60 cell *end = (cell *)((cell)ptr + parent->binary_payload_start(ptr));
65 for(; slot < end; slot++) trace_handle(slot);
69 object *promote_object(object *untagged)
71 cell size = parent->untagged_object_size(untagged);
72 object *newpointer = target->allot(size);
73 /* XXX not exception-safe */
74 if(!newpointer) longjmp(current_gc->gc_unwind,1);
76 memcpy(newpointer,untagged,size);
77 untagged->h.forward_to(newpointer);
79 stats->object_count++;
80 stats->bytes_copied += size;
85 void trace_stack_elements(segment *region, cell *top)
87 for(cell *ptr = (cell *)region->start; ptr <= top; ptr++)
91 void trace_registered_locals()
93 std::vector<cell>::const_iterator iter = parent->gc_locals.begin();
94 std::vector<cell>::const_iterator end = parent->gc_locals.end();
96 for(; iter < end; iter++)
97 trace_handle((cell *)(*iter));
100 void trace_registered_bignums()
102 std::vector<cell>::const_iterator iter = parent->gc_bignums.begin();
103 std::vector<cell>::const_iterator end = parent->gc_bignums.end();
105 for(; iter < end; iter++)
107 cell *handle = (cell *)(*iter);
111 *handle |= BIGNUM_TYPE;
112 trace_handle(handle);
113 *handle &= ~BIGNUM_TYPE;
118 /* Copy roots over at the start of GC, namely various constants, stacks,
119 the user environment and extra roots registered by local_roots.hpp */
122 trace_handle(&parent->true_object);
123 trace_handle(&parent->bignum_zero);
124 trace_handle(&parent->bignum_pos_one);
125 trace_handle(&parent->bignum_neg_one);
127 trace_registered_locals();
128 trace_registered_bignums();
130 for(int i = 0; i < USER_ENV; i++) trace_handle(&parent->userenv[i]);
133 void trace_contexts()
135 context *ctx = parent->ctx;
139 trace_stack_elements(ctx->datastack_region,(cell *)ctx->datastack);
140 trace_stack_elements(ctx->retainstack_region,(cell *)ctx->retainstack);
142 trace_handle(&ctx->catchstack_save);
143 trace_handle(&ctx->current_callback_save);