]> gitweb.factorcode.org Git - factor.git/blob - vm/full_collector.cpp
849ef07084493e7d31a81437e77c4c3106e9ebbc
[factor.git] / vm / full_collector.cpp
1 #include "master.hpp"
2
3 namespace factor
4 {
5
6 inline static code_block_visitor<code_workhorse> make_code_visitor(factor_vm *parent)
7 {
8         return code_block_visitor<code_workhorse>(parent,code_workhorse(parent));
9 }
10
11 full_collector::full_collector(factor_vm *parent_) :
12         collector<tenured_space,full_policy>(
13                 parent_,
14                 parent_->data->tenured,
15                 full_policy(parent_)),
16         code_visitor(make_code_visitor(parent_)) {}
17
18 void full_collector::trace_code_block(code_block *compiled)
19 {
20         data_visitor.visit_code_block_objects(compiled);
21         data_visitor.visit_embedded_literals(compiled);
22         code_visitor.visit_embedded_code_pointers(compiled);
23 }
24
25 void full_collector::trace_context_code_blocks()
26 {
27         code_visitor.visit_context_code_blocks();
28 }
29
30 void full_collector::trace_uninitialized_code_blocks()
31 {
32         code_visitor.visit_uninitialized_code_blocks();
33 }
34
35 void full_collector::trace_object_code_block(object *obj)
36 {
37         code_visitor.visit_object_code_block(obj);
38 }
39
40 /* After a sweep, invalidate any code heap roots which are not marked,
41 so that if a block makes a tail call to a generic word, and the PIC
42 compiler triggers a GC, and the caller block gets gets GCd as a result,
43 the PIC code won't try to overwrite the call site */
44 void factor_vm::update_code_roots_for_sweep()
45 {
46         std::vector<code_root *>::const_iterator iter = code_roots.begin();
47         std::vector<code_root *>::const_iterator end = code_roots.end();
48
49         mark_bits<code_block> *state = &code->allocator->state;
50
51         for(; iter < end; iter++)
52         {
53                 code_root *root = *iter;
54                 code_block *block = (code_block *)(root->value & (~data_alignment - 1));
55                 if(root->valid && !state->marked_p(block))
56                         root->valid = false;
57         }
58 }
59
60 void factor_vm::collect_mark_impl(bool trace_contexts_p)
61 {
62         full_collector collector(this);
63
64         mark_stack.clear();
65
66         code->clear_mark_bits();
67         data->tenured->clear_mark_bits();
68
69         collector.trace_roots();
70         if(trace_contexts_p)
71         {
72                 collector.trace_contexts();
73                 collector.trace_context_code_blocks();
74                 collector.trace_uninitialized_code_blocks();
75         }
76
77         while(!mark_stack.empty())
78         {
79                 cell ptr = mark_stack.back();
80                 mark_stack.pop_back();
81
82                 if(ptr & 1)
83                 {
84                         code_block *compiled = (code_block *)(ptr - 1);
85                         collector.trace_code_block(compiled);
86                 }
87                 else
88                 {
89                         object *obj = (object *)ptr;
90                         collector.trace_object(obj);
91                         collector.trace_object_code_block(obj);
92                 }
93         }
94
95         data->reset_generation(data->tenured);
96         data->reset_generation(data->aging);
97         data->reset_generation(&nursery);
98         code->clear_remembered_set();
99 }
100
101 void factor_vm::collect_sweep_impl()
102 {
103         current_gc->event->started_data_sweep();
104         data->tenured->sweep();
105         current_gc->event->ended_data_sweep();
106
107         update_code_roots_for_sweep();
108
109         current_gc->event->started_code_sweep();
110         code->allocator->sweep();
111         current_gc->event->ended_code_sweep();
112 }
113
114 void factor_vm::collect_full(bool trace_contexts_p)
115 {
116         collect_mark_impl(trace_contexts_p);
117         collect_sweep_impl();
118
119         if(data->low_memory_p())
120         {
121                 current_gc->op = collect_growing_heap_op;
122                 current_gc->event->op = collect_growing_heap_op;
123                 collect_growing_heap(0,trace_contexts_p);
124         }
125         else if(data->high_fragmentation_p())
126         {
127                 current_gc->op = collect_compact_op;
128                 current_gc->event->op = collect_compact_op;
129                 collect_compact_impl(trace_contexts_p);
130         }
131
132         code->flush_icache();
133 }
134
135 }