6 code_heap::code_heap(bool secure_gc, cell size) : heap(secure_gc,size,true) {}
8 void code_heap::write_barrier(code_block *compiled)
10 points_to_nursery.insert(compiled);
11 points_to_aging.insert(compiled);
14 void code_heap::clear_remembered_set()
16 points_to_nursery.clear();
17 points_to_aging.clear();
20 bool code_heap::needs_fixup_p(code_block *compiled)
22 return needs_fixup.count(compiled) > 0;
25 void code_heap::code_heap_free(code_block *compiled)
27 points_to_nursery.erase(compiled);
28 points_to_aging.erase(compiled);
29 needs_fixup.erase(compiled);
33 /* Allocate a code heap during startup */
34 void factor_vm::init_code_heap(cell size)
36 code = new code_heap(secure_gc,size);
39 bool factor_vm::in_code_heap_p(cell ptr)
41 return (ptr >= code->seg->start && ptr <= code->seg->end);
44 /* Compile a word definition with the non-optimizing compiler. Allocates memory */
45 void factor_vm::jit_compile_word(cell word_, cell def_, bool relocate)
47 gc_root<word> word(word_,this);
48 gc_root<quotation> def(def_,this);
50 jit_compile(def.value(),relocate);
52 word->code = def->code;
54 if(to_boolean(word->pic_def)) jit_compile(word->pic_def,relocate);
55 if(to_boolean(word->pic_tail_def)) jit_compile(word->pic_tail_def,relocate);
61 explicit word_updater(factor_vm *parent_) : parent(parent_) {}
62 void operator()(code_block *compiled, cell size)
64 parent->update_word_references(compiled);
68 /* Update pointers to words referenced from all code blocks. Only after
69 defining a new word. */
70 void factor_vm::update_code_heap_words()
72 word_updater updater(this);
73 iterate_code_heap(updater);
76 /* After a full GC that did not grow the heap, we have to update references
77 to literals and other words. */
78 struct word_and_literal_code_heap_updater {
81 word_and_literal_code_heap_updater(factor_vm *parent_) : parent(parent_) {}
83 void operator()(heap_block *block, cell size)
85 parent->update_code_block_words_and_literals((code_block *)block);
89 void factor_vm::update_code_heap_words_and_literals()
91 word_and_literal_code_heap_updater updater(this);
92 code->sweep_heap(updater);
95 /* After growing the heap, we have to perform a full relocation to update
96 references to card and deck arrays. */
97 struct code_heap_relocator {
100 code_heap_relocator(factor_vm *parent_) : parent(parent_) {}
102 void operator()(code_block *block, cell size)
104 parent->relocate_code_block(block);
108 void factor_vm::relocate_code_heap()
110 code_heap_relocator relocator(this);
111 code_heap_iterator<code_heap_relocator> iter(relocator);
112 code->sweep_heap(iter);
115 void factor_vm::primitive_modify_code_heap()
117 gc_root<array> alist(dpop(),this);
119 cell count = array_capacity(alist.untagged());
125 for(i = 0; i < count; i++)
127 gc_root<array> pair(array_nth(alist.untagged(),i),this);
129 gc_root<word> word(array_nth(pair.untagged(),0),this);
130 gc_root<object> data(array_nth(pair.untagged(),1),this);
135 jit_compile_word(word.value(),data.value(),false);
139 array *compiled_data = data.as<array>().untagged();
140 cell owner = array_nth(compiled_data,0);
141 cell literals = array_nth(compiled_data,1);
142 cell relocation = array_nth(compiled_data,2);
143 cell labels = array_nth(compiled_data,3);
144 cell code = array_nth(compiled_data,4);
146 code_block *compiled = add_code_block(
147 code_block_optimized,
154 word->code = compiled;
158 critical_error("Expected a quotation or an array",data.value());
162 update_word_xt(word.value());
165 update_code_heap_words();
168 /* Push the free space and total size of the code heap */
169 void factor_vm::primitive_code_room()
171 cell used, total_free, max_free;
172 code->heap_usage(&used,&total_free,&max_free);
173 dpush(tag_fixnum(code->seg->size / 1024));
174 dpush(tag_fixnum(used / 1024));
175 dpush(tag_fixnum(total_free / 1024));
176 dpush(tag_fixnum(max_free / 1024));
179 code_block *code_heap::forward_code_block(code_block *compiled)
181 return (code_block *)state->forward_block(compiled);
184 struct callframe_forwarder {
187 explicit callframe_forwarder(factor_vm *parent_) : parent(parent_) {}
189 void operator()(stack_frame *frame)
191 cell offset = (cell)FRAME_RETURN_ADDRESS(frame,parent) - (cell)frame->xt;
193 code_block *forwarded = parent->code->forward_code_block(parent->frame_code(frame));
194 frame->xt = forwarded->xt();
196 FRAME_RETURN_ADDRESS(frame,parent) = (void *)((cell)frame->xt + offset);
200 void factor_vm::forward_object_xts()
206 while(to_boolean(obj = next_object()))
208 switch(tagged<object>(obj).type())
212 word *w = untag<word>(obj);
215 w->code = code->forward_code_block(w->code);
217 w->profiling = code->forward_code_block(w->profiling);
224 quotation *quot = untag<quotation>(obj);
228 quot->code = code->forward_code_block(quot->code);
229 set_quot_xt(quot,quot->code);
235 callstack *stack = untag<callstack>(obj);
236 callframe_forwarder forwarder(this);
237 iterate_callstack_object(stack,forwarder);
248 void factor_vm::forward_context_xts()
250 callframe_forwarder forwarder(this);
251 iterate_active_frames(forwarder);
254 struct callback_forwarder {
256 callback_heap *callbacks;
258 callback_forwarder(code_heap *code_, callback_heap *callbacks_) :
259 code(code_), callbacks(callbacks_) {}
261 void operator()(callback *stub)
263 stub->compiled = code->forward_code_block(stub->compiled);
264 callbacks->update(stub);
268 void factor_vm::forward_callback_xts()
270 callback_forwarder forwarder(code,callbacks);
271 callbacks->iterate(forwarder);
274 /* Move all free space to the end of the code heap. Live blocks must be marked
275 on entry to this function. XTs in code blocks must be updated after this
277 void factor_vm::compact_code_heap(bool trace_contexts_p)
279 /* Figure out where blocks are going to go */
280 code->state->compute_forwarding();
282 /* Update references to the code heap from the data heap */
283 forward_object_xts();
286 forward_context_xts();
287 forward_callback_xts();
290 /* Move code blocks and update references amongst them (this requires
291 that the data heap is up to date since relocation looks up object XTs) */
292 code_heap_relocator relocator(this);
293 code_heap_iterator<code_heap_relocator> iter(relocator);
294 code->compact_heap(iter);
297 struct stack_trace_stripper {
298 explicit stack_trace_stripper() {}
300 void operator()(code_block *compiled, cell size)
302 compiled->owner = false_object;
306 void factor_vm::primitive_strip_stack_traces()
308 stack_trace_stripper stripper;
309 iterate_code_heap(stripper);