6 /* Allocate a code heap during startup */
7 void factor_vm::init_code_heap(cell size)
9 code = new heap(this,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 = code->first_block();
38 if(scan->status != B_FREE)
39 iter((code_block *)scan,this);
40 scan = code->next_block(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_FORWARD(modify_code_heap)
111 /* Push the free space and total size of the code heap */
112 inline void factor_vm::primitive_code_room()
114 cell used, total_free, max_free;
115 code->heap_usage(&used,&total_free,&max_free);
116 dpush(tag_fixnum(code->seg->size / 1024));
117 dpush(tag_fixnum(used / 1024));
118 dpush(tag_fixnum(total_free / 1024));
119 dpush(tag_fixnum(max_free / 1024));
122 PRIMITIVE_FORWARD(code_room)
124 code_block *factor_vm::forward_xt(code_block *compiled)
126 return (code_block *)forwarding[compiled];
129 void factor_vm::forward_frame_xt(stack_frame *frame)
131 cell offset = (cell)FRAME_RETURN_ADDRESS(frame) - (cell)frame_code(frame);
132 code_block *forwarded = forward_xt(frame_code(frame));
133 frame->xt = forwarded->xt();
134 FRAME_RETURN_ADDRESS(frame) = (void *)((cell)forwarded + offset);
137 void forward_frame_xt(stack_frame *frame,factor_vm *myvm)
139 return myvm->forward_frame_xt(frame);
142 void factor_vm::forward_object_xts()
148 while((obj = next_object()) != F)
150 switch(tagged<object>(obj).type())
154 word *w = untag<word>(obj);
157 w->code = forward_xt(w->code);
159 w->profiling = forward_xt(w->profiling);
164 quotation *quot = untag<quotation>(obj);
167 quot->code = forward_xt(quot->code);
172 callstack *stack = untag<callstack>(obj);
173 iterate_callstack_object(stack,factor::forward_frame_xt);
184 /* Set the XT fields now that the heap has been compacted */
185 void factor_vm::fixup_object_xts()
191 while((obj = next_object()) != F)
193 switch(tagged<object>(obj).type())
200 quotation *quot = untag<quotation>(obj);
202 set_quot_xt(quot,quot->code);
213 /* Move all free space to the end of the code heap. This is not very efficient,
214 since it makes several passes over the code and data heaps, but we only ever
215 do this before saving a deployed image and exiting, so performaance is not
217 void factor_vm::compact_code_heap()
219 /* Free all unreachable code blocks */
222 /* Figure out where the code heap blocks are going to end up */
223 cell size = code->compute_heap_forwarding(forwarding);
225 /* Update word and quotation code pointers */
226 forward_object_xts();
228 /* Actually perform the compaction */
229 code->compact_heap(forwarding);
231 /* Update word and quotation XTs */
234 /* Now update the free list; there will be a single free block at
236 code->build_free_list(size);