Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jit/jit-compile.c view on Meta::CPAN
state->gen.code_end - state->gen.code_start);
#endif
/* Terminate the debug information and flush it */
if(!_jit_varint_encode_end(&state->gen.offset_encoder))
{
jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
}
state->func->bytecode_offset = _jit_varint_get_data(&state->gen.offset_encoder);
}
}
/*
* Give back the allocated space in case of failure to generate the code.
*/
static void
memory_abort(_jit_compile_t *state)
{
if(state->memory_started)
{
state->memory_started = 0;
/* Release the code space */
_jit_memory_end_function(state->gen.context, JIT_MEMORY_RESTART);
/* Free encoded bytecode offset data */
_jit_varint_free_data(_jit_varint_get_data(&state->gen.offset_encoder));
}
}
/*
* Allocate more code space.
*/
static void
memory_realloc(_jit_compile_t *state)
{
int result;
/* Release the previously allocated code space */
memory_abort(state);
/* Request to extend memory limit and retry space allocation */
_jit_memory_extend_limit(state->gen.context, state->page_factor++);
result = _jit_memory_start_function(state->gen.context, state->func);
if(result != JIT_MEMORY_OK)
{
/* Failed to allocate enough space */
jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
}
/* Start with with allocated space */
memory_start(state);
}
/*
* Prepare function info needed for code generation.
*/
static void
codegen_prepare(_jit_compile_t *state)
{
/* Intuit "nothrow" and "noreturn" flags for this function */
if(!state->func->builder->may_throw)
{
state->func->no_throw = 1;
}
if(!state->func->builder->ordinary_return)
{
state->func->no_return = 1;
}
/* Compute liveness and "next use" information for this function */
_jit_function_compute_liveness(state->func);
/* Allocate global registers to variables within the function */
#ifndef JIT_BACKEND_INTERP
_jit_regs_alloc_global(&state->gen, state->func);
#endif
}
/*
* Run codegen.
*/
static void
codegen(_jit_compile_t *state)
{
jit_function_t func = state->func;
struct jit_gencode *gen = &state->gen;
jit_block_t block;
/* Remember the start code address (due to alignment it may differ from
the available space start - gen->start) */
gen->code_start = gen->ptr;
#ifdef JIT_PROLOG_SIZE
/* Output space for the function prolog */
_jit_gen_check_space(gen, JIT_PROLOG_SIZE);
gen->ptr += JIT_PROLOG_SIZE;
#endif
/* Generate code for the blocks in the function */
block = 0;
while((block = jit_block_next(func, block)) != 0)
{
/* Notify the back end that the block is starting */
_jit_gen_start_block(gen, block);
#ifndef JIT_BACKEND_INTERP
/* Clear the local register assignments */
_jit_regs_init_for_block(gen);
#endif
/* Generate the block's code */
compile_block(gen, func, block);
#ifndef JIT_BACKEND_INTERP
/* Spill all live register values back to their frame positions */
_jit_regs_spill_all(gen);
#endif
/* Notify the back end that the block is finished */
_jit_gen_end_block(gen, block);
}
/* Output the function epilog. All return paths will jump to here */
( run in 0.565 second using v1.01-cache-2.11-cpan-119454b85a5 )