parrotcode: JIT | |
Contents | C |
src/jit.c - JIT
JIT (Just In Time) compilation converts bytecode to native machine code instructions and executes the generated instruction sequence directly.
Actually it's not really just in time, it's just before this piece of code is used and not per subroutine or even opcode, it works per bytecode segment.
static void insert_fixup_targets(Interp *interpreter, char *branch, size_t limit)
static void make_branch_list(Interp *interpreter, Parrot_jit_optimizer_t *optimizer, opcode_t *cur_op, opcode_t *code_start, opcode_t *code_end)
optimizer->map_branch
parallels the opcodes with a list of branch information and register mapping informationJIT_BRANCH_SOURCE
JIT_BRANCH_TARGET
static void set_register_usage(Interp *interpreter, Parrot_jit_optimizer_t *optimizer, Parrot_jit_optimizer_section_ptr cur_section, op_info_t *op_info, opcode_t *cur_op, opcode_t *code_start)
static void make_sections(Interp *interpreter, Parrot_jit_optimizer_t *optimizer, opcode_t *cur_op, opcode_t *code_start, opcode_t *code_end)
Parrot_jit_vtable_n_op()
does use register mappings.static void make_branch_targets(Interp *interpreter, Parrot_jit_optimizer_t *optimizer, opcode_t *code_start)
static void sort_registers(Interp *interpreter, Parrot_jit_optimizer_t *optimizer, opcode_t *code_start)
static void assign_registers(Interp *interpreter, Parrot_jit_optimizer_t *optimizer, Parrot_jit_optimizer_section_ptr cur_section, opcode_t *code_start, int from_imcc)
map_registers()
to actually assign the Parrot registers to hardware registers. a) allocate non-volatiles first
overhead for jit_begin, jit_end:
- 2 * max_used_non_volatile registers
overhead for register preserving around non-jitted sections:
- only used IN arguments are saved
- only OUT non-volatile arguments are restored
b) allocate volatiles first
no overhead for jit_begin, jit_end
overhead per JITed op that calls a C function:
- 2 * n_used_volatiles_to_preserve for each call
overhead for register preserving around non-jitted sections:
- all volatiles are saved and restored around non-jitted sections
static void map_registers(Interp *interpreter, Parrot_jit_optimizer_t *optimizer, opcode_t *code_start)
static void debug_sections(Interp *interpreter, Parrot_jit_optimizer_t *optimizer, opcode_t *code_start)
static Parrot_jit_optimizer_t *optimize_jit(Interp *interpreter, opcode_t *cur_op, opcode_t *code_start, opcode_t *code_end)
build_asm()
to run the optimizer.static Parrot_jit_optimizer_t *optimize_imcc_jit(Interp *interpreter, opcode_t *cur_op, opcode_t *code_start, opcode_t *code_end, struct PackFile_Segment *jit_seg)
_JIT
section in the packfile.static char *reg_addr(Interp *interpreter, int typ, int i)
size_t reg_offs(Interp *interpreter, int typ, int i)
typ[i]
.Parrot_jit_emit_get_base_reg_no
.static void Parrot_jit_load_registers(Parrot_jit_info_t *jit_info, Interp *interpreter, int volatiles)
volatiles
is true, this code is used to restore these registers in JITted code that calls out to Parrot.static void Parrot_jit_save_registers(Parrot_jit_info_t *jit_info, Interp *interpreter, int volatiles)
volatiles
is true, this code is used to preserve these registers in JITted code that calls out to Parrot.void Parrot_destroy_jit(void *ptr)
jit_f build_asm(Interp *interpreter, opcode_t *pc, opcode_t *code_start, opcode_t *code_end, void *objfile)
parrot -o foo.o foo.imc
void Parrot_jit_newfixup(Parrot_jit_info_t *jit_info)
include/parrot/jit.h, docs/jit.pod,d src/jit_debug.c, jit/$jitcpuarch/jit_emit.h, jit/$jitcpuarch/core.jit.
|