6 static relocation_type relocation_type_of(relocation_entry r)
8 return (relocation_type)((r & 0xf0000000) >> 28);
11 static relocation_class relocation_class_of(relocation_entry r)
13 return (relocation_class)((r & 0x0f000000) >> 24);
16 static cell relocation_offset_of(relocation_entry r)
18 return (r & 0x00ffffff);
21 void flush_icache_for(code_block *block)
23 flush_icache((cell)block,block->size);
26 static int number_of_parameters(relocation_type type)
42 case RT_MEGAMORPHIC_CACHE_HITS:
45 critical_error("Bad rel type",type);
46 return -1; /* Can't happen */
50 void *object_xt(cell obj)
52 switch(tagged<object>(obj).type())
55 return untag<word>(obj)->xt;
57 return untag<quotation>(obj)->xt;
59 critical_error("Expected word or quotation",obj);
64 static void *xt_pic(word *w, cell tagged_quot)
66 if(tagged_quot == F || max_pic_size == 0)
70 quotation *quot = untag<quotation>(tagged_quot);
78 void *word_xt_pic(word *w)
80 return xt_pic(w,w->pic_def);
83 void *word_xt_pic_tail(word *w)
85 return xt_pic(w,w->pic_tail_def);
88 /* References to undefined symbols are patched up to call this function on
90 void undefined_symbol()
92 general_error(ERROR_UNDEFINED_SYMBOL,F,F,NULL);
95 /* Look up an external library symbol referenced by a compiled code block */
96 void *get_rel_symbol(array *literals, cell index)
98 cell symbol = array_nth(literals,index);
99 cell library = array_nth(literals,index + 1);
101 dll *d = (library == F ? NULL : untag<dll>(library));
103 if(d != NULL && !d->dll)
104 return (void *)undefined_symbol;
106 switch(tagged<object>(symbol).type())
108 case BYTE_ARRAY_TYPE:
110 symbol_char *name = alien_offset(symbol);
111 void *sym = ffi_dlsym(d,name);
117 return (void *)undefined_symbol;
123 array *names = untag<array>(symbol);
124 for(i = 0; i < array_capacity(names); i++)
126 symbol_char *name = alien_offset(array_nth(names,i));
127 void *sym = ffi_dlsym(d,name);
132 return (void *)undefined_symbol;
135 critical_error("Bad symbol specifier",symbol);
136 return (void *)undefined_symbol;
140 cell compute_relocation(relocation_entry rel, cell index, code_block *compiled)
142 array *literals = untag<array>(compiled->literals);
143 cell offset = relocation_offset_of(rel) + (cell)compiled->xt();
145 #define ARG array_nth(literals,index)
147 switch(relocation_type_of(rel))
150 return (cell)primitives[untag_fixnum(ARG)];
152 return (cell)get_rel_symbol(literals,index);
156 return (cell)object_xt(ARG);
158 return (cell)word_xt_pic(untag<word>(ARG));
160 return (cell)word_xt_pic_tail(untag<word>(ARG));
163 fixnum arg = untag_fixnum(ARG);
164 return (arg >= 0 ? offset + arg : (cell)(compiled +1) - arg);
167 return (cell)(compiled + 1);
169 return (cell)&stack_chain;
171 return untag_fixnum(ARG);
172 case RT_MEGAMORPHIC_CACHE_HITS:
173 return (cell)&megamorphic_cache_hits;
175 critical_error("Bad rel type",rel);
176 return 0; /* Can't happen */
182 void iterate_relocations(code_block *compiled, relocation_iterator iter)
184 if(compiled->relocation != F)
186 byte_array *relocation = untag<byte_array>(compiled->relocation);
188 cell index = stack_traces_p() ? 1 : 0;
190 cell length = array_capacity(relocation) / sizeof(relocation_entry);
191 for(cell i = 0; i < length; i++)
193 relocation_entry rel = relocation->data<relocation_entry>()[i];
194 iter(rel,index,compiled);
195 index += number_of_parameters(relocation_type_of(rel));
200 /* Store a 32-bit value into a PowerPC LIS/ORI sequence */
201 static void store_address_2_2(cell *ptr, cell value)
203 ptr[-1] = ((ptr[-1] & ~0xffff) | ((value >> 16) & 0xffff));
204 ptr[ 0] = ((ptr[ 0] & ~0xffff) | (value & 0xffff));
207 /* Store a value into a bitfield of a PowerPC instruction */
208 static void store_address_masked(cell *ptr, fixnum value, cell mask, fixnum shift)
210 /* This is unaccurate but good enough */
211 fixnum test = (fixnum)mask >> 1;
212 if(value <= -test || value >= test)
213 critical_error("Value does not fit inside relocation",0);
215 *ptr = ((*ptr & ~mask) | ((value >> shift) & mask));
218 /* Perform a fixup on a code block */
219 void store_address_in_code_block(cell klass, cell offset, fixnum absolute_value)
221 fixnum relative_value = absolute_value - offset;
225 case RC_ABSOLUTE_CELL:
226 *(cell *)offset = absolute_value;
229 *(u32*)offset = absolute_value;
232 *(u32*)offset = relative_value - sizeof(u32);
234 case RC_ABSOLUTE_PPC_2_2:
235 store_address_2_2((cell *)offset,absolute_value);
237 case RC_ABSOLUTE_PPC_2:
238 store_address_masked((cell *)offset,absolute_value,rel_absolute_ppc_2_mask,0);
240 case RC_RELATIVE_PPC_2:
241 store_address_masked((cell *)offset,relative_value,rel_relative_ppc_2_mask,0);
243 case RC_RELATIVE_PPC_3:
244 store_address_masked((cell *)offset,relative_value,rel_relative_ppc_3_mask,0);
246 case RC_RELATIVE_ARM_3:
247 store_address_masked((cell *)offset,relative_value - sizeof(cell) * 2,
248 rel_relative_arm_3_mask,2);
250 case RC_INDIRECT_ARM:
251 store_address_masked((cell *)offset,relative_value - sizeof(cell),
252 rel_indirect_arm_mask,0);
254 case RC_INDIRECT_ARM_PC:
255 store_address_masked((cell *)offset,relative_value - sizeof(cell) * 2,
256 rel_indirect_arm_mask,0);
259 critical_error("Bad rel class",klass);
264 void update_literal_references_step(relocation_entry rel, cell index, code_block *compiled)
266 if(relocation_type_of(rel) == RT_IMMEDIATE)
268 cell offset = relocation_offset_of(rel) + (cell)(compiled + 1);
269 array *literals = untag<array>(compiled->literals);
270 fixnum absolute_value = array_nth(literals,index);
271 store_address_in_code_block(relocation_class_of(rel),offset,absolute_value);
275 /* Update pointers to literals from compiled code. */
276 void update_literal_references(code_block *compiled)
278 if(!compiled->needs_fixup)
280 iterate_relocations(compiled,update_literal_references_step);
281 flush_icache_for(compiled);
285 /* Copy all literals referenced from a code block to newspace. Only for
286 aging and nursery collections */
287 void copy_literal_references(code_block *compiled)
289 if(collecting_gen >= compiled->last_scan)
291 if(collecting_accumulation_gen_p())
292 compiled->last_scan = collecting_gen;
294 compiled->last_scan = collecting_gen + 1;
296 /* initialize chase pointer */
297 cell scan = newspace->here;
299 copy_handle(&compiled->literals);
300 copy_handle(&compiled->relocation);
302 /* do some tracing so that all reachable literals are now
303 at their final address */
304 copy_reachable_objects(scan,&newspace->here);
306 update_literal_references(compiled);
310 /* Compute an address to store at a relocation */
311 void relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled)
314 tagged<array>(compiled->literals).untag_check();
315 tagged<byte_array>(compiled->relocation).untag_check();
318 store_address_in_code_block(relocation_class_of(rel),
319 relocation_offset_of(rel) + (cell)compiled->xt(),
320 compute_relocation(rel,index,compiled));
323 void update_word_references_step(relocation_entry rel, cell index, code_block *compiled)
325 relocation_type type = relocation_type_of(rel);
326 if(type == RT_XT || type == RT_XT_PIC || type == RT_XT_PIC_TAIL)
327 relocate_code_block_step(rel,index,compiled);
330 /* Relocate new code blocks completely; updating references to literals,
331 dlsyms, and words. For all other words in the code heap, we only need
332 to update references to other words, without worrying about literals
334 void update_word_references(code_block *compiled)
336 if(compiled->needs_fixup)
337 relocate_code_block(compiled);
338 /* update_word_references() is always applied to every block in
339 the code heap. Since it resets all call sites to point to
340 their canonical XT (cold entry point for non-tail calls,
341 standard entry point for tail calls), it means that no PICs
342 are referenced after this is done. So instead of polluting
343 the code heap with dead PICs that will be freed on the next
344 GC, we add them to the free list immediately. */
345 else if(compiled->type == PIC_TYPE)
346 heap_free(&code,compiled);
349 iterate_relocations(compiled,update_word_references_step);
350 flush_icache_for(compiled);
354 void update_literal_and_word_references(code_block *compiled)
356 update_literal_references(compiled);
357 update_word_references(compiled);
360 static void check_code_address(cell address)
363 assert(address >= code.seg->start && address < code.seg->end);
367 /* Update references to words. This is done after a new code block
368 is added to the heap. */
370 /* Mark all literals referenced from a word XT. Only for tenured
372 void mark_code_block(code_block *compiled)
374 check_code_address((cell)compiled);
376 mark_block(compiled);
378 copy_handle(&compiled->literals);
379 copy_handle(&compiled->relocation);
382 void mark_stack_frame_step(stack_frame *frame)
384 mark_code_block(frame_code(frame));
387 /* Mark code blocks executing in currently active stack frames. */
388 void mark_active_blocks(context *stacks)
390 if(collecting_gen == data->tenured())
392 cell top = (cell)stacks->callstack_top;
393 cell bottom = (cell)stacks->callstack_bottom;
395 iterate_callstack(top,bottom,mark_stack_frame_step);
399 void mark_object_code_block(object *object)
401 switch(object->h.hi_tag())
405 word *w = (word *)object;
407 mark_code_block(w->code);
409 mark_code_block(w->profiling);
414 quotation *q = (quotation *)object;
416 mark_code_block(q->code);
421 callstack *stack = (callstack *)object;
422 iterate_callstack_object(stack,mark_stack_frame_step);
428 /* Perform all fixups on a code block */
429 void relocate_code_block(code_block *compiled)
431 compiled->last_scan = data->nursery();
432 compiled->needs_fixup = false;
433 iterate_relocations(compiled,relocate_code_block_step);
434 flush_icache_for(compiled);
437 /* Fixup labels. This is done at compile time, not image load time */
438 void fixup_labels(array *labels, code_block *compiled)
441 cell size = array_capacity(labels);
443 for(i = 0; i < size; i += 3)
445 cell klass = untag_fixnum(array_nth(labels,i));
446 cell offset = untag_fixnum(array_nth(labels,i + 1));
447 cell target = untag_fixnum(array_nth(labels,i + 2));
449 store_address_in_code_block(klass,
450 offset + (cell)(compiled + 1),
451 target + (cell)(compiled + 1));
456 code_block *allot_code_block(cell size)
458 heap_block *block = heap_allot(&code,size + sizeof(code_block));
460 /* If allocation failed, do a code GC */
464 block = heap_allot(&code,size + sizeof(code_block));
466 /* Insufficient room even after code GC, give up */
469 cell used, total_free, max_free;
470 heap_usage(&code,&used,&total_free,&max_free);
472 print_string("Code heap stats:\n");
473 print_string("Used: "); print_cell(used); nl();
474 print_string("Total free space: "); print_cell(total_free); nl();
475 print_string("Largest free block: "); print_cell(max_free); nl();
476 fatal_error("Out of memory in add-compiled-block",0);
480 return (code_block *)block;
484 code_block *add_code_block(
491 gc_root<byte_array> code(code_);
492 gc_root<object> labels(labels_);
493 gc_root<byte_array> relocation(relocation_);
494 gc_root<array> literals(literals_);
496 cell code_length = align8(array_capacity(code.untagged()));
497 code_block *compiled = allot_code_block(code_length);
499 /* compiled header */
500 compiled->type = type;
501 compiled->last_scan = data->nursery();
502 compiled->needs_fixup = true;
503 compiled->relocation = relocation.value();
505 /* slight space optimization */
506 if(literals.type() == ARRAY_TYPE && array_capacity(literals.untagged()) == 0)
507 compiled->literals = F;
509 compiled->literals = literals.value();
512 memcpy(compiled + 1,code.untagged() + 1,code_length);
515 if(labels.value() != F)
516 fixup_labels(labels.as<array>().untagged(),compiled);
518 /* next time we do a minor GC, we have to scan the code heap for
520 last_code_heap_scan = data->nursery();