120 lines
2.6 KiB
C
120 lines
2.6 KiB
C
#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);
|
|
}
|
|
|