6 code_heap::code_heap(bool secure_gc, cell size) :
7 heap<heap_block,code_heap_layout>(secure_gc,size,true) {}
9 void code_heap::write_barrier(code_block *compiled)
11 points_to_nursery.insert(compiled);
12 points_to_aging.insert(compiled);
15 void code_heap::clear_remembered_set()
17 points_to_nursery.clear();
18 points_to_aging.clear();
21 bool code_heap::needs_fixup_p(code_block *compiled)
23 return needs_fixup.count(compiled) > 0;
26 void code_heap::code_heap_free(code_block *compiled)
28 points_to_nursery.erase(compiled);
29 points_to_aging.erase(compiled);
30 needs_fixup.erase(compiled);
34 /* Allocate a code heap during startup */
35 void factor_vm::init_code_heap(cell size)
37 code = new code_heap(secure_gc,size);
40 bool factor_vm::in_code_heap_p(cell ptr)
42 return (ptr >= code->seg->start && ptr <= code->seg->end);
45 /* Compile a word definition with the non-optimizing compiler. Allocates memory */
46 void factor_vm::jit_compile_word(cell word_, cell def_, bool relocate)
48 gc_root<word> word(word_,this);
49 gc_root<quotation> def(def_,this);
51 jit_compile(def.value(),relocate);
53 word->code = def->code;
55 if(to_boolean(word->pic_def)) jit_compile(word->pic_def,relocate);
56 if(to_boolean(word->pic_tail_def)) jit_compile(word->pic_tail_def,relocate);
62 explicit word_updater(factor_vm *parent_) : parent(parent_) {}
63 void operator()(code_block *compiled, cell size)
65 parent->update_word_references(compiled);
69 /* Update pointers to words referenced from all code blocks. Only after
70 defining a new word. */
71 void factor_vm::update_code_heap_words()
73 word_updater updater(this);
74 iterate_code_heap(updater);
77 /* After a full GC that did not grow the heap, we have to update references
78 to literals and other words. */
79 struct word_and_literal_code_heap_updater {
82 word_and_literal_code_heap_updater(factor_vm *parent_) : parent(parent_) {}
84 void operator()(heap_block *block, cell size)
86 parent->update_code_block_words_and_literals((code_block *)block);
90 void factor_vm::update_code_heap_words_and_literals()
92 word_and_literal_code_heap_updater updater(this);
93 code->sweep_heap(updater);
96 /* After growing the heap, we have to perform a full relocation to update
97 references to card and deck arrays. */
98 struct code_heap_relocator {
101 code_heap_relocator(factor_vm *parent_) : parent(parent_) {}
103 void operator()(code_block *block, cell size)
105 parent->relocate_code_block(block);
109 void factor_vm::relocate_code_heap()
111 code_heap_relocator relocator(this);
112 code_heap_iterator<code_heap_relocator> iter(relocator);
113 code->sweep_heap(iter);
116 void factor_vm::primitive_modify_code_heap()
118 gc_root<array> alist(dpop(),this);
120 cell count = array_capacity(alist.untagged());
126 for(i = 0; i < count; i++)
128 gc_root<array> pair(array_nth(alist.untagged(),i),this);
130 gc_root<word> word(array_nth(pair.untagged(),0),this);
131 gc_root<object> data(array_nth(pair.untagged(),1),this);
136 jit_compile_word(word.value(),data.value(),false);
140 array *compiled_data = data.as<array>().untagged();
141 cell owner = array_nth(compiled_data,0);
142 cell literals = array_nth(compiled_data,1);
143 cell relocation = array_nth(compiled_data,2);
144 cell labels = array_nth(compiled_data,3);
145 cell code = array_nth(compiled_data,4);
147 code_block *compiled = add_code_block(
148 code_block_optimized,
155 word->code = compiled;
159 critical_error("Expected a quotation or an array",data.value());
163 update_word_xt(word.value());
166 update_code_heap_words();
169 /* Push the free space and total size of the code heap */
170 void factor_vm::primitive_code_room()
172 cell used, total_free, max_free;
173 code->heap_usage(&used,&total_free,&max_free);
174 dpush(tag_fixnum(code->seg->size / 1024));
175 dpush(tag_fixnum(used / 1024));
176 dpush(tag_fixnum(total_free / 1024));
177 dpush(tag_fixnum(max_free / 1024));
180 code_block *code_heap::forward_code_block(code_block *compiled)
182 return (code_block *)state->forward_block(compiled);
185 struct callframe_forwarder {
188 explicit callframe_forwarder(factor_vm *parent_) : parent(parent_) {}
190 void operator()(stack_frame *frame)
192 cell offset = (cell)FRAME_RETURN_ADDRESS(frame,parent) - (cell)frame->xt;
194 code_block *forwarded = parent->code->forward_code_block(parent->frame_code(frame));
195 frame->xt = forwarded->xt();
197 FRAME_RETURN_ADDRESS(frame,parent) = (void *)((cell)frame->xt + offset);
201 void factor_vm::forward_object_xts()
207 while(to_boolean(obj = next_object()))
209 switch(tagged<object>(obj).type())
213 word *w = untag<word>(obj);
216 w->code = code->forward_code_block(w->code);
218 w->profiling = code->forward_code_block(w->profiling);
225 quotation *quot = untag<quotation>(obj);
229 quot->code = code->forward_code_block(quot->code);
230 set_quot_xt(quot,quot->code);
236 callstack *stack = untag<callstack>(obj);
237 callframe_forwarder forwarder(this);
238 iterate_callstack_object(stack,forwarder);
249 void factor_vm::forward_context_xts()
251 callframe_forwarder forwarder(this);
252 iterate_active_frames(forwarder);
255 struct callback_forwarder {
257 callback_heap *callbacks;
259 callback_forwarder(code_heap *code_, callback_heap *callbacks_) :
260 code(code_), callbacks(callbacks_) {}
262 void operator()(callback *stub)
264 stub->compiled = code->forward_code_block(stub->compiled);
265 callbacks->update(stub);
269 void factor_vm::forward_callback_xts()
271 callback_forwarder forwarder(code,callbacks);
272 callbacks->iterate(forwarder);
275 /* Move all free space to the end of the code heap. Live blocks must be marked
276 on entry to this function. XTs in code blocks must be updated after this
278 void factor_vm::compact_code_heap(bool trace_contexts_p)
280 /* Figure out where blocks are going to go */
281 code->state->compute_forwarding();
283 /* Update references to the code heap from the data heap */
284 forward_object_xts();
287 forward_context_xts();
288 forward_callback_xts();
291 /* Move code blocks and update references amongst them (this requires
292 that the data heap is up to date since relocation looks up object XTs) */
293 code_heap_relocator relocator(this);
294 code_heap_iterator<code_heap_relocator> iter(relocator);
295 code->compact_heap(iter);
298 struct stack_trace_stripper {
299 explicit stack_trace_stripper() {}
301 void operator()(code_block *compiled, cell size)
303 compiled->owner = false_object;
307 void factor_vm::primitive_strip_stack_traces()
309 stack_trace_stripper stripper;
310 iterate_code_heap(stripper);