From b1a26ec0307fb1036a1a0ba4252f617e27b66278 Mon Sep 17 00:00:00 2001 From: Aleksey Demakov Date: Fri, 30 Oct 2009 04:41:57 +0600 Subject: [PATCH] handle codegen errors with internal exceptions --- ChangeLog | 7 +++ jit/jit-reg-alloc.c | 121 +++++++++++---------------------------- jit/jit-reg-alloc.h | 9 ++- jit/jit-rules-alpha.c | 14 ++--- jit/jit-rules-arm.ins | 6 +- jit/jit-rules-interp.c | 18 ++---- jit/jit-rules-x86-64.c | 27 +++------ jit/jit-rules-x86.c | 39 ++++--------- jit/jit-rules-x86.ins | 18 +----- tools/gen-rules-parser.y | 45 ++++----------- 10 files changed, 87 insertions(+), 217 deletions(-) diff --git a/ChangeLog b/ChangeLog index 688bd9b..d939080 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,13 @@ 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 diff --git a/jit/jit-reg-alloc.c b/jit/jit-reg-alloc.c index a16f4d2..3dad531 100644 --- a/jit/jit-reg-alloc.c +++ b/jit/jit-reg-alloc.c @@ -600,7 +600,7 @@ set_regdesc_register(jit_gencode_t gen, _jit_regs_t *regs, int index, int reg, i /* * Determine value flags. */ -static int +static void set_regdesc_flags(jit_gencode_t gen, _jit_regs_t *regs, int index) { _jit_regdesc_t *desc; @@ -615,7 +615,7 @@ set_regdesc_flags(jit_gencode_t gen, _jit_regs_t *regs, int index) desc = ®s->descs[index]; if(desc->reg < 0 || desc->duplicate) { - return 1; + return; } /* See if the value clobbers the register it is assigned to. */ @@ -863,8 +863,6 @@ set_regdesc_flags(jit_gencode_t gen, _jit_regs_t *regs, int index) printf("copy = %d\n", desc->copy); printf("kill = %d\n", desc->kill); #endif - - return 1; } /* @@ -1044,7 +1042,7 @@ thrashes_value(jit_gencode_t gen, return 0; } -static int +static void choose_scratch_register(jit_gencode_t gen, _jit_regs_t *regs, int index) { _jit_regclass_t *regclass; @@ -1126,13 +1124,14 @@ choose_scratch_register(jit_gencode_t gen, _jit_regs_t *regs, int index) 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; @@ -1310,10 +1309,11 @@ choose_output_register(jit_gencode_t gen, _jit_regs_t *regs) 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); + } } /* @@ -1359,7 +1359,7 @@ choose_input_order(jit_gencode_t gen, _jit_regs_t *regs) } } -static int +static void choose_input_register(jit_gencode_t gen, _jit_regs_t *regs, int index) { _jit_regclass_t *regclass; @@ -1379,7 +1379,7 @@ choose_input_register(jit_gencode_t gen, _jit_regs_t *regs, int index) desc = ®s->descs[index]; if(!desc->value) { - return 0; + jit_exception_builtin(JIT_RESULT_COMPILE_ERROR); } regclass = regs->descs[index].regclass; @@ -1490,10 +1490,11 @@ choose_input_register(jit_gencode_t gen, _jit_regs_t *regs, int index) 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); + } } /* @@ -3319,7 +3320,7 @@ _jit_regs_clobber_all(jit_gencode_t gen, _jit_regs_t *regs) } } -int +void _jit_regs_assign(jit_gencode_t gen, _jit_regs_t *regs) { int index; @@ -3352,17 +3353,11 @@ _jit_regs_assign(jit_gencode_t gen, _jit_regs_t *regs) { 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) @@ -3383,18 +3378,12 @@ _jit_regs_assign(jit_gencode_t gen, _jit_regs_t *regs) } 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. */ @@ -3402,31 +3391,17 @@ _jit_regs_assign(jit_gencode_t gen, _jit_regs_t *regs) { 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; @@ -3469,7 +3444,7 @@ _jit_regs_gen(jit_gencode_t gen, _jit_regs_t *regs) { /* 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; @@ -3590,7 +3565,6 @@ _jit_regs_gen(jit_gencode_t gen, _jit_regs_t *regs) #ifdef JIT_REG_DEBUG dump_regs(gen, "leave _jit_regs_gen"); #endif - return 1; } #ifdef JIT_REG_STACK @@ -3747,39 +3721,10 @@ _jit_regs_commit(jit_gencode_t gen, _jit_regs_t *regs) #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); } diff --git a/jit/jit-reg-alloc.h b/jit/jit-reg-alloc.h index 483b5c6..32adb6f 100644 --- a/jit/jit-reg-alloc.h +++ b/jit/jit-reg-alloc.h @@ -168,11 +168,12 @@ void _jit_regs_clobber(_jit_regs_t *regs, int reg); 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); @@ -183,9 +184,7 @@ int _jit_regs_get_value1_other(_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 }; diff --git a/jit/jit-rules-alpha.c b/jit/jit-rules-alpha.c index bdd51fb..2836c4a 100644 --- a/jit/jit-rules-alpha.c +++ b/jit/jit-rules-alpha.c @@ -78,12 +78,9 @@ int _alpha_has_ieeefp() { /* * 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 @@ -533,10 +530,7 @@ void *_jit_gen_redirector(jit_gencode_t gen, jit_function_t func) { 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; diff --git a/jit/jit-rules-arm.ins b/jit/jit-rules-arm.ins index b676352..1590dde 100644 --- a/jit/jit-rules-arm.ins +++ b/jit/jit-rules-arm.ins @@ -1758,11 +1758,7 @@ JIT_OP_STORE_RELATIVE_STRUCT: manual _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, diff --git a/jit/jit-rules-interp.c b/jit/jit-rules-interp.c index 24a4b29..e3f5d80 100644 --- a/jit/jit-rules-interp.c +++ b/jit/jit-rules-interp.c @@ -193,19 +193,13 @@ generation is complete. /* * 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) /* diff --git a/jit/jit-rules-x86-64.c b/jit/jit-rules-x86-64.c index 9c5f3fc..52ba8ed 100644 --- a/jit/jit-rules-x86-64.c +++ b/jit/jit-rules-x86-64.c @@ -122,13 +122,10 @@ do { \ /* * 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 @@ -1155,14 +1152,8 @@ _jit_gen_free_reg(jit_gencode_t gen, int reg, 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); } } @@ -2459,11 +2450,7 @@ _jit_gen_epilog(jit_gencode_t gen, jit_function_t func) 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; diff --git a/jit/jit-rules-x86.c b/jit/jit-rules-x86.c index 1669856..244e42a 100644 --- a/jit/jit-rules-x86.c +++ b/jit/jit-rules-x86.c @@ -264,12 +264,8 @@ void _jit_gen_epilog(jit_gencode_t gen, jit_function_t func) 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 */ @@ -408,11 +404,7 @@ void _jit_gen_epilog(jit_gencode_t gen, jit_function_t func) 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); @@ -423,13 +415,10 @@ void *_jit_gen_redirector(jit_gencode_t gen, jit_function_t func) /* * 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 @@ -641,21 +630,15 @@ void _jit_gen_spill_reg(jit_gencode_t gen, int reg, 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); } } diff --git a/jit/jit-rules-x86.ins b/jit/jit-rules-x86.ins index 95f57db..bc5a1a8 100644 --- a/jit/jit-rules-x86.ins +++ b/jit/jit-rules-x86.ins @@ -1779,11 +1779,7 @@ JIT_OP_SETUP_FOR_SIBLING: branch 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; } @@ -1802,11 +1798,7 @@ JIT_OP_IMPORT: manual 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) { @@ -2323,11 +2315,7 @@ JIT_OP_STORE_RELATIVE_STRUCT: manual _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, diff --git a/tools/gen-rules-parser.y b/tools/gen-rules-parser.y index dbda4d7..56704d7 100644 --- a/tools/gen-rules-parser.y +++ b/tools/gen-rules-parser.y @@ -1429,14 +1429,8 @@ static void gensel_output_clauses(gensel_clause_t clauses, gensel_option_t optio { 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"); } @@ -1447,12 +1441,11 @@ static void gensel_output_clauses(gensel_clause_t clauses, gensel_option_t optio 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) { @@ -1472,23 +1465,11 @@ static void gensel_output_clauses(gensel_clause_t clauses, gensel_option_t optio ? 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; @@ -1563,19 +1544,15 @@ static void gensel_output_clauses(gensel_clause_t clauses, gensel_option_t optio 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; -- 2.47.3