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 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 /* Push the free space and total size of the code heap */
110 void factor_vm::primitive_code_room()
112 cell used, total_free, max_free;
113 code->heap_usage(&used,&total_free,&max_free);
114 dpush(tag_fixnum(code->seg->size / 1024));
115 dpush(tag_fixnum(used / 1024));
116 dpush(tag_fixnum(total_free / 1024));
117 dpush(tag_fixnum(max_free / 1024));
120 code_block *factor_vm::forward_xt(code_block *compiled)
122 return (code_block *)forwarding[compiled];
125 void factor_vm::forward_frame_xt(stack_frame *frame)
127 cell offset = (cell)FRAME_RETURN_ADDRESS(frame) - (cell)frame_code(frame);
128 code_block *forwarded = forward_xt(frame_code(frame));
129 frame->xt = forwarded->xt();
130 FRAME_RETURN_ADDRESS(frame) = (void *)((cell)forwarded + offset);
133 void forward_frame_xt(stack_frame *frame,factor_vm *myvm)
135 return myvm->forward_frame_xt(frame);
138 void factor_vm::forward_object_xts()
144 while((obj = next_object()) != F)
146 switch(tagged<object>(obj).type())
150 word *w = untag<word>(obj);
153 w->code = forward_xt(w->code);
155 w->profiling = forward_xt(w->profiling);
160 quotation *quot = untag<quotation>(obj);
163 quot->code = forward_xt(quot->code);
168 callstack *stack = untag<callstack>(obj);
169 iterate_callstack_object(stack,factor::forward_frame_xt);
180 /* Set the XT fields now that the heap has been compacted */
181 void factor_vm::fixup_object_xts()
187 while((obj = next_object()) != F)
189 switch(tagged<object>(obj).type())
196 quotation *quot = untag<quotation>(obj);
198 set_quot_xt(quot,quot->code);
209 /* Move all free space to the end of the code heap. This is not very efficient,
210 since it makes several passes over the code and data heaps, but we only ever
211 do this before saving a deployed image and exiting, so performaance is not
213 void factor_vm::compact_code_heap()
215 /* Free all unreachable code blocks */
218 /* Figure out where the code heap blocks are going to end up */
219 cell size = code->compute_heap_forwarding(forwarding);
221 /* Update word and quotation code pointers */
222 forward_object_xts();
224 /* Actually perform the compaction */
225 code->compact_heap(forwarding);
227 /* Update word and quotation XTs */
230 /* Now update the free list; there will be a single free block at
232 code->build_free_list(size);