6 /* Allocate a code heap during startup */
7 void factor_vm::init_code_heap(cell size)
12 bool factor_vm::in_code_heap_p(cell ptr)
14 return (ptr >= code.seg->start && ptr <= code.seg->end);
17 /* Compile a word definition with the non-optimizing compiler. Allocates memory */
18 void factor_vm::jit_compile_word(cell word_, cell def_, bool relocate)
20 gc_root<word> word(word_,this);
21 gc_root<quotation> def(def_,this);
23 jit_compile(def.value(),relocate);
25 word->code = def->code;
27 if(word->pic_def != F) jit_compile(word->pic_def,relocate);
28 if(word->pic_tail_def != F) jit_compile(word->pic_tail_def,relocate);
31 /* Apply a function to every code block */
32 void factor_vm::iterate_code_heap(code_heap_iterator iter)
34 heap_block *scan = first_block(&code);
38 if(scan->status != B_FREE)
39 iter((code_block *)scan,this);
40 scan = next_block(&code,scan);
44 /* Copy literals referenced from all code blocks to newspace. Only for
45 aging and nursery collections */
46 void factor_vm::copy_code_heap_roots()
48 iterate_code_heap(factor::copy_literal_references);
51 /* Update pointers to words referenced from all code blocks. Only after
52 defining a new word. */
53 void factor_vm::update_code_heap_words()
55 iterate_code_heap(factor::update_word_references);
58 inline void factor_vm::primitive_modify_code_heap()
60 gc_root<array> alist(dpop(),this);
62 cell count = array_capacity(alist.untagged());
68 for(i = 0; i < count; i++)
70 gc_root<array> pair(array_nth(alist.untagged(),i),this);
72 gc_root<word> word(array_nth(pair.untagged(),0),this);
73 gc_root<object> data(array_nth(pair.untagged(),1),this);
78 jit_compile_word(word.value(),data.value(),false);
82 array *compiled_data = data.as<array>().untagged();
83 cell literals = array_nth(compiled_data,0);
84 cell relocation = array_nth(compiled_data,1);
85 cell labels = array_nth(compiled_data,2);
86 cell code = array_nth(compiled_data,3);
88 code_block *compiled = add_code_block(
95 word->code = compiled;
99 critical_error("Expected a quotation or an array",data.value());
103 update_word_xt(word.value());
106 update_code_heap_words();
109 PRIMITIVE(modify_code_heap)
111 PRIMITIVE_GETVM()->primitive_modify_code_heap();
114 /* Push the free space and total size of the code heap */
115 inline void factor_vm::primitive_code_room()
117 cell used, total_free, max_free;
118 heap_usage(&code,&used,&total_free,&max_free);
119 dpush(tag_fixnum(code.seg->size / 1024));
120 dpush(tag_fixnum(used / 1024));
121 dpush(tag_fixnum(total_free / 1024));
122 dpush(tag_fixnum(max_free / 1024));
127 PRIMITIVE_GETVM()->primitive_code_room();
130 code_block *factor_vm::forward_xt(code_block *compiled)
132 return (code_block *)forwarding[compiled];
135 void factor_vm::forward_frame_xt(stack_frame *frame)
137 cell offset = (cell)FRAME_RETURN_ADDRESS(frame) - (cell)frame_code(frame);
138 code_block *forwarded = forward_xt(frame_code(frame));
139 frame->xt = forwarded->xt();
140 FRAME_RETURN_ADDRESS(frame) = (void *)((cell)forwarded + offset);
143 void forward_frame_xt(stack_frame *frame,factor_vm *myvm)
145 return myvm->forward_frame_xt(frame);
148 void factor_vm::forward_object_xts()
154 while((obj = next_object()) != F)
156 switch(tagged<object>(obj).type())
160 word *w = untag<word>(obj);
163 w->code = forward_xt(w->code);
165 w->profiling = forward_xt(w->profiling);
170 quotation *quot = untag<quotation>(obj);
173 quot->code = forward_xt(quot->code);
178 callstack *stack = untag<callstack>(obj);
179 iterate_callstack_object(stack,factor::forward_frame_xt);
190 /* Set the XT fields now that the heap has been compacted */
191 void factor_vm::fixup_object_xts()
197 while((obj = next_object()) != F)
199 switch(tagged<object>(obj).type())
206 quotation *quot = untag<quotation>(obj);
208 set_quot_xt(quot,quot->code);
219 /* Move all free space to the end of the code heap. This is not very efficient,
220 since it makes several passes over the code and data heaps, but we only ever
221 do this before saving a deployed image and exiting, so performaance is not
223 void factor_vm::compact_code_heap()
225 /* Free all unreachable code blocks */
228 /* Figure out where the code heap blocks are going to end up */
229 cell size = compute_heap_forwarding(&code, forwarding);
231 /* Update word and quotation code pointers */
232 forward_object_xts();
234 /* Actually perform the compaction */
235 compact_heap(&code,forwarding);
237 /* Update word and quotation XTs */
240 /* Now update the free list; there will be a single free block at
242 build_free_list(&code,size);