]> gitweb.factorcode.org Git - factor.git/blob - vm/full_collector.cpp
merge project-euler.factor
[factor.git] / vm / full_collector.cpp
1 #include "master.hpp"
2
3 namespace factor
4 {
5
6 full_collector::full_collector(factor_vm *myvm_) :
7         copying_collector<tenured_space,full_policy>(myvm_,myvm_->data->tenured,full_policy(myvm_)) {}
8
9 struct stack_frame_marker {
10         factor_vm *myvm;
11         full_collector *collector;
12
13         explicit stack_frame_marker(full_collector *collector_) :
14                 myvm(collector_->myvm), collector(collector_) {}
15
16         void operator()(stack_frame *frame)
17         {
18                 collector->mark_code_block(myvm->frame_code(frame));
19         }
20 };
21
22 /* Mark code blocks executing in currently active stack frames. */
23 void full_collector::mark_active_blocks()
24 {
25         context *stacks = this->myvm->stack_chain;
26
27         while(stacks)
28         {
29                 cell top = (cell)stacks->callstack_top;
30                 cell bottom = (cell)stacks->callstack_bottom;
31
32                 stack_frame_marker marker(this);
33                 myvm->iterate_callstack(top,bottom,marker);
34
35                 stacks = stacks->next;
36         }
37 }
38
39 void full_collector::mark_object_code_block(object *obj)
40 {
41         switch(obj->h.hi_tag())
42         {
43         case WORD_TYPE:
44                 {
45                         word *w = (word *)obj;
46                         if(w->code)
47                                 mark_code_block(w->code);
48                         if(w->profiling)
49                                 mark_code_block(w->profiling);
50                         break;
51                 }
52         case QUOTATION_TYPE:
53                 {
54                         quotation *q = (quotation *)obj;
55                         if(q->code)
56                                 mark_code_block(q->code);
57                         break;
58                 }
59         case CALLSTACK_TYPE:
60                 {
61                         callstack *stack = (callstack *)obj;
62                         stack_frame_marker marker(this);
63                         myvm->iterate_callstack_object(stack,marker);
64                         break;
65                 }
66         }
67 }
68
69 /* Trace all literals referenced from a code block. Only for aging and nursery collections */
70 void full_collector::trace_literal_references(code_block *compiled)
71 {
72         this->trace_handle(&compiled->owner);
73         this->trace_handle(&compiled->literals);
74         this->trace_handle(&compiled->relocation);
75 }
76
77 /* Mark all literals referenced from a word XT. Only for tenured
78 collections */
79 void full_collector::mark_code_block(code_block *compiled)
80 {
81         this->code->mark_block(compiled);
82         trace_literal_references(compiled);
83 }
84
85 void full_collector::cheneys_algorithm()
86 {
87         while(scan && scan < target->here)
88         {
89                 object *obj = (object *)scan;
90                 this->trace_slots(obj);
91                 this->mark_object_code_block(obj);
92                 scan = target->next_object_after(this->myvm,scan);
93         }
94 }
95
96 void factor_vm::collect_full(cell requested_bytes, bool trace_contexts_p)
97 {
98         if(current_gc->growing_data_heap)
99         {
100                 current_gc->old_data_heap = data;
101                 set_data_heap(grow_data_heap(current_gc->old_data_heap,requested_bytes));
102         }
103         else
104         {
105                 std::swap(data->tenured,data->tenured_semispace);
106                 reset_generation(data->tenured);
107         }
108
109         full_collector collector(this);
110
111         collector.trace_roots();
112         if(trace_contexts_p)
113         {
114                 collector.trace_contexts();
115                 collector.mark_active_blocks();
116         }
117
118         collector.cheneys_algorithm();
119         free_unmarked_code_blocks();
120
121         reset_generation(data->aging);
122         nursery.here = nursery.start;
123
124         if(current_gc->growing_data_heap)
125                 delete current_gc->old_data_heap;
126 }
127
128 }