[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET Just In Time compiler (l
From: |
Aleksey Demakov |
Subject: |
[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET Just In Time compiler (libjit) branch, master, updated. b1a26ec0307fb1036a1a0ba4252f617e27b66278 |
Date: |
Thu, 29 Oct 2009 22:43:03 +0000 |
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "DotGNU Portable.NET Just In Time compiler (libjit)".
The branch, master has been updated
via b1a26ec0307fb1036a1a0ba4252f617e27b66278 (commit)
via 6390fa4d7e13377f90fbe8a567e49539b978ae28 (commit)
via 2d97c190d9c21eb8ded50e5ca654f54911a7fef9 (commit)
from b41fd4a38fce4d0f5c24e63609deff8d32d03f6f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/libjit.git/commit/?id=b1a26ec0307fb1036a1a0ba4252f617e27b66278
commit b1a26ec0307fb1036a1a0ba4252f617e27b66278
Author: Aleksey Demakov <address@hidden>
Date: Fri Oct 30 04:41:57 2009 +0600
handle codegen errors with internal exceptions
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 <address@hidden>
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;
http://git.savannah.gnu.org/cgit/libjit.git/commit/?id=6390fa4d7e13377f90fbe8a567e49539b978ae28
commit 6390fa4d7e13377f90fbe8a567e49539b978ae28
Author: Aleksey Demakov <address@hidden>
Date: Fri Oct 30 04:27:36 2009 +0600
use internal exception to handle the cache full conditions
diff --git a/ChangeLog b/ChangeLog
index 8e3749c..688bd9b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,8 @@
* include/jit/jit-except.h (JIT_RESULT_CACHE_FULL): add result code.
* jit/jit-cache.h, jit/jit-cache.c (_jit_cache_check_space): add
function to check the available cache space.
+ * jit/jit-compile.c: use internal exception to handle the cache full
+ condition.
2009-10-13 Gopal V <address@hidden>
diff --git a/jit/jit-compile.c b/jit/jit-compile.c
index 49e3a55..75dab3f 100644
--- a/jit/jit-compile.c
+++ b/jit/jit-compile.c
@@ -29,6 +29,27 @@
# include <stdio.h>
#endif
+/*
+ * Misc data needed for compilation
+ */
+typedef struct
+{
+ jit_function_t func;
+
+ jit_cache_t cache;
+ int cache_locked;
+ int cache_started;
+
+ int restart;
+ int page_factor;
+
+ void *code_start;
+ void *code_end;
+
+ struct jit_gencode gen;
+
+} _jit_compile_t;
+
#define _JIT_RESULT_TO_OBJECT(x) ((void *) ((int) (x) - JIT_RESULT_OK))
#define _JIT_RESULT_FROM_OBJECT(x) ((int) ((void *) (x)) + JIT_RESULT_OK)
@@ -59,7 +80,7 @@ optimize(jit_function_t func)
/* Eliminate useless control flow */
_jit_block_clean_cfg(func);
- /* Optimization is */
+ /* Optimization is done */
func->is_optimized = 1;
}
@@ -259,7 +280,7 @@ compile_block(jit_gencode_t gen, jit_function_t func,
jit_block_t block)
}
/*
- * Reset value on restart.
+ * Reset value on codegen restart.
*/
static void
reset_value(jit_value_t value)
@@ -271,7 +292,7 @@ reset_value(jit_value_t value)
}
/*
- * Clean up the compilation state on restart.
+ * Clean up the compilation state on codegen restart.
*/
static void
cleanup_on_restart(jit_gencode_t gen, jit_function_t func)
@@ -336,248 +357,365 @@ cleanup_on_restart(jit_gencode_t gen, jit_function_t
func)
gen->epilog_fixup = 0;
}
+/*
+ * Acquire the code cache.
+ */
static void
-prepare(jit_function_t func)
+cache_acquire(_jit_compile_t *state)
{
- /* Intuit "nothrow" and "noreturn" flags for this function */
- if(!func->builder->may_throw)
+ /* Acquire the cache lock */
+ jit_mutex_lock(&state->func->context->cache_lock);
+
+ /* Remember that the lock is acquired */
+ state->cache_locked = 1;
+
+ /* Get the method cache */
+ state->cache = _jit_context_get_cache(state->func->context);
+ if(!state->cache)
{
- func->no_throw = 1;
+ jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
}
- if(!func->builder->ordinary_return)
+}
+
+/*
+ * Release the code cache.
+ */
+static void
+cache_release(_jit_compile_t *state)
+{
+ /* Release the lock if it was previously acquired */
+ if(state->cache_locked)
{
- func->no_return = 1;
+ jit_mutex_unlock(&state->func->context->cache_lock);
+ state->cache_locked = 0;
}
+}
- /* Compute liveness and "next use" information for this function */
- _jit_function_compute_liveness(func);
+/*
+ * Allocate some space in the code cache.
+ */
+static void
+cache_alloc(_jit_compile_t *state)
+{
+ int result;
+
+ /* First try with the current cache page */
+ result = _jit_cache_start_method(state->cache,
+ &state->gen.posn,
+ state->page_factor++,
+ JIT_FUNCTION_ALIGNMENT,
+ state->func);
+ if(result == JIT_CACHE_RESTART)
+ {
+ /* No space left on the current cache page. Allocate a new
one. */
+ result = _jit_cache_start_method(state->cache,
+ &state->gen.posn,
+ state->page_factor++,
+ JIT_FUNCTION_ALIGNMENT,
+ state->func);
+ }
+ if(result != JIT_CACHE_OK)
+ {
+ /* Failed to allocate any cache space */
+ jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
+ }
+
+ /* On success remember the cache state */
+ state->cache_started = 1;
}
-static int
-codegen(jit_function_t func, void **entry_point)
+/*
+ * End function output to the cache.
+ */
+static void
+cache_flush(_jit_compile_t *state)
{
- struct jit_gencode gen;
- jit_cache_t cache;
- unsigned char *start;
- unsigned char *end;
- jit_block_t block;
- int page_factor;
int result;
- /* Initialize the code generation state */
- jit_memzero(&gen, sizeof(gen));
- page_factor = 0;
- start = 0;
- end = 0;
+ if(state->cache_started)
+ {
+ state->cache_started = 0;
+
+ /* End the function's output process */
+ result = _jit_cache_end_method(&state->gen.posn);
+ if(result != JIT_CACHE_OK)
+ {
+ if(result == JIT_CACHE_RESTART)
+ {
+ /* Throw an internal exception that causes
+ a larger code space to be allocated and
+ the code generation to restart */
+ jit_exception_builtin(JIT_RESULT_CACHE_FULL);
+ }
+ else
+ {
+ /* Throw exception that indicates failure
+ to allocate enough code space */
+ jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
+ }
+ }
- /* Allocate global registers to variables within the function */
#ifndef JIT_BACKEND_INTERP
- _jit_regs_alloc_global(&gen, func);
+ /* On success perform a CPU cache flush, to make the code
executable */
+ jit_flush_exec(state->code_start,
+ (unsigned int)(state->code_end -
state->code_start));
#endif
+ }
+}
-#ifdef _JIT_COMPILE_DEBUG
- printf("\n*** Start compilation ***\n\n");
- func->builder->block_count = 0;
- func->builder->insn_count = 0;
-#endif
+/*
+ * Release the allocated cache space.
+ */
+static void
+cache_abort(_jit_compile_t *state)
+{
+ if(state->cache_started)
+ {
+ state->cache_started = 0;
- /* Get the method cache */
- cache = _jit_context_get_cache(func->context);
- if(!cache)
+ /* Make sure that the _jit_cache_end_method() call below will
+ release the currently held cache space rather than make it
+ allocated permanently */
+ jit_cache_mark_full(&state->gen.posn);
+
+ /* Actually release the cache space */
+ _jit_cache_end_method(&state->gen.posn);
+ }
+}
+
+/*
+ * Allocate more space in the code cache.
+ */
+static void
+cache_realloc(_jit_compile_t *state)
+{
+ int result;
+
+ /* Release the allocated cache space */
+ cache_abort(state);
+
+ /* Allocate a new cache page with the size that grows
+ by factor of 2 on each reallocation */
+ result = _jit_cache_start_method(state->cache,
+ &state->gen.posn,
+ state->page_factor,
+ JIT_FUNCTION_ALIGNMENT,
+ state->func);
+ if(result != JIT_CACHE_OK)
{
- return JIT_RESULT_OUT_OF_MEMORY;
+ /* Failed to allocate enough cache space */
+ jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
}
- /* Start function output to the cache */
- result = _jit_cache_start_method(cache, &(gen.posn),
- page_factor++,
- JIT_FUNCTION_ALIGNMENT, func);
- if (result == JIT_CACHE_RESTART)
+ state->page_factor *= 2;
+
+ /* On success remember the cache state */
+ state->cache_started = 1;
+}
+
+/*
+ * Prepare data 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)
{
- /* No space left on the current cache page. Allocate a new
one. */
- result = _jit_cache_start_method(cache, &(gen.posn),
- page_factor++,
- JIT_FUNCTION_ALIGNMENT, func);
+ state->func->no_throw = 1;
}
- if (result != JIT_CACHE_OK)
+ if(!state->func->builder->ordinary_return)
{
- /* Failed to allocate any cache space */
- return JIT_RESULT_OUT_OF_MEMORY;
+ state->func->no_return = 1;
}
- for(;;)
- {
- start = gen.posn.ptr;
+ /* Compute liveness and "next use" information for this function */
+ _jit_function_compute_liveness(state->func);
-#ifdef jit_extra_gen_init
- /* Initialize information that may need to be reset each loop */
- jit_extra_gen_init(&gen);
+ /* 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;
+
+ state->code_start = gen->posn.ptr;
#ifdef JIT_PROLOG_SIZE
- /* Output space for the function prolog */
- if(!jit_cache_check_for_n(&(gen.posn), JIT_PROLOG_SIZE))
- {
- /* No space left on the current cache page. Restart. */
- jit_cache_mark_full(&(gen.posn));
- goto restart;
- }
- gen.posn.ptr += JIT_PROLOG_SIZE;
+ /* Output space for the function prolog */
+ _jit_cache_check_space(&gen->posn, JIT_PROLOG_SIZE);
+ gen->posn.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);
+ /* 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);
+ /* Clear the local register assignments */
+ _jit_regs_init_for_block(gen);
#endif
- /* Generate the block's code */
- compile_block(&gen, func, block);
+ /* 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);
+ /* 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);
+ /* Notify the back end that the block is finished */
+ _jit_gen_end_block(gen, block);
- /* Stop code generation if the cache page is full */
- if(_jit_cache_is_full(cache, &(gen.posn)))
- {
- /* No space left on the current cache page.
Restart. */
- goto restart;
- }
+ /* Stop code generation if the cache page is full */
+ if(_jit_cache_is_full(state->cache, &gen->posn))
+ {
+ /* No space left on the current cache page. Restart. */
+ jit_exception_builtin(JIT_RESULT_CACHE_FULL);
}
+ }
- /* Output the function epilog. All return paths will jump to
here */
- _jit_gen_epilog(&gen, func);
- end = gen.posn.ptr;
+ /* Output the function epilog. All return paths will jump to here */
+ _jit_gen_epilog(gen, func);
+ state->code_end = gen->posn.ptr;
#ifdef JIT_PROLOG_SIZE
- /* Back-patch the function prolog and get the real entry point
*/
- start = _jit_gen_prolog(&gen, func, start);
+ /* Back-patch the function prolog and get the real entry point */
+ state->code_start = _jit_gen_prolog(gen, func, state->code_start);
#endif
#if !defined(JIT_BACKEND_INTERP) && (!defined(jit_redirector_size) ||
!defined(jit_indirector_size))
- /* If the function is recompilable, then we need an extra entry
- point to properly redirect previous references to the
function */
- if(func->is_recompilable && !func->indirector)
- {
- /* TODO: use _jit_create_indirector() instead of
- _jit_gen_redirector() as both do the same. */
- func->indirector = _jit_gen_redirector(&gen, func);
- }
-#endif
-
- restart:
- /* End the function's output process */
- result = _jit_cache_end_method(&(gen.posn));
- if(result != JIT_CACHE_RESTART)
- {
- break;
- }
-
- /* Clean up the compilation state before restart */
- cleanup_on_restart(&gen, func);
-
-#ifdef _JIT_COMPILE_DEBUG
- printf("\n*** Restart compilation ***\n\n");
- func->builder->block_count = 0;
- func->builder->insn_count = 0;
-#endif
-
- /* Restart function output to the cache */
- result = _jit_cache_start_method(cache, &(gen.posn),
- page_factor,
- JIT_FUNCTION_ALIGNMENT, func);
- if(result != JIT_CACHE_OK)
- {
-#ifdef jit_extra_gen_cleanup
- /* Clean up the extra code generation state */
- jit_extra_gen_cleanup(gen);
-#endif
- return JIT_RESULT_OUT_OF_MEMORY;
- }
- page_factor *= 2;
- }
-
-#ifdef jit_extra_gen_cleanup
- /* Clean up the extra code generation state */
- jit_extra_gen_cleanup(gen);
-#endif
-
- /* Bail out if we ran out of memory while translating the function */
- if(result != JIT_CACHE_OK)
+ /* If the function is recompilable, then we need an extra entry
+ point to properly redirect previous references to the function */
+ if(func->is_recompilable && !func->indirector)
{
- return JIT_RESULT_OUT_OF_MEMORY;
+ /* TODO: use _jit_create_indirector() instead of
+ _jit_gen_redirector() as both do the same. */
+ func->indirector = _jit_gen_redirector(&gen, func);
}
-
-#ifndef JIT_BACKEND_INTERP
- /* Perform a CPU cache flush, to make the code executable */
- jit_flush_exec(start, (unsigned int)(end - start));
#endif
-
- /* Record the entry point */
- *entry_point = start;
-
- return JIT_RESULT_OK;
}
/*
* Compile a function and return its entry point.
*/
static int
-compile(jit_function_t func, void **entry_point)
+compile(_jit_compile_t *state, jit_function_t func)
{
- jit_jmp_buf jbuf;
jit_exception_func handler;
- volatile int unlock = 0;
+ jit_jmp_buf jbuf;
+ int result;
- /* Override user's exception handler */
+ /* Initialize compilation state */
+ jit_memzero(state, sizeof(_jit_compile_t));
+ state->func = func;
+
+ /* Replace user's exception handler with internal handler */
handler = jit_exception_set_handler(internal_exception_handler);
/* Establish a "setjmp" point here so that we can unwind the
stack to this point when an exception occurs and then prevent
the exception from propagating further up the stack */
_jit_unwind_push_setjmp(&jbuf);
+
+ restart:
+ /* Handle compilation exceptions */
if(setjmp(jbuf.buf))
{
- if(unlock)
+ result =
_JIT_RESULT_FROM_OBJECT(jit_exception_get_last_and_clear());
+ if(result == JIT_RESULT_CACHE_FULL)
{
- jit_mutex_unlock(&func->context->cache_lock);
+ /* Restart code generation after the cache-full
condition */
+ state->restart = 1;
+ goto restart;
}
- _jit_unwind_pop_setjmp();
- jit_exception_set_handler(handler);
- return
_JIT_RESULT_FROM_OBJECT(jit_exception_get_last_and_clear());
+
+ /* Release allocated cache space and exit */
+ cache_abort(state);
+ goto exit;
}
- /* Perform machine-independent optimizations */
- optimize(func);
+ if(state->restart == 0)
+ {
+ /* Start compilation */
+
+ /* Perform machine-independent optimizations */
+ optimize(state->func);
- /* Prepare the data needed for code generation */
- prepare(func);
+ /* Prepare data needed for code generation */
+ codegen_prepare(state);
+
+ /* Allocate some cache */
+ cache_acquire(state);
+ cache_alloc(state);
+ }
+ else
+ {
+ /* Restart compilation */
+
+ /* Clean up the compilation state */
+ cleanup_on_restart(&state->gen, state->func);
+
+ /* Allocate more cache */
+ cache_realloc(state);
+ }
+
+#ifdef _JIT_COMPILE_DEBUG
+ if(state->restart == 0)
+ {
+ printf("\n*** Start code generation ***\n\n");
+ }
+ else
+ {
+ printf("\n*** Restart code generation ***\n\n");
+ }
+ state->func->builder->block_count = 0;
+ state->func->builder->insn_count = 0;
+#endif
- /* We need the cache lock while we are generating the code */
- jit_mutex_lock(&func->context->cache_lock);
- unlock = 1;
+#ifdef jit_extra_gen_init
+ /* Initialize information that may need to be reset both
+ on start and restart */
+ jit_extra_gen_init(&state->gen);
+#endif
/* Perform code generation */
- codegen(func, entry_point);
+ codegen(state);
+
+#ifdef jit_extra_gen_cleanup
+ /* Clean up the extra code generation state */
+ jit_extra_gen_cleanup(&state->gen);
+#endif
- /* Unlock the cache */
- jit_mutex_unlock(&func->context->cache_lock);
+ /* End the function's output process */
+ cache_flush(state);
- /* Restore the "setjmp" contexts and exit */
+ /* Compilation done, no exceptions occured */
+ result = JIT_RESULT_OK;
+
+ exit:
+ /* Release the cache */
+ cache_release(state);
+
+ /* Restore the "setjmp" context */
_jit_unwind_pop_setjmp();
+
+ /* Restore user's exception handler */
jit_exception_set_handler(handler);
- return JIT_RESULT_OK;
+
+ return result;
}
/*@
@@ -599,8 +737,8 @@ compile(jit_function_t func, void **entry_point)
int
jit_compile(jit_function_t func)
{
+ _jit_compile_t state;
int result;
- void *entry_point;
/* Bail out on invalid parameter */
if(!func)
@@ -623,11 +761,11 @@ jit_compile(jit_function_t func)
}
}
- /* Compile and record the entry point. */
- result = compile(func, &entry_point);
+ /* Compile and record the entry point */
+ result = compile(&state, func);
if(result == JIT_RESULT_OK)
{
- func->entry_point = entry_point;
+ func->entry_point = state.code_start;
func->is_compiled = 1;
/* Free the builder structure, which we no longer require */
@@ -647,6 +785,9 @@ jit_compile(jit_function_t func)
int
jit_compile_entry(jit_function_t func, void **entry_point)
{
+ _jit_compile_t state;
+ int result;
+
/* Init entry_point */
if(entry_point)
{
@@ -679,8 +820,14 @@ jit_compile_entry(jit_function_t func, void **entry_point)
}
}
- /* Compile and return the entry point. */
- return compile(func, entry_point);
+ /* Compile and return the entry point */
+ result = compile(&state, func);
+ if(result == JIT_RESULT_OK)
+ {
+ *entry_point = state.code_start;
+ }
+
+ return result;
}
/*@
@@ -747,8 +894,8 @@ jit_function_compile_entry(jit_function_t func, void
**entry_point)
void *
_jit_function_compile_on_demand(jit_function_t func)
{
+ _jit_compile_t state;
int result;
- void *entry;
/* Lock down the context */
jit_context_build_start(func->context);
@@ -773,10 +920,10 @@ _jit_function_compile_on_demand(jit_function_t func)
if(result == JIT_RESULT_OK && !func->is_compiled)
{
/* Compile the function if the user didn't do so */
- result = compile(func, &entry);
+ result = compile(&state, func);
if(result == JIT_RESULT_OK)
{
- func->entry_point = entry;
+ func->entry_point = state.code_start;
func->is_compiled = 1;
}
}
http://git.savannah.gnu.org/cgit/libjit.git/commit/?id=2d97c190d9c21eb8ded50e5ca654f54911a7fef9
commit 2d97c190d9c21eb8ded50e5ca654f54911a7fef9
Author: Aleksey Demakov <address@hidden>
Date: Fri Oct 30 04:15:05 2009 +0600
Add JIT_RESULT_CACHE_FULL internal exception;
Add _jit_check_cache_space function.
diff --git a/ChangeLog b/ChangeLog
index 1375b0f..8e3749c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-10-30 Aleksey Demakov <address@hidden>
+
+ * include/jit/jit-except.h (JIT_RESULT_CACHE_FULL): add result code.
+ * jit/jit-cache.h, jit/jit-cache.c (_jit_cache_check_space): add
+ function to check the available cache space.
2009-10-13 Gopal V <address@hidden>
diff --git a/include/jit/jit-except.h b/include/jit/jit-except.h
index 07e7439..4010453 100644
--- a/include/jit/jit-except.h
+++ b/include/jit/jit-except.h
@@ -41,6 +41,7 @@ extern "C" {
#define JIT_RESULT_CALLED_NESTED (-7)
#define JIT_RESULT_OUT_OF_BOUNDS (-8)
#define JIT_RESULT_UNDEFINED_LABEL (-9)
+#define JIT_RESULT_CACHE_FULL (-10000)
/*
* Exception handling function for builtin exceptions.
diff --git a/jit/jit-cache.c b/jit/jit-cache.c
index 7461756..0f01485 100644
--- a/jit/jit-cache.c
+++ b/jit/jit-cache.c
@@ -726,6 +726,17 @@ int _jit_cache_is_full(jit_cache_t cache, jit_cache_posn
*posn)
return (!cache->freeStart || (posn && posn->ptr >= posn->limit));
}
+void
+_jit_cache_check_space(jit_cache_posn *posn, int space)
+{
+ if(!jit_cache_check_for_n(posn, space))
+ {
+ /* No space left on the current cache page. */
+ jit_cache_mark_full(posn);
+ jit_exception_builtin(JIT_RESULT_CACHE_FULL);
+ }
+}
+
int _jit_cache_start_method(jit_cache_t cache,
jit_cache_posn *posn,
int page_factor,
diff --git a/jit/jit-cache.h b/jit/jit-cache.h
index 1b1d699..e0c5dab 100644
--- a/jit/jit-cache.h
+++ b/jit/jit-cache.h
@@ -68,6 +68,12 @@ void _jit_cache_destroy(jit_cache_t cache);
int _jit_cache_is_full(jit_cache_t cache, jit_cache_posn *posn);
/*
+ * Determine if there is sufficient space in the code cache.
+ * If not throws JIT_RESULT_CACHE_FULL exception.
+ */
+void _jit_cache_check_space(jit_cache_posn *posn, int space);
+
+/*
* Return values for "_jit_cache_start_method" and "_jit_cache_end_method".
*/
#define JIT_CACHE_OK 0 /* Function is OK */
@@ -174,8 +180,7 @@ void **_jit_cache_get_method_list(jit_cache_t cache);
* if the native offset could not be determined.
*/
#define JIT_CACHE_NO_OFFSET (~((unsigned long)0))
-unsigned long _jit_cache_get_native(jit_cache_t cache, void *start,
-
unsigned long offset, int exact);
+unsigned long _jit_cache_get_native(jit_cache_t cache, void *start, unsigned
long offset, int exact);
/*
* Get the bytecode offset that is associated with a native
@@ -183,8 +188,7 @@ unsigned long _jit_cache_get_native(jit_cache_t cache, void
*start,
* entry point for the method. Returns JIT_CACHE_NO_OFFSET
* if the bytecode offset could not be determined.
*/
-unsigned long _jit_cache_get_bytecode(jit_cache_t cache, void *start,
-
unsigned long offset, int exact);
+unsigned long _jit_cache_get_bytecode(jit_cache_t cache, void *start, unsigned
long offset, int exact);
/*
* Get the number of bytes currently in use in the method cache.
@@ -198,102 +202,78 @@ unsigned long _jit_cache_get_size(jit_cache_t cache);
* an instruction that falls within a method region. This
* macro corrects for the "off by 1" address.
*/
-#define jit_cache_return_to_pc(addr) \
- ((void *)(((unsigned char *)(addr)) - 1))
+#define jit_cache_return_to_pc(addr) \
+ ((void *)(((unsigned char *)(addr)) - 1))
/*
* Output a single byte to the current method.
*/
-#define jit_cache_byte(posn,value) \
- do { \
- if((posn)->ptr < (posn)->limit) \
- { \
- *(((posn)->ptr)++) = (unsigned
char)(value); \
- } \
- } while (0)
+#define jit_cache_byte(posn,value) \
+ do { \
+ if((posn)->ptr < (posn)->limit) \
+ { \
+ *(((posn)->ptr)++) = (unsigned char)(value); \
+ } \
+ } while (0)
/*
* Output a 16-bit word to the current method.
*/
-#define jit_cache_word16(posn,value) \
- do { \
- if(((posn)->ptr + 1) < (posn)->limit) \
- { \
- *((jit_ushort *)((posn)->ptr)) =
(jit_ushort)(value); \
- (posn)->ptr += 2; \
- } \
- else \
- { \
- (posn)->ptr = (posn)->limit; \
- } \
- } while (0)
+#define jit_cache_word16(posn,value) \
+ do { \
+ _jit_cache_check_space((posn), 2); \
+ *((jit_ushort *)((posn)->ptr)) = (jit_ushort)(value); \
+ (posn)->ptr += 2; \
+ } while (0)
/*
* Output a 32-bit word to the current method.
*/
-#define jit_cache_word32(posn,value) \
- do { \
- if(((posn)->ptr + 3) < (posn)->limit) \
- { \
- *((jit_uint *)((posn)->ptr)) =
(jit_uint)(value); \
- (posn)->ptr += 4; \
- } \
- else \
- { \
- (posn)->ptr = (posn)->limit; \
- } \
- } while (0)
+#define jit_cache_word32(posn,value) \
+ do { \
+ _jit_cache_check_space((posn), 4); \
+ *((jit_uint *)((posn)->ptr)) = (jit_uint)(value); \
+ (posn)->ptr += 4; \
+ } while (0)
/*
* Output a native word to the current method.
*/
-#define jit_cache_native(posn,value) \
- do { \
- if(((posn)->ptr + sizeof(jit_nuint) - 1) <
(posn)->limit) \
- { \
- *((jit_nuint *)((posn)->ptr)) =
(jit_nuint)(value); \
- (posn)->ptr += sizeof(jit_nuint); \
- } \
- else \
- { \
- (posn)->ptr = (posn)->limit; \
- } \
- } while (0)
+#define jit_cache_native(posn,value) \
+ do { \
+ _jit_cache_check_space((posn), sizeof(jit_nuint)); \
+ *((jit_nuint *)((posn)->ptr)) = (jit_nuint)(value); \
+ (posn)->ptr += sizeof(jit_nuint); \
+ } while (0)
/*
* Output a 64-bit word to the current method.
*/
-#define jit_cache_word64(posn,value) \
- do { \
- if(((posn)->ptr + 7) < (posn)->limit) \
- { \
- *((jit_ulong *)((posn)->ptr)) =
(jit_ulong)(value); \
- (posn)->ptr += 8; \
- } \
- else \
- { \
- (posn)->ptr = (posn)->limit; \
- } \
- } while (0)
+#define jit_cache_word64(posn,value) \
+ do { \
+ _jit_cache_check_space((posn), 8); \
+ *((jit_ulong *)((posn)->ptr)) = (jit_ulong)(value); \
+ (posn)->ptr += 8; \
+ } while (0)
/*
* Get the output position within the current method.
*/
-#define jit_cache_get_posn(posn) ((posn)->ptr)
+#define jit_cache_get_posn(posn) ((posn)->ptr)
/*
* Determine if there is sufficient space for N bytes in the current method.
*/
-#define jit_cache_check_for_n(posn,n) \
- (((posn)->ptr + (n)) <= (posn)->limit)
+#define jit_cache_check_for_n(posn,n) \
+ (((posn)->ptr + (n)) <= (posn)->limit)
/*
* Mark the cache as full.
*/
-#define jit_cache_mark_full(posn) \
- do { \
- (posn)->ptr = (posn)->limit; \
- } while (0)
+#define jit_cache_mark_full(posn) \
+ do { \
+ (posn)->ptr = (posn)->limit; \
+ } while (0)
#ifdef __cplusplus
};
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 14 ++
include/jit/jit-except.h | 1 +
jit/jit-cache.c | 11 +
jit/jit-cache.h | 116 +++++-------
jit/jit-compile.c | 497 ++++++++++++++++++++++++++++++----------------
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 +---
14 files changed, 476 insertions(+), 460 deletions(-)
hooks/post-receive
--
DotGNU Portable.NET Just In Time compiler (libjit)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [dotgnu-pnet-commits] [SCM] DotGNU Portable.NET Just In Time compiler (libjit) branch, master, updated. b1a26ec0307fb1036a1a0ba4252f617e27b66278,
Aleksey Demakov <=
- Prev by Date:
[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET engine, compilers and tools (pnet) branch, master, updated. bc705ada5a69d945f34ae93b1a3cb1f7167ee9d0
- Next by Date:
[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET Just In Time compiler (libjit) branch, master, updated. 865ceafd016266a1f146e4b7f516edcadaffd45a
- Previous by thread:
[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET engine, compilers and tools (pnet) branch, master, updated. bc705ada5a69d945f34ae93b1a3cb1f7167ee9d0
- Next by thread:
[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET Just In Time compiler (libjit) branch, master, updated. 865ceafd016266a1f146e4b7f516edcadaffd45a
- Index(es):