dotgnu-pnet-commits
[Top][All Lists]
Advanced

[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 = &regs->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 = &regs->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, &regs->descs[1], &regs->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, 
&regs))\n");
-                               printf("\t\t{\n");
-                               printf("\t\t\treturn;\n");
-                               printf("\t\t}\n");
-                               printf("\t\tif(!_jit_regs_gen(gen, &regs))\n");
-                               printf("\t\t{\n");
-                               printf("\t\t\treturn;\n");
-                               printf("\t\t}\n");
+                               printf("\t\t_jit_regs_assign(gen, &regs);\n");
+                               printf("\t\t_jit_regs_gen(gen, &regs);\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, &regs, ", gensel_inst_type);
+                               printf("\t\t_jit_regs_begin(gen, &regs, ");
                        }
                        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, &regs);\n");
-                       }
-               }
-               else if(contains_registers)
-               {
-                       printf("\t\t_jit_regs_end(gen, &regs, (unsigned char 
*)inst);\n");
                }
                else
                {
                        printf("\t\tgen->posn.ptr = (unsigned char *)inst;\n");
                }
+               if(contains_registers)
+               {
+                       printf("\t\t_jit_regs_commit(gen, &regs);\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)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]