6 /* Allocate a code heap during startup */
7 void factorvm::init_code_heap(cell size)
13 bool factorvm::in_code_heap_p(cell ptr)
15 return (ptr >= code.seg->start && ptr <= code.seg->end);
18 bool in_code_heap_p(cell ptr)
20 return vm->in_code_heap_p(ptr); // used by os specific signal handlers
23 /* Compile a word definition with the non-optimizing compiler. Allocates memory */
24 void factorvm::jit_compile_word(cell word_, cell def_, bool relocate)
26 gc_root<word> word(word_,this);
27 gc_root<quotation> def(def_,this);
29 jit_compile(def.value(),relocate);
31 word->code = def->code;
33 if(word->pic_def != F) jit_compile(word->pic_def,relocate);
34 if(word->pic_tail_def != F) jit_compile(word->pic_tail_def,relocate);
38 /* Apply a function to every code block */
39 void factorvm::iterate_code_heap(code_heap_iterator iter)
41 heap_block *scan = first_block(&code);
45 if(scan->status != B_FREE)
46 iter((code_block *)scan,this);
47 scan = next_block(&code,scan);
52 /* Copy literals referenced from all code blocks to newspace. Only for
53 aging and nursery collections */
54 void factorvm::copy_code_heap_roots()
56 iterate_code_heap(factor::copy_literal_references);
60 /* Update pointers to words referenced from all code blocks. Only after
61 defining a new word. */
62 void factorvm::update_code_heap_words()
64 iterate_code_heap(factor::update_word_references);
68 inline void factorvm::vmprim_modify_code_heap()
70 gc_root<array> alist(dpop(),this);
72 cell count = array_capacity(alist.untagged());
78 for(i = 0; i < count; i++)
80 gc_root<array> pair(array_nth(alist.untagged(),i),this);
82 gc_root<word> word(array_nth(pair.untagged(),0),this);
83 gc_root<object> data(array_nth(pair.untagged(),1),this);
88 jit_compile_word(word.value(),data.value(),false);
92 array *compiled_data = data.as<array>().untagged();
93 cell literals = array_nth(compiled_data,0);
94 cell relocation = array_nth(compiled_data,1);
95 cell labels = array_nth(compiled_data,2);
96 cell code = array_nth(compiled_data,3);
98 code_block *compiled = add_code_block(
105 word->code = compiled;
109 critical_error("Expected a quotation or an array",data.value());
113 update_word_xt(word.value());
116 update_code_heap_words();
119 PRIMITIVE(modify_code_heap)
121 PRIMITIVE_GETVM()->vmprim_modify_code_heap();
124 /* Push the free space and total size of the code heap */
125 inline void factorvm::vmprim_code_room()
127 cell used, total_free, max_free;
128 heap_usage(&code,&used,&total_free,&max_free);
129 dpush(tag_fixnum(code.seg->size / 1024));
130 dpush(tag_fixnum(used / 1024));
131 dpush(tag_fixnum(total_free / 1024));
132 dpush(tag_fixnum(max_free / 1024));
137 PRIMITIVE_GETVM()->vmprim_code_room();
141 code_block *factorvm::forward_xt(code_block *compiled)
143 return (code_block *)forwarding[compiled];
147 void factorvm::forward_frame_xt(stack_frame *frame)
149 cell offset = (cell)FRAME_RETURN_ADDRESS(frame) - (cell)frame_code(frame);
150 code_block *forwarded = forward_xt(frame_code(frame));
151 frame->xt = forwarded->xt();
152 FRAME_RETURN_ADDRESS(frame) = (void *)((cell)forwarded + offset);
155 void forward_frame_xt(stack_frame *frame,factorvm *myvm)
157 return myvm->forward_frame_xt(frame);
160 void factorvm::forward_object_xts()
166 while((obj = next_object()) != F)
168 switch(tagged<object>(obj).type())
172 word *w = untag<word>(obj);
175 w->code = forward_xt(w->code);
177 w->profiling = forward_xt(w->profiling);
182 quotation *quot = untag<quotation>(obj);
185 quot->code = forward_xt(quot->code);
190 callstack *stack = untag<callstack>(obj);
191 iterate_callstack_object(stack,factor::forward_frame_xt);
203 /* Set the XT fields now that the heap has been compacted */
204 void factorvm::fixup_object_xts()
210 while((obj = next_object()) != F)
212 switch(tagged<object>(obj).type())
219 quotation *quot = untag<quotation>(obj);
221 set_quot_xt(quot,quot->code);
233 /* Move all free space to the end of the code heap. This is not very efficient,
234 since it makes several passes over the code and data heaps, but we only ever
235 do this before saving a deployed image and exiting, so performaance is not
237 void factorvm::compact_code_heap()
239 /* Free all unreachable code blocks */
242 /* Figure out where the code heap blocks are going to end up */
243 cell size = compute_heap_forwarding(&code, forwarding);
245 /* Update word and quotation code pointers */
246 forward_object_xts();
248 /* Actually perform the compaction */
249 compact_heap(&code,forwarding);
251 /* Update word and quotation XTs */
254 /* Now update the free list; there will be a single free block at
256 build_free_list(&code,size);