#include "master.h" /* Simple code generator used by: - profiler (profiler.c), - quotation compiler (quotations.c), - megamorphic caches (dispatch.c), - polymorphic inline caches (inline_cache.c) */ /* Allocates memory */ void jit_init(F_JIT *jit, CELL jit_type, CELL owner) { jit->owner = owner; REGISTER_ROOT(jit->owner); jit->type = jit_type; jit->code = make_growable_byte_array(); REGISTER_ROOT(jit->code.array); jit->relocation = make_growable_byte_array(); REGISTER_ROOT(jit->relocation.array); jit->literals = make_growable_array(); REGISTER_ROOT(jit->literals.array); if(stack_traces_p()) growable_array_add(&jit->literals,jit->owner); jit->computing_offset_p = false; } /* Facility to convert compiled code offsets to quotation offsets. Call jit_compute_offset() with the compiled code offset, then emit code, and at the end jit->position is the quotation position. */ void jit_compute_position(F_JIT *jit, CELL offset) { jit->computing_offset_p = true; jit->position = 0; jit->offset = offset; } /* Allocates memory */ F_CODE_BLOCK *jit_make_code_block(F_JIT *jit) { growable_byte_array_trim(&jit->code); growable_byte_array_trim(&jit->relocation); growable_array_trim(&jit->literals); F_CODE_BLOCK *code = add_code_block( jit->type, untag_object(jit->code.array), NULL, /* no labels */ jit->relocation.array, jit->literals.array); return code; } void jit_dispose(F_JIT *jit) { UNREGISTER_ROOT(jit->literals.array); UNREGISTER_ROOT(jit->relocation.array); UNREGISTER_ROOT(jit->code.array); UNREGISTER_ROOT(jit->owner); } static F_REL rel_to_emit(F_JIT *jit, CELL template, bool *rel_p) { F_ARRAY *quadruple = untag_object(template); CELL rel_class = array_nth(quadruple,1); CELL rel_type = array_nth(quadruple,2); CELL offset = array_nth(quadruple,3); if(rel_class == F) { *rel_p = false; return 0; } else { *rel_p = true; return (untag_fixnum_fast(rel_type) << 28) | (untag_fixnum_fast(rel_class) << 24) | ((jit->code.count + untag_fixnum_fast(offset))); } } /* Allocates memory */ void jit_emit(F_JIT *jit, CELL template) { REGISTER_ROOT(template); bool rel_p; F_REL rel = rel_to_emit(jit,template,&rel_p); if(rel_p) growable_byte_array_append(&jit->relocation,&rel,sizeof(F_REL)); F_BYTE_ARRAY *code = code_to_emit(template); if(jit->computing_offset_p) { CELL size = array_capacity(code); if(jit->offset == 0) { jit->position--; jit->computing_offset_p = false; } else if(jit->offset < size) { jit->position++; jit->computing_offset_p = false; } else jit->offset -= size; } growable_byte_array_append(&jit->code,code + 1,array_capacity(code)); UNREGISTER_ROOT(template); }