3 void flush_icache_for(F_CODE_BLOCK
*compiled
)
5 CELL start
= (CELL
)(compiled
+ 1);
6 flush_icache(start
,compiled
->code_length
);
9 void iterate_relocations(F_CODE_BLOCK
*compiled
, RELOCATION_ITERATOR iter
)
11 if(compiled
->relocation
!= F
)
13 F_BYTE_ARRAY
*relocation
= untag_object(compiled
->relocation
);
15 F_REL
*rel
= (F_REL
*)(relocation
+ 1);
16 F_REL
*rel_end
= (F_REL
*)((char *)rel
+ byte_array_capacity(relocation
));
26 /* Store a 32-bit value into a PowerPC LIS/ORI sequence */
27 INLINE
void store_address_2_2(CELL cell
, CELL value
)
29 put(cell
- CELLS
,((get(cell
- CELLS
) & ~0xffff) | ((value
>> 16) & 0xffff)));
30 put(cell
,((get(cell
) & ~0xffff) | (value
& 0xffff)));
33 /* Store a value into a bitfield of a PowerPC instruction */
34 INLINE
void store_address_masked(CELL cell
, F_FIXNUM value
, CELL mask
, F_FIXNUM shift
)
36 /* This is unaccurate but good enough */
37 F_FIXNUM test
= (F_FIXNUM
)mask
>> 1;
38 if(value
<= -test
|| value
>= test
)
39 critical_error("Value does not fit inside relocation",0);
41 u32 original
= *(u32
*)cell
;
43 *(u32
*)cell
= (original
| ((value
>> shift
) & mask
));
46 /* Perform a fixup on a code block */
47 void store_address_in_code_block(CELL
class, CELL offset
, F_FIXNUM absolute_value
)
49 F_FIXNUM relative_value
= absolute_value
- offset
;
53 case RC_ABSOLUTE_CELL
:
54 put(offset
,absolute_value
);
57 *(u32
*)offset
= absolute_value
;
60 *(u32
*)offset
= relative_value
- sizeof(u32
);
62 case RC_ABSOLUTE_PPC_2_2
:
63 store_address_2_2(offset
,absolute_value
);
65 case RC_RELATIVE_PPC_2
:
66 store_address_masked(offset
,relative_value
,REL_RELATIVE_PPC_2_MASK
,0);
68 case RC_RELATIVE_PPC_3
:
69 store_address_masked(offset
,relative_value
,REL_RELATIVE_PPC_3_MASK
,0);
71 case RC_RELATIVE_ARM_3
:
72 store_address_masked(offset
,relative_value
- CELLS
* 2,
73 REL_RELATIVE_ARM_3_MASK
,2);
76 store_address_masked(offset
,relative_value
- CELLS
,
77 REL_INDIRECT_ARM_MASK
,0);
79 case RC_INDIRECT_ARM_PC
:
80 store_address_masked(offset
,relative_value
- CELLS
* 2,
81 REL_INDIRECT_ARM_MASK
,0);
84 critical_error("Bad rel class",class);
89 void update_literal_references_step(F_REL
*rel
, F_CODE_BLOCK
*compiled
)
91 if(REL_TYPE(rel
) == RT_IMMEDIATE
)
93 CELL offset
= rel
->offset
+ (CELL
)(compiled
+ 1);
94 F_ARRAY
*literals
= untag_object(compiled
->literals
);
95 F_FIXNUM absolute_value
= array_nth(literals
,REL_ARGUMENT(rel
));
96 store_address_in_code_block(REL_CLASS(rel
),offset
,absolute_value
);
100 /* Update pointers to literals from compiled code. */
101 void update_literal_references(F_CODE_BLOCK
*compiled
)
103 iterate_relocations(compiled
,update_literal_references_step
);
104 flush_icache_for(compiled
);
107 /* Copy all literals referenced from a code block to newspace. Only for
108 aging and nursery collections */
109 void copy_literal_references(F_CODE_BLOCK
*compiled
)
111 if(collecting_gen
>= compiled
->last_scan
)
113 if(collecting_accumulation_gen_p())
114 compiled
->last_scan
= collecting_gen
;
116 compiled
->last_scan
= collecting_gen
+ 1;
118 /* initialize chase pointer */
119 CELL scan
= newspace
->here
;
121 copy_handle(&compiled
->literals
);
122 copy_handle(&compiled
->relocation
);
124 /* do some tracing so that all reachable literals are now
125 at their final address */
126 copy_reachable_objects(scan
,&newspace
->here
);
128 update_literal_references(compiled
);
132 CELL
object_xt(CELL obj
)
134 if(type_of(obj
) == WORD_TYPE
)
135 return (CELL
)untag_word(obj
)->xt
;
137 return (CELL
)untag_quotation(obj
)->xt
;
140 void update_word_references_step(F_REL
*rel
, F_CODE_BLOCK
*compiled
)
142 if(REL_TYPE(rel
) == RT_XT
)
144 CELL offset
= rel
->offset
+ (CELL
)(compiled
+ 1);
145 F_ARRAY
*literals
= untag_object(compiled
->literals
);
146 CELL xt
= object_xt(array_nth(literals
,REL_ARGUMENT(rel
)));
147 store_address_in_code_block(REL_CLASS(rel
),offset
,xt
);
151 /* Relocate new code blocks completely; updating references to literals,
152 dlsyms, and words. For all other words in the code heap, we only need
153 to update references to other words, without worrying about literals
155 void update_word_references(F_CODE_BLOCK
*compiled
)
157 if(compiled
->needs_fixup
)
158 relocate_code_block(compiled
);
161 iterate_relocations(compiled
,update_word_references_step
);
162 flush_icache_for(compiled
);
166 /* Update references to words. This is done after a new code block
167 is added to the heap. */
169 /* Mark all literals referenced from a word XT. Only for tenured
171 void mark_code_block(F_CODE_BLOCK
*compiled
)
173 mark_block(compiled_to_block(compiled
));
175 copy_handle(&compiled
->literals
);
176 copy_handle(&compiled
->relocation
);
178 flush_icache_for(compiled
);
181 void mark_stack_frame_step(F_STACK_FRAME
*frame
)
183 mark_code_block(frame_code(frame
));
186 /* Mark code blocks executing in currently active stack frames. */
187 void mark_active_blocks(F_CONTEXT
*stacks
)
189 if(collecting_gen
== TENURED
)
191 CELL top
= (CELL
)stacks
->callstack_top
;
192 CELL bottom
= (CELL
)stacks
->callstack_bottom
;
194 iterate_callstack(top
,bottom
,mark_stack_frame_step
);
198 void mark_object_code_block(CELL scan
)
204 switch(object_type(scan
))
207 word
= (F_WORD
*)scan
;
208 mark_code_block(word
->code
);
210 mark_code_block(word
->profiling
);
213 quot
= (F_QUOTATION
*)scan
;
214 if(quot
->compiledp
!= F
)
215 mark_code_block(quot
->code
);
218 stack
= (F_CALLSTACK
*)scan
;
219 iterate_callstack_object(stack
,mark_stack_frame_step
);
224 /* References to undefined symbols are patched up to call this function on
226 void undefined_symbol(void)
228 general_error(ERROR_UNDEFINED_SYMBOL
,F
,F
,NULL
);
231 /* Look up an external library symbol referenced by a compiled code block */
232 void *get_rel_symbol(F_REL
*rel
, F_ARRAY
*literals
)
234 CELL arg
= REL_ARGUMENT(rel
);
235 CELL symbol
= array_nth(literals
,arg
);
236 CELL library
= array_nth(literals
,arg
+ 1);
238 F_DLL
*dll
= (library
== F
? NULL
: untag_dll(library
));
240 if(dll
!= NULL
&& !dll
->dll
)
241 return undefined_symbol
;
243 if(type_of(symbol
) == BYTE_ARRAY_TYPE
)
245 F_SYMBOL
*name
= alien_offset(symbol
);
246 void *sym
= ffi_dlsym(dll
,name
);
251 else if(type_of(symbol
) == ARRAY_TYPE
)
254 F_ARRAY
*names
= untag_object(symbol
);
255 for(i
= 0; i
< array_capacity(names
); i
++)
257 F_SYMBOL
*name
= alien_offset(array_nth(names
,i
));
258 void *sym
= ffi_dlsym(dll
,name
);
265 return undefined_symbol
;
268 /* Compute an address to store at a relocation */
269 void relocate_code_block_step(F_REL
*rel
, F_CODE_BLOCK
*compiled
)
271 CELL offset
= rel
->offset
+ (CELL
)(compiled
+ 1);
272 F_ARRAY
*literals
= untag_object(compiled
->literals
);
273 F_FIXNUM absolute_value
;
275 switch(REL_TYPE(rel
))
278 absolute_value
= (CELL
)primitives
[REL_ARGUMENT(rel
)];
281 absolute_value
= (CELL
)get_rel_symbol(rel
,literals
);
284 absolute_value
= array_nth(literals
,REL_ARGUMENT(rel
));
287 absolute_value
= object_xt(array_nth(literals
,REL_ARGUMENT(rel
)));
290 absolute_value
= rel
->offset
+ (CELL
)(compiled
+ 1) + (short)REL_ARGUMENT(rel
);
293 absolute_value
= (CELL
)(compiled
+ 1) + REL_ARGUMENT(rel
);
296 absolute_value
= (CELL
)&stack_chain
;
299 critical_error("Bad rel type",rel
->type
);
300 return; /* Can't happen */
303 store_address_in_code_block(REL_CLASS(rel
),offset
,absolute_value
);
306 /* Perform all fixups on a code block */
307 void relocate_code_block(F_CODE_BLOCK
*compiled
)
309 compiled
->last_scan
= NURSERY
;
310 compiled
->needs_fixup
= false;
311 iterate_relocations(compiled
,relocate_code_block_step
);
312 flush_icache_for(compiled
);
315 /* Fixup labels. This is done at compile time, not image load time */
316 void fixup_labels(F_ARRAY
*labels
, CELL code_format
, F_CODE_BLOCK
*compiled
)
319 CELL size
= array_capacity(labels
);
321 for(i
= 0; i
< size
; i
+= 3)
323 CELL
class = to_fixnum(array_nth(labels
,i
));
324 CELL offset
= to_fixnum(array_nth(labels
,i
+ 1));
325 CELL target
= to_fixnum(array_nth(labels
,i
+ 2));
327 store_address_in_code_block(class,
328 offset
+ (CELL
)(compiled
+ 1),
329 target
+ (CELL
)(compiled
+ 1));
333 /* Write a sequence of integers to memory, with 'format' bytes per integer */
334 void deposit_integers(CELL here
, F_ARRAY
*array
, CELL format
)
336 CELL count
= array_capacity(array
);
339 for(i
= 0; i
< count
; i
++)
341 F_FIXNUM value
= to_fixnum(array_nth(array
,i
));
343 bput(here
+ i
,value
);
344 else if(format
== sizeof(unsigned int))
345 *(unsigned int *)(here
+ format
* i
) = value
;
346 else if(format
== sizeof(CELL
))
347 *(CELL
*)(here
+ format
* i
) = value
;
349 critical_error("Bad format in deposit_integers()",format
);
353 bool stack_traces_p(void)
355 return to_boolean(userenv
[STACK_TRACES_ENV
]);
358 CELL
compiled_code_format(void)
360 return untag_fixnum_fast(userenv
[JIT_CODE_FORMAT
]);
364 void *allot_code_block(CELL size
)
366 void *start
= heap_allot(&code_heap
,size
);
368 /* If allocation failed, do a code GC */
372 start
= heap_allot(&code_heap
,size
);
374 /* Insufficient room even after code GC, give up */
377 CELL used
, total_free
, max_free
;
378 heap_usage(&code_heap
,&used
,&total_free
,&max_free
);
380 print_string("Code heap stats:\n");
381 print_string("Used: "); print_cell(used
); nl();
382 print_string("Total free space: "); print_cell(total_free
); nl();
383 print_string("Largest free block: "); print_cell(max_free
); nl();
384 fatal_error("Out of memory in add-compiled-block",0);
392 F_CODE_BLOCK
*add_compiled_block(
399 CELL code_format
= compiled_code_format();
400 CELL code_length
= align8(array_capacity(code
) * code_format
);
402 REGISTER_ROOT(literals
);
403 REGISTER_ROOT(relocation
);
404 REGISTER_UNTAGGED(code
);
405 REGISTER_UNTAGGED(labels
);
407 F_CODE_BLOCK
*compiled
= allot_code_block(sizeof(F_CODE_BLOCK
) + code_length
);
409 UNREGISTER_UNTAGGED(labels
);
410 UNREGISTER_UNTAGGED(code
);
411 UNREGISTER_ROOT(relocation
);
412 UNREGISTER_ROOT(literals
);
414 /* compiled header */
415 compiled
->type
= type
;
416 compiled
->last_scan
= NURSERY
;
417 compiled
->needs_fixup
= true;
418 compiled
->code_length
= code_length
;
419 compiled
->literals
= literals
;
420 compiled
->relocation
= relocation
;
423 deposit_integers((CELL
)(compiled
+ 1),code
,code_format
);
426 if(labels
) fixup_labels(labels
,code_format
,compiled
);
428 /* next time we do a minor GC, we have to scan the code heap for
430 last_code_heap_scan
= NURSERY
;