3 /* Allocate a code heap during startup */
4 void init_code_heap(CELL size
)
6 new_heap(&code_heap
,size
);
9 bool in_code_heap_p(CELL ptr
)
11 return (ptr
>= code_heap
.segment
->start
12 && ptr
<= code_heap
.segment
->end
);
15 void set_word_code(F_WORD
*word
, F_CODE_BLOCK
*compiled
)
17 if(compiled
->type
!= WORD_TYPE
)
18 critical_error("bad param to set_word_xt",(CELL
)compiled
);
20 word
->code
= compiled
;
24 /* Allocates memory */
25 void default_word_code(F_WORD
*word
, bool relocate
)
27 REGISTER_UNTAGGED(word
);
28 jit_compile(word
->def
,relocate
);
29 UNREGISTER_UNTAGGED(word
);
31 word
->code
= untag_quotation(word
->def
)->code
;
35 /* Apply a function to every code block */
36 void iterate_code_heap(CODE_HEAP_ITERATOR iter
)
38 F_BLOCK
*scan
= first_block(&code_heap
);
42 if(scan
->status
!= B_FREE
)
43 iter(block_to_compiled(scan
));
44 scan
= next_block(&code_heap
,scan
);
48 /* Copy literals referenced from all code blocks to newspace. Only for
49 aging and nursery collections */
50 void copy_code_heap_roots(void)
52 iterate_code_heap(copy_literal_references
);
55 /* Update literals referenced from all code blocks. Only for tenured
56 collections, done at the end. */
57 void update_code_heap_roots(void)
59 iterate_code_heap(update_literal_references
);
62 /* Update pointers to words referenced from all code blocks. Only after
63 defining a new word. */
64 void update_code_heap_words(void)
66 iterate_code_heap(update_word_references
);
69 void primitive_modify_code_heap(void)
71 F_ARRAY
*alist
= untag_array(dpop());
73 CELL count
= untag_fixnum_fast(alist
->capacity
);
78 for(i
= 0; i
< count
; i
++)
80 F_ARRAY
*pair
= untag_array(array_nth(alist
,i
));
82 F_WORD
*word
= untag_word(array_nth(pair
,0));
84 CELL data
= array_nth(pair
,1);
88 REGISTER_UNTAGGED(alist
);
89 REGISTER_UNTAGGED(word
);
90 default_word_code(word
,false);
91 UNREGISTER_UNTAGGED(word
);
92 UNREGISTER_UNTAGGED(alist
);
96 F_ARRAY
*compiled_code
= untag_array(data
);
98 F_ARRAY
*literals
= untag_array(array_nth(compiled_code
,0));
99 CELL relocation
= array_nth(compiled_code
,1);
100 F_ARRAY
*labels
= untag_array(array_nth(compiled_code
,2));
101 F_ARRAY
*code
= untag_array(array_nth(compiled_code
,3));
103 REGISTER_UNTAGGED(alist
);
104 REGISTER_UNTAGGED(word
);
106 F_CODE_BLOCK
*compiled
= add_compiled_block(
111 tag_object(literals
));
113 UNREGISTER_UNTAGGED(word
);
114 UNREGISTER_UNTAGGED(alist
);
116 set_word_code(word
,compiled
);
119 REGISTER_UNTAGGED(alist
);
120 update_word_xt(word
);
121 UNREGISTER_UNTAGGED(alist
);
124 update_code_heap_words();
127 /* Push the free space and total size of the code heap */
128 void primitive_code_room(void)
130 CELL used
, total_free
, max_free
;
131 heap_usage(&code_heap
,&used
,&total_free
,&max_free
);
132 dpush(tag_fixnum((code_heap
.segment
->size
) / 1024));
133 dpush(tag_fixnum(used
/ 1024));
134 dpush(tag_fixnum(total_free
/ 1024));
135 dpush(tag_fixnum(max_free
/ 1024));
138 F_CODE_BLOCK
*forward_xt(F_CODE_BLOCK
*compiled
)
140 return block_to_compiled(compiled_to_block(compiled
)->forwarding
);
143 void forward_frame_xt(F_STACK_FRAME
*frame
)
145 CELL offset
= (CELL
)FRAME_RETURN_ADDRESS(frame
) - (CELL
)frame_code(frame
);
146 F_CODE_BLOCK
*forwarded
= forward_xt(frame_code(frame
));
147 frame
->xt
= (XT
)(forwarded
+ 1);
148 FRAME_RETURN_ADDRESS(frame
) = (XT
)((CELL
)forwarded
+ offset
);
151 void forward_object_xts(void)
157 while((obj
= next_object()) != F
)
159 if(type_of(obj
) == WORD_TYPE
)
161 F_WORD
*word
= untag_object(obj
);
163 word
->code
= forward_xt(word
->code
);
165 word
->profiling
= forward_xt(word
->profiling
);
167 else if(type_of(obj
) == QUOTATION_TYPE
)
169 F_QUOTATION
*quot
= untag_object(obj
);
171 if(quot
->compiledp
!= F
)
172 quot
->code
= forward_xt(quot
->code
);
174 else if(type_of(obj
) == CALLSTACK_TYPE
)
176 F_CALLSTACK
*stack
= untag_object(obj
);
177 iterate_callstack_object(stack
,forward_frame_xt
);
181 /* End the heap scan */
185 /* Set the XT fields now that the heap has been compacted */
186 void fixup_object_xts(void)
192 while((obj
= next_object()) != F
)
194 if(type_of(obj
) == WORD_TYPE
)
196 F_WORD
*word
= untag_object(obj
);
197 update_word_xt(word
);
199 else if(type_of(obj
) == QUOTATION_TYPE
)
201 F_QUOTATION
*quot
= untag_object(obj
);
203 if(quot
->compiledp
!= F
)
204 set_quot_xt(quot
,quot
->code
);
208 /* End the heap scan */
212 /* Move all free space to the end of the code heap. This is not very efficient,
213 since it makes several passes over the code and data heaps, but we only ever
214 do this before saving a deployed image and exiting, so performaance is not
216 void compact_code_heap(void)
218 /* Free all unreachable code blocks */
221 /* Figure out where the code heap blocks are going to end up */
222 CELL size
= compute_heap_forwarding(&code_heap
);
224 /* Update word and quotation code pointers */
225 forward_object_xts();
227 /* Actually perform the compaction */
228 compact_heap(&code_heap
);
230 /* Update word and quotation XTs */
233 /* Now update the free list; there will be a single free block at
235 build_free_list(&code_heap
,size
);