6 /* Allocate a code heap during startup */
7 void factorvm::init_code_heap(cell size)
12 bool factorvm::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 factorvm::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);
32 /* Apply a function to every code block */
33 void factorvm::iterate_code_heap(code_heap_iterator iter)
35 heap_block *scan = first_block(&code);
39 if(scan->status != B_FREE)
40 iter((code_block *)scan,this);
41 scan = next_block(&code,scan);
46 /* Copy literals referenced from all code blocks to newspace. Only for
47 aging and nursery collections */
48 void factorvm::copy_code_heap_roots()
50 iterate_code_heap(factor::copy_literal_references);
54 /* Update pointers to words referenced from all code blocks. Only after
55 defining a new word. */
56 void factorvm::update_code_heap_words()
58 iterate_code_heap(factor::update_word_references);
62 inline void factorvm::vmprim_modify_code_heap()
64 gc_root<array> alist(dpop(),this);
66 cell count = array_capacity(alist.untagged());
72 for(i = 0; i < count; i++)
74 gc_root<array> pair(array_nth(alist.untagged(),i),this);
76 gc_root<word> word(array_nth(pair.untagged(),0),this);
77 gc_root<object> data(array_nth(pair.untagged(),1),this);
82 jit_compile_word(word.value(),data.value(),false);
86 array *compiled_data = data.as<array>().untagged();
87 cell literals = array_nth(compiled_data,0);
88 cell relocation = array_nth(compiled_data,1);
89 cell labels = array_nth(compiled_data,2);
90 cell code = array_nth(compiled_data,3);
92 code_block *compiled = add_code_block(
99 word->code = compiled;
103 critical_error("Expected a quotation or an array",data.value());
107 update_word_xt(word.value());
110 update_code_heap_words();
113 PRIMITIVE(modify_code_heap)
115 PRIMITIVE_GETVM()->vmprim_modify_code_heap();
118 /* Push the free space and total size of the code heap */
119 inline void factorvm::vmprim_code_room()
121 cell used, total_free, max_free;
122 heap_usage(&code,&used,&total_free,&max_free);
123 dpush(tag_fixnum(code.seg->size / 1024));
124 dpush(tag_fixnum(used / 1024));
125 dpush(tag_fixnum(total_free / 1024));
126 dpush(tag_fixnum(max_free / 1024));
131 PRIMITIVE_GETVM()->vmprim_code_room();
135 code_block *factorvm::forward_xt(code_block *compiled)
137 return (code_block *)forwarding[compiled];
141 void factorvm::forward_frame_xt(stack_frame *frame)
143 cell offset = (cell)FRAME_RETURN_ADDRESS(frame) - (cell)frame_code(frame);
144 code_block *forwarded = forward_xt(frame_code(frame));
145 frame->xt = forwarded->xt();
146 FRAME_RETURN_ADDRESS(frame) = (void *)((cell)forwarded + offset);
149 void forward_frame_xt(stack_frame *frame,factorvm *myvm)
151 return myvm->forward_frame_xt(frame);
154 void factorvm::forward_object_xts()
160 while((obj = next_object()) != F)
162 switch(tagged<object>(obj).type())
166 word *w = untag<word>(obj);
169 w->code = forward_xt(w->code);
171 w->profiling = forward_xt(w->profiling);
176 quotation *quot = untag<quotation>(obj);
179 quot->code = forward_xt(quot->code);
184 callstack *stack = untag<callstack>(obj);
185 iterate_callstack_object(stack,factor::forward_frame_xt);
197 /* Set the XT fields now that the heap has been compacted */
198 void factorvm::fixup_object_xts()
204 while((obj = next_object()) != F)
206 switch(tagged<object>(obj).type())
213 quotation *quot = untag<quotation>(obj);
215 set_quot_xt(quot,quot->code);
227 /* Move all free space to the end of the code heap. This is not very efficient,
228 since it makes several passes over the code and data heaps, but we only ever
229 do this before saving a deployed image and exiting, so performaance is not
231 void factorvm::compact_code_heap()
233 /* Free all unreachable code blocks */
236 /* Figure out where the code heap blocks are going to end up */
237 cell size = compute_heap_forwarding(&code, forwarding);
239 /* Update word and quotation code pointers */
240 forward_object_xts();
242 /* Actually perform the compaction */
243 compact_heap(&code,forwarding);
245 /* Update word and quotation XTs */
248 /* Now update the free list; there will be a single free block at
250 build_free_list(&code,size);