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(word->pic_def != F) jit_compile(word->pic_def,relocate);
55 if(word->pic_tail_def != F) jit_compile(word->pic_tail_def,relocate);
61 explicit word_updater(factor_vm *myvm_) : myvm(myvm_) {}
62 void operator()(code_block *compiled)
64 myvm->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 void factor_vm::primitive_modify_code_heap()
78 gc_root<array> alist(dpop(),this);
80 cell count = array_capacity(alist.untagged());
86 for(i = 0; i < count; i++)
88 gc_root<array> pair(array_nth(alist.untagged(),i),this);
90 gc_root<word> word(array_nth(pair.untagged(),0),this);
91 gc_root<object> data(array_nth(pair.untagged(),1),this);
96 jit_compile_word(word.value(),data.value(),false);
100 array *compiled_data = data.as<array>().untagged();
101 cell owner = array_nth(compiled_data,0);
102 cell literals = array_nth(compiled_data,1);
103 cell relocation = array_nth(compiled_data,2);
104 cell labels = array_nth(compiled_data,3);
105 cell code = array_nth(compiled_data,4);
107 code_block *compiled = add_code_block(
115 word->code = compiled;
119 critical_error("Expected a quotation or an array",data.value());
123 update_word_xt(word.value());
126 update_code_heap_words();
129 /* Push the free space and total size of the code heap */
130 void factor_vm::primitive_code_room()
132 cell used, total_free, max_free;
133 code->heap_usage(&used,&total_free,&max_free);
134 dpush(tag_fixnum(code->seg->size / 1024));
135 dpush(tag_fixnum(used / 1024));
136 dpush(tag_fixnum(total_free / 1024));
137 dpush(tag_fixnum(max_free / 1024));
140 code_block *code_heap::forward_code_block(code_block *compiled)
142 return (code_block *)forwarding[compiled];
145 struct callframe_forwarder {
148 explicit callframe_forwarder(factor_vm *myvm_) : myvm(myvm_) {}
150 void operator()(stack_frame *frame)
152 cell offset = (cell)FRAME_RETURN_ADDRESS(frame,myvm) - (cell)frame->xt;
154 code_block *forwarded = myvm->code->forward_code_block(myvm->frame_code(frame));
155 frame->xt = forwarded->xt();
157 FRAME_RETURN_ADDRESS(frame,myvm) = (void *)((cell)frame->xt + offset);
161 void factor_vm::forward_object_xts()
167 while((obj = next_object()) != F)
169 switch(tagged<object>(obj).type())
173 word *w = untag<word>(obj);
176 w->code = code->forward_code_block(w->code);
178 w->profiling = code->forward_code_block(w->profiling);
185 quotation *quot = untag<quotation>(obj);
189 quot->code = code->forward_code_block(quot->code);
190 set_quot_xt(quot,quot->code);
196 callstack *stack = untag<callstack>(obj);
197 callframe_forwarder forwarder(this);
198 iterate_callstack_object(stack,forwarder);
209 void factor_vm::forward_context_xts()
211 callframe_forwarder forwarder(this);
212 iterate_active_frames(forwarder);
215 struct callback_forwarder {
217 callback_heap *callbacks;
219 callback_forwarder(code_heap *code_, callback_heap *callbacks_) :
220 code(code_), callbacks(callbacks_) {}
222 void operator()(callback *stub)
224 stub->compiled = code->forward_code_block(stub->compiled);
225 callbacks->update(stub);
229 void factor_vm::forward_callback_xts()
231 callback_forwarder forwarder(code,callbacks);
232 callbacks->iterate(forwarder);
235 /* Move all free space to the end of the code heap. Live blocks must be marked
236 on entry to this function. XTs in code blocks must be updated after this
238 void factor_vm::compact_code_heap(bool trace_contexts_p)
240 code->compact_heap();
241 forward_object_xts();
244 forward_context_xts();
245 forward_callback_xts();
249 struct stack_trace_stripper {
250 explicit stack_trace_stripper() {}
252 void operator()(code_block *compiled)
258 void factor_vm::primitive_strip_stack_traces()
260 stack_trace_stripper stripper;
261 iterate_code_heap(stripper);