function to check the available cache space.
* jit/jit-compile.c: use internal exception to handle the cache full
condition.
+ * jit/jit-reg-alloc.h, jit/jit-reg-alloc.c, jit/jit-rules-alpha.c,
+ * jit/jit-rules-arm.c, jit/jit-rules-interp.c, jit/jit-rules-x86.c,
+ * jit/jit-rules-x86-64.c, tools/gen-rules-parser.y: use internal
+ exceptions to signal the cache full condition and other codegen
+ errors.
+ * jit/jit-reg-alloc.h, jit/jit-reg-alloc.c (_jit_regs_inst_ptr)
+ (_jit_regs_end): remove functions.
2009-10-13 Gopal V <gopalv@php.net>
/*
* Determine value flags.
*/
-static int
+static void
set_regdesc_flags(jit_gencode_t gen, _jit_regs_t *regs, int index)
{
_jit_regdesc_t *desc;
desc = ®s->descs[index];
if(desc->reg < 0 || desc->duplicate)
{
- return 1;
+ return;
}
/* See if the value clobbers the register it is assigned to. */
printf("copy = %d\n", desc->copy);
printf("kill = %d\n", desc->kill);
#endif
-
- return 1;
}
/*
return 0;
}
-static int
+static void
choose_scratch_register(jit_gencode_t gen, _jit_regs_t *regs, int index)
{
_jit_regclass_t *regclass;
if(suitable_reg >= 0)
{
set_scratch_register(gen, regs, index, suitable_reg);
- return 1;
}
-
- return 0;
+ else
+ {
+ jit_exception_builtin(JIT_RESULT_COMPILE_ERROR);
+ }
}
-static int
+static void
choose_output_register(jit_gencode_t gen, _jit_regs_t *regs)
{
_jit_regclass_t *regclass;
if(suitable_reg >= 0)
{
set_regdesc_register(gen, regs, 0, suitable_reg, suitable_other_reg);
- return 1;
}
-
- return 0;
+ else
+ {
+ jit_exception_builtin(JIT_RESULT_COMPILE_ERROR);
+ }
}
/*
}
}
-static int
+static void
choose_input_register(jit_gencode_t gen, _jit_regs_t *regs, int index)
{
_jit_regclass_t *regclass;
desc = ®s->descs[index];
if(!desc->value)
{
- return 0;
+ jit_exception_builtin(JIT_RESULT_COMPILE_ERROR);
}
regclass = regs->descs[index].regclass;
if(suitable_reg >= 0)
{
set_regdesc_register(gen, regs, index, suitable_reg, suitable_other_reg);
- return 1;
}
-
- return 0;
+ else
+ {
+ jit_exception_builtin(JIT_RESULT_COMPILE_ERROR);
+ }
}
/*
}
}
-int
+void
_jit_regs_assign(jit_gencode_t gen, _jit_regs_t *regs)
{
int index;
{
if(regs->ternary)
{
- if(!choose_input_register(gen, regs, 0))
- {
- return 0;
- }
+ choose_input_register(gen, regs, 0);
}
else
{
- if(!choose_output_register(gen, regs))
- {
- return 0;
- }
+ choose_output_register(gen, regs);
}
}
if(regs->ternary)
}
if(regs->descs[1].value && regs->descs[1].reg < 0)
{
- if(!choose_input_register(gen, regs, 1))
- {
- return 0;
- }
+ choose_input_register(gen, regs, 1);
}
check_duplicate_value(regs, ®s->descs[1], ®s->descs[2]);
if(regs->descs[2].value && regs->descs[2].reg < 0)
{
- if(!choose_input_register(gen, regs, 2))
- {
- return 0;
- }
+ choose_input_register(gen, regs, 2);
}
/* Assign scratch registers. */
{
if(regs->scratch[index].reg < 0)
{
- if(choose_scratch_register(gen, regs, index) < 0)
- {
- return 0;
- }
+ choose_scratch_register(gen, regs, index);
}
}
/* Collect information about registers. */
- if(!set_regdesc_flags(gen, regs, 0))
- {
- return 0;
- }
- if(!set_regdesc_flags(gen, regs, 1))
- {
- return 0;
- }
- if(!set_regdesc_flags(gen, regs, 2))
- {
- return 0;
- }
-
- return 1;
+ set_regdesc_flags(gen, regs, 0);
+ set_regdesc_flags(gen, regs, 1);
+ set_regdesc_flags(gen, regs, 2);
}
-int
+void
_jit_regs_gen(jit_gencode_t gen, _jit_regs_t *regs)
{
int reg;
{
/* After the branch is taken there is no way
to load the global register back. */
- return 0;
+ jit_exception_builtin(JIT_RESULT_COMPILE_ERROR);
}
_jit_gen_spill_global(gen, reg, 0);
continue;
#ifdef JIT_REG_DEBUG
dump_regs(gen, "leave _jit_regs_gen");
#endif
- return 1;
}
#ifdef JIT_REG_STACK
#endif
}
-unsigned char *
-_jit_regs_inst_ptr(jit_gencode_t gen, int space)
-{
- unsigned char *inst;
-
- inst = (unsigned char *)(gen->posn.ptr);
- if(!jit_cache_check_for_n(&(gen->posn), space))
- {
- jit_cache_mark_full(&(gen->posn));
- return 0;
- }
-
- return inst;
-}
-
-unsigned char *
-_jit_regs_begin(jit_gencode_t gen, _jit_regs_t *regs, int space)
-{
- if(!_jit_regs_assign(gen, regs))
- {
- return 0;
- }
- if(!_jit_regs_gen(gen, regs))
- {
- return 0;
- }
-
- return _jit_regs_inst_ptr(gen, space);
-}
-
void
-_jit_regs_end(jit_gencode_t gen, _jit_regs_t *regs, unsigned char *inst)
+_jit_regs_begin(jit_gencode_t gen, _jit_regs_t *regs, int space)
{
- gen->posn.ptr = inst;
- _jit_regs_commit(gen, regs);
+ _jit_regs_assign(gen, regs);
+ _jit_regs_gen(gen, regs);
+ _jit_cache_check_space(&gen->posn, space);
}
void _jit_regs_clobber_class(jit_gencode_t gen, _jit_regs_t *regs, _jit_regclass_t *regclass);
void _jit_regs_clobber_all(jit_gencode_t gen, _jit_regs_t *regs);
-int _jit_regs_assign(jit_gencode_t gen, _jit_regs_t *regs);
-int _jit_regs_gen(jit_gencode_t gen, _jit_regs_t *regs);
+void _jit_regs_assign(jit_gencode_t gen, _jit_regs_t *regs);
+void _jit_regs_gen(jit_gencode_t gen, _jit_regs_t *regs);
#ifdef JIT_REG_STACK
int _jit_regs_select(_jit_regs_t *regs);
#endif
+
void _jit_regs_commit(jit_gencode_t gen, _jit_regs_t *regs);
int _jit_regs_get_dest(_jit_regs_t *regs);
int _jit_regs_get_value2_other(_jit_regs_t *regs);
int _jit_regs_get_scratch(_jit_regs_t *regs, int index);
-unsigned char *_jit_regs_inst_ptr(jit_gencode_t gen, int space);
-unsigned char *_jit_regs_begin(jit_gencode_t gen, _jit_regs_t *regs, int space);
-void _jit_regs_end(jit_gencode_t gen, _jit_regs_t *regs, unsigned char *inst);
+void _jit_regs_begin(jit_gencode_t gen, _jit_regs_t *regs, int space);
#ifdef __cplusplus
};
/*
* Setup or teardown the alpha code output process.
*/
-#define jit_cache_setup_output(needed) \
- alpha_inst inst = (alpha_inst) gen->posn.ptr; \
- if(!jit_cache_check_for_n(&(gen->posn), (needed))) { \
- jit_cache_mark_full(&(gen->posn)); \
- return; \
- } \
+#define jit_cache_setup_output(needed) \
+ alpha_inst inst = (alpha_inst) gen->posn.ptr; \
+ _jit_cache_check_space(&gen->posn, (needed))
#define jit_cache_end_output() \
gen->posn.ptr = (unsigned char*) inst
void *ptr, *entry;
alpha_inst inst = (alpha_inst) gen->posn.ptr;
- if (!jit_cache_check_for_n(&(gen->posn), 8*6)) {
- jit_cache_mark_full(&(gen->posn));
- return NULL;
- }
+ _jit_cache_check_space(&gen->posn, 8*6);
ptr = (void *)&(func->entry_point);
entry = gen->posn.ptr;
_jit_regs_spill_all(gen);
_jit_gen_fix_value(insn->value1);
jit_gen_load_inst_ptr(gen, inst);
- if(!jit_cache_check_for_n(&(gen->posn), 128))
- {
- jit_cache_mark_full(&(gen->posn));
- return;
- }
+ _jit_cache_check_space(&gen->posn, 128);
reg = _jit_reg_info[reg].cpu_reg;
inst = memory_copy(gen, inst, reg, (int)(insn->value2->address),
ARM_FP, insn->value1->frame_offset,
/*
* Write "n" bytes to the cache, rounded up to a multiple of "void *".
*/
-#define jit_cache_add_n(posn,buf,size) \
- do { \
- unsigned int __size = \
+#define jit_cache_add_n(posn,buf,size) \
+ do { \
+ unsigned int __size = \
((size) + sizeof(void *) - 1) & ~(sizeof(void *) - 1); \
- if(jit_cache_check_for_n((posn), __size)) \
- { \
- jit_memcpy((posn)->ptr, (buf), (size)); \
- (posn)->ptr += __size; \
- } \
- else \
- { \
- jit_cache_mark_full((posn)); \
- } \
+ _jit_cache_check_space((posn), __size); \
+ jit_memcpy((posn)->ptr, (buf), (size)); \
+ (posn)->ptr += __size; \
} while (0)
/*
/*
* Setup or teardown the x86 code output process.
*/
-#define jit_cache_setup_output(needed) \
- unsigned char *inst = gen->posn.ptr; \
- if(!jit_cache_check_for_n(&(gen->posn), (needed))) \
- { \
- jit_cache_mark_full(&(gen->posn)); \
- return; \
- }
+#define jit_cache_setup_output(needed) \
+ unsigned char *inst = gen->posn.ptr; \
+ _jit_cache_check_space(&gen->posn, (needed))
+
#define jit_cache_end_output() \
gen->posn.ptr = inst
floating-point register whose value hasn't been used yet */
if(!value_used && IS_FPU_REG(reg))
{
- if(jit_cache_check_for_n(&(gen->posn), 2))
- {
- x86_fstp(gen->posn.ptr, reg - X86_64_REG_ST0);
- }
- else
- {
- jit_cache_mark_full(&(gen->posn));
- }
+ _jit_cache_check_space(&gen->posn, 2);
+ x86_fstp(gen->posn.ptr, reg - X86_64_REG_ST0);
}
}
jit_int *next;
/* Bail out if there is insufficient space for the epilog */
- if(!jit_cache_check_for_n(&(gen->posn), 48))
- {
- jit_cache_mark_full(&(gen->posn));
- return;
- }
+ _jit_cache_check_space(&gen->posn, 48);
inst = gen->posn.ptr;
void **fixup;
void **next;
- /* Bail out if there is insufficient space for the epilog */
- if(!jit_cache_check_for_n(&(gen->posn), 48))
- {
- jit_cache_mark_full(&(gen->posn));
- return;
- }
+ /* Check if there is sufficient space for the epilog */
+ _jit_cache_check_space(&gen->posn, 48);
#if JIT_APPLY_X86_FASTCALL == 1
/* Determine the number of parameter bytes to pop when we return */
void *_jit_gen_redirector(jit_gencode_t gen, jit_function_t func)
{
void *ptr, *entry;
- if(!jit_cache_check_for_n(&(gen->posn), 8))
- {
- jit_cache_mark_full(&(gen->posn));
- return 0;
- }
+ _jit_cache_check_space(&gen->posn, 8);
ptr = (void *)&(func->entry_point);
entry = gen->posn.ptr;
x86_jump_mem(gen->posn.ptr, ptr);
/*
* Setup or teardown the x86 code output process.
*/
-#define jit_cache_setup_output(needed) \
- unsigned char *inst = gen->posn.ptr; \
- if(!jit_cache_check_for_n(&(gen->posn), (needed))) \
- { \
- jit_cache_mark_full(&(gen->posn)); \
- return; \
- }
+#define jit_cache_setup_output(needed) \
+ unsigned char *inst = gen->posn.ptr; \
+ _jit_cache_check_space(&gen->posn, (needed))
+
#define jit_cache_end_output() \
gen->posn.ptr = inst
jit_cache_end_output();
}
-void _jit_gen_free_reg(jit_gencode_t gen, int reg,
- int other_reg, int value_used)
+void
+_jit_gen_free_reg(jit_gencode_t gen, int reg, int other_reg, int value_used)
{
/* We only need to take explicit action if we are freeing a
floating-point register whose value hasn't been used yet */
if(!value_used && IS_FLOAT_REG(reg))
{
- if(jit_cache_check_for_n(&(gen->posn), 2))
- {
- x86_fstp(gen->posn.ptr, reg - X86_REG_ST0);
- }
- else
- {
- jit_cache_mark_full(&(gen->posn));
- }
+ _jit_cache_check_space(&gen->posn, 2);
+ x86_fstp(gen->posn.ptr, reg - X86_REG_ST0);
}
}
while(level > 0)
{
gen->posn.ptr = inst;
- if(!jit_cache_check_for_n(&(gen->posn), 16))
- {
- jit_cache_mark_full(&(gen->posn));
- return;
- }
+ _jit_cache_check_space(&gen->posn, 16);
x86_mov_reg_membase(inst, cpu_reg, cpu_reg, 0, sizeof(void *));
--level;
}
reg = _jit_regs_load_value
(gen, func->builder->parent_frame, 1, 0);
inst = gen->posn.ptr;
- if(!jit_cache_check_for_n(&(gen->posn), 32 + level * 8))
- {
- jit_cache_mark_full(&(gen->posn));
- return;
- }
+ _jit_cache_check_space(&gen->posn, 32 + level * 8);
reg = _jit_reg_info[reg].cpu_reg;
while(level > 0)
{
_jit_regs_spill_all(gen);
_jit_gen_fix_value(insn->value1);
inst = gen->posn.ptr;
- if(!jit_cache_check_for_n(&(gen->posn), 128))
- {
- jit_cache_mark_full(&(gen->posn));
- return;
- }
+ _jit_cache_check_space(&gen->posn, 128);
reg = _jit_reg_info[reg].cpu_reg;
inst = memory_copy(gen, inst, reg, (int)(insn->value2->address),
X86_EBP, insn->value1->frame_offset,
{
if(contains_registers)
{
- printf("\t\tif(!_jit_regs_assign(gen, ®s))\n");
- printf("\t\t{\n");
- printf("\t\t\treturn;\n");
- printf("\t\t}\n");
- printf("\t\tif(!_jit_regs_gen(gen, ®s))\n");
- printf("\t\t{\n");
- printf("\t\t\treturn;\n");
- printf("\t\t}\n");
+ printf("\t\t_jit_regs_assign(gen, ®s);\n");
+ printf("\t\t_jit_regs_gen(gen, ®s);\n");
}
printf("\t\tjit_gen_load_inst_ptr(gen, inst);\n");
}
if(contains_registers)
{
- printf("\t\tif(!(inst = (%s)_jit_regs_begin(gen, ®s, ", gensel_inst_type);
+ printf("\t\t_jit_regs_begin(gen, ®s, ");
}
else
{
- printf("\t\tinst = (%s)(gen->posn.ptr);\n", gensel_inst_type);
- printf("\t\tif(!jit_cache_check_for_n(&(gen->posn), ");
+ printf("\t\t_jit_cache_check_space(&gen->posn, ");
}
if(space && space->values && space->values->value)
{
? gensel_reserve_space
: gensel_reserve_more_space));
}
- if(contains_registers)
- {
- printf(")))\n");
- printf("\t\t{\n");
- printf("\t\t\treturn;\n");
- printf("\t\t}\n");
- }
- else
- {
- printf("))\n");
- printf("\t\t{\n");
- printf("\t\t\tjit_cache_mark_full(&(gen->posn));\n");
- printf("\t\t\treturn;\n");
- printf("\t\t}\n");
- }
+ printf(");\n");
}
+ printf("\t\tinst = (%s)(gen->posn.ptr);\n", gensel_inst_type);
+
regs = 0;
imms = 0;
locals = 0;
if(gensel_new_inst_type)
{
printf("\t\tjit_gen_save_inst_ptr(gen, inst);\n");
- if(contains_registers)
- {
- printf("\t\t_jit_regs_commit(gen, ®s);\n");
- }
- }
- else if(contains_registers)
- {
- printf("\t\t_jit_regs_end(gen, ®s, (unsigned char *)inst);\n");
}
else
{
printf("\t\tgen->posn.ptr = (unsigned char *)inst;\n");
}
+ if(contains_registers)
+ {
+ printf("\t\t_jit_regs_commit(gen, ®s);\n");
+ }
printf("\t}\n");
first = 0;