* Removed all Id tags.
[cacao.git] / src / vm / jit / intrp / codegen.c
index 509c1f81b0bb17ed948a493caa6053067a1ef15d..e49678bea92f6f5d4c51fb37c8c0a4068351a4c4 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/intrp/codegen.c - code generator for Interpreter
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-            Anton Ertl
-                       
-   Changes: Edwin Steiner
-
-   $Id: codegen.c 5661 2006-10-04 13:35:25Z twisti $
-
 */
 
 
 #include "vm/jit/intrp/codegen.h"
 #include "vm/jit/intrp/intrp.h"
 
+#include "mm/memory.h"
+
 #include "native/native.h"
+
 #include "vm/builtin.h"
-#include "vm/class.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/options.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/dseg.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher.h"
+#include "vm/jit/stack.h"
+#include "vm/jit/stacktrace.h"
+
+#include "vmcore/class.h"
+#include "vmcore/options.h"
 
 
 #define gen_branch(_inst) { \
   gen_##_inst(cd, 0); \
-  codegen_addreference(cd, iptr->dst.block); \
+  codegen_addreference(cd, BLOCK_OF(iptr->dst.insindex)); \
 }
 
 #define index2offset(_i) (-(_i) * SIZEOF_VOID_P)
@@ -214,7 +212,8 @@ void genarg_avftbl(codegendata *cd1, vftbl_t *a)
 
 /* include the interpreter generation functions *******************************/
 
-#include "vm/jit/intrp/java-gen.i"
+/* Do not use "java-gen.i", it does not work with builddir. */
+#include <java-gen.i>
 
 
 typedef void (*genfunctionptr) (codegendata *);
@@ -281,16 +280,17 @@ struct builtin_gen builtin_gen_table[] = {
 
 *******************************************************************************/
 
+#define I(value)   iptr[0].sx.val.i = (value); break;
+
 bool intrp_codegen(jitdata *jd)
 {
        methodinfo         *m;
        codegendata        *cd;
        registerdata       *rd;
        s4                  i, len, s1, s2, d;
-       stackptr            src;
        basicblock         *bptr;
        instruction        *iptr;
-       exceptiontable     *ex;
+       exception_entry    *ex;
        u2                  currentline;
        methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
        unresolved_method  *um;
@@ -313,33 +313,42 @@ bool intrp_codegen(jitdata *jd)
        lm = NULL;
        bte = NULL;
 
+       /* determine stackframe size (in units of ptrint slots) */
+
+       cd->stackframesize = m->maxlocals;
+
+#if defined(ENABLE_THREADS)
+       if (checksync && (m->flags & ACC_SYNCHRONIZED))
+               cd->stackframesize += 1;
+#endif
+
        /* create method header */
 
-       (void) dseg_addaddress(cd, jd->code);                  /* CodeinfoPointer */
-       (void) dseg_adds4(cd, m->maxlocals * SIZEOF_VOID_P);    /* FrameSize      */
+       (void) dseg_add_unique_address(cd, jd->code);
+       (void) dseg_add_unique_s4(cd, cd->stackframesize * SIZEOF_VOID_P);
 
 #if defined(ENABLE_THREADS)
        if (checksync && (m->flags & ACC_SYNCHRONIZED))
-               (void) dseg_adds4(cd, 1);                           /* IsSync         */
+               (void) dseg_add_unique_s4(cd, 1);
        else
 #endif
-               (void) dseg_adds4(cd, 0);                           /* IsSync         */
+               (void) dseg_add_unique_s4(cd, 0);
                                               
-       (void) dseg_adds4(cd, 0);                               /* IsLeaf         */
-       (void) dseg_adds4(cd, 0);                               /* IntSave        */
-       (void) dseg_adds4(cd, 0);                               /* FltSave        */
+       (void) dseg_add_unique_s4(cd, 0);
+       (void) dseg_add_unique_s4(cd, 0);
+       (void) dseg_add_unique_s4(cd, 0);
 
        dseg_addlinenumbertablesize(cd);
 
-       (void) dseg_adds4(cd, cd->exceptiontablelength);        /* ExTableSize    */
+       (void) dseg_add_unique_s4(cd, jd->exceptiontablelength);
 
        /* create exception table */
 
-       for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
-               dseg_addtarget(cd, ex->start);
-               dseg_addtarget(cd, ex->end);
-               dseg_addtarget(cd, ex->handler);
-               (void) dseg_addaddress(cd, ex->catchtype.any);
+       for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
+               dseg_add_target(cd, ex->start);
+               dseg_add_target(cd, ex->end);
+               dseg_add_target(cd, ex->handler);
+               (void) dseg_add_unique_address(cd, ex->catchtype.any);
        }
 
 #if 0  
@@ -353,10 +362,14 @@ bool intrp_codegen(jitdata *jd)
 
 #if defined(ENABLE_THREADS)
        if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
-               if (m->flags & ACC_STATIC)
+               if (m->flags & ACC_STATIC) {
                        gen_ACONST(cd, (java_objectheader *) m->class);
-               else
+               }
+               else {
                        gen_ALOAD(cd, 0);
+                       gen_DUP(cd);
+                       gen_ASTORE(cd, index2offset(m->maxlocals));
+               }
                
                gen_MONITORENTER(cd);
        }                       
@@ -369,15 +382,14 @@ bool intrp_codegen(jitdata *jd)
 
        /* walk through all basic blocks */
 
-       for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
+       for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
 
                bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
 
-               if (bptr->flags >= BBREACHED) {
+               if (bptr->flags != BBDELETED) {
 
                /* walk through all instructions */
                
-               src = bptr->instack;
                len = bptr->icount;
 
                gen_BBSTART;
@@ -390,6 +402,7 @@ bool intrp_codegen(jitdata *jd)
 
                MCODECHECK(64);       /* an instruction usually needs < 64 words      */
 
+switch_again:
                switch (iptr->opc) {
 
                case ICMD_INLINE_START:
@@ -409,12 +422,127 @@ bool intrp_codegen(jitdata *jd)
                case ICMD_ICONST:     /* ...  ==> ..., constant                       */
                                      /* op1 = 0, val.i = constant                    */
 
+                       /* optimize ICONST (2^x) .. IREM --> IREMPOW2 (const) */
+
+                       if (len >= 2 && iptr[1].opc == ICMD_IREM) {
+                               switch (iptr[0].sx.val.i) {
+       case 0x00000001: case 0x00000002: case 0x00000004: case 0x00000008:
+       case 0x00000010: case 0x00000020: case 0x00000040: case 0x00000080:
+       case 0x00000100: case 0x00000200: case 0x00000400: case 0x00000800:
+       case 0x00001000: case 0x00002000: case 0x00004000: case 0x00008000:
+       case 0x00010000: case 0x00020000: case 0x00040000: case 0x00080000:
+       case 0x00100000: case 0x00200000: case 0x00400000: case 0x00800000:
+       case 0x01000000: case 0x02000000: case 0x04000000: case 0x08000000:
+       case 0x10000000: case 0x20000000: case 0x40000000: case 0x80000000:
+                                       iptr[0].opc = ICMD_IREMPOW2;
+                                       iptr[0].sx.val.i--;
+                                       iptr[1].opc = ICMD_NOP;
+                                       goto switch_again;
+                               }
+                       }
+
+                       /* optimize ICONST (2^x) .. IDIV --> IDIVPOW2 (const) */
+
+                       if (len >= 2 && iptr[1].opc == ICMD_IDIV) {
+                               switch (iptr[0].sx.val.i) {
+                              case 0x00000002: I( 1) case 0x00000004: I( 2) case 0x00000008: I( 3)
+       case 0x00000010: I( 4) case 0x00000020: I( 5) case 0x00000040: I( 6) case 0x00000080: I( 7)
+       case 0x00000100: I( 8) case 0x00000200: I( 9) case 0x00000400: I(10) case 0x00000800: I(11)
+       case 0x00001000: I(12) case 0x00002000: I(13) case 0x00004000: I(14) case 0x00008000: I(15)
+       case 0x00010000: I(16) case 0x00020000: I(17) case 0x00040000: I(18) case 0x00080000: I(19)
+       case 0x00100000: I(20) case 0x00200000: I(21) case 0x00400000: I(22) case 0x00800000: I(23)
+       case 0x01000000: I(24) case 0x02000000: I(25) case 0x04000000: I(26) case 0x08000000: I(27)
+       case 0x10000000: I(28) case 0x20000000: I(29) case 0x40000000: I(30) case 0x80000000: I(31)
+       default: goto dont_opt_IDIVPOW2;
+                               }
+                               iptr[0].opc = ICMD_IDIVPOW2;
+                               iptr[1].opc = ICMD_NOP;
+                               goto switch_again;
+                       }
+dont_opt_IDIVPOW2:
+
+                       /* optimize ICONST .. IF_ICMPxx --> IFxx (const) */
+
+                       if (len >= 2) {
+                               switch (iptr[1].opc) {
+                                       case ICMD_IF_ICMPEQ: iptr[0].opc = ICMD_IFEQ; break;
+                                       case ICMD_IF_ICMPNE: iptr[0].opc = ICMD_IFNE; break;
+                                       case ICMD_IF_ICMPLT: iptr[0].opc = ICMD_IFLT; break;
+                                       case ICMD_IF_ICMPLE: iptr[0].opc = ICMD_IFLE; break;
+                                       case ICMD_IF_ICMPGT: iptr[0].opc = ICMD_IFGT; break;
+                                       case ICMD_IF_ICMPGE: iptr[0].opc = ICMD_IFGE; break;
+                                       default:        goto dont_opt_IFxx;
+                               }
+                               iptr[0].dst.insindex = iptr[1].dst.insindex;
+                               iptr[1].opc = ICMD_NOP;
+                               goto switch_again;
+                       }
+dont_opt_IFxx:
+
                        gen_ICONST(cd, iptr->sx.val.i);
                        break;
 
                case ICMD_LCONST:     /* ...  ==> ..., constant                       */
                                      /* op1 = 0, val.l = constant                    */
 
+                       /* optimize LCONST (2^x) .. LREM --> LREMPOW2 (const) */
+
+                       if (len >= 2 && iptr[1].opc == ICMD_LREM) {
+                               switch (iptr[0].sx.val.l) {
+       case 0x00000001: case 0x00000002: case 0x00000004: case 0x00000008:
+       case 0x00000010: case 0x00000020: case 0x00000040: case 0x00000080:
+       case 0x00000100: case 0x00000200: case 0x00000400: case 0x00000800:
+       case 0x00001000: case 0x00002000: case 0x00004000: case 0x00008000:
+       case 0x00010000: case 0x00020000: case 0x00040000: case 0x00080000:
+       case 0x00100000: case 0x00200000: case 0x00400000: case 0x00800000:
+       case 0x01000000: case 0x02000000: case 0x04000000: case 0x08000000:
+       case 0x10000000: case 0x20000000: case 0x40000000: case 0x80000000:
+                                       iptr[0].opc = ICMD_LREMPOW2;
+                                       iptr[0].sx.val.l--;
+                                       iptr[1].opc = ICMD_NOP;
+                                       goto switch_again;
+                               }
+                       }
+
+                       /* optimize LCONST (2^x) .. LDIV --> LDIVPOW2 (const) */
+
+                       if (len >= 2 && iptr[1].opc == ICMD_LDIV) {
+                               switch (iptr[0].sx.val.l) {
+                              case 0x00000002: I( 1) case 0x00000004: I( 2) case 0x00000008: I( 3)
+       case 0x00000010: I( 4) case 0x00000020: I( 5) case 0x00000040: I( 6) case 0x00000080: I( 7)
+       case 0x00000100: I( 8) case 0x00000200: I( 9) case 0x00000400: I(10) case 0x00000800: I(11)
+       case 0x00001000: I(12) case 0x00002000: I(13) case 0x00004000: I(14) case 0x00008000: I(15)
+       case 0x00010000: I(16) case 0x00020000: I(17) case 0x00040000: I(18) case 0x00080000: I(19)
+       case 0x00100000: I(20) case 0x00200000: I(21) case 0x00400000: I(22) case 0x00800000: I(23)
+       case 0x01000000: I(24) case 0x02000000: I(25) case 0x04000000: I(26) case 0x08000000: I(27)
+       case 0x10000000: I(28) case 0x20000000: I(29) case 0x40000000: I(30) case 0x80000000: I(31)
+       default: goto dont_opt_LDIVPOW2;
+                               }
+                               iptr[0].opc = ICMD_LDIVPOW2;
+                               iptr[1].opc = ICMD_NOP;
+                               goto switch_again;
+                       }
+dont_opt_LDIVPOW2:
+
+                       /* optimize LCONST .. LCMP .. IFxx (0) --> IF_Lxx */
+
+                       if (len >= 3 && iptr[1].opc == ICMD_LCMP && iptr[2].sx.val.i == 0) {
+                               switch (iptr[2].opc) {
+                                       case ICMD_IFEQ: iptr[0].opc = ICMD_IF_LEQ; break;
+                                       case ICMD_IFNE: iptr[0].opc = ICMD_IF_LNE; break;
+                                       case ICMD_IFLT: iptr[0].opc = ICMD_IF_LLT; break;
+                                       case ICMD_IFLE: iptr[0].opc = ICMD_IF_LLE; break;
+                                       case ICMD_IFGT: iptr[0].opc = ICMD_IF_LGT; break;
+                                       case ICMD_IFGE: iptr[0].opc = ICMD_IF_LGE; break;
+                                       default:        goto dont_opt_IF_Lxx;
+                               }
+                               iptr[0].dst.insindex = iptr[2].dst.insindex;
+                               iptr[1].opc = ICMD_NOP;
+                               iptr[2].opc = ICMD_NOP;
+                               goto switch_again;
+                       }
+dont_opt_IF_Lxx:
+
                        gen_LCONST(cd, iptr->sx.val.l);
                        break;
 
@@ -449,74 +577,68 @@ bool intrp_codegen(jitdata *jd)
                case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
                                      /* op1 = local variable                         */
 
-                       gen_ILOAD(cd, index2offset(iptr->s1.localindex));
+                       gen_ILOAD(cd, index2offset(iptr->s1.varindex));
                        break;
 
                case ICMD_LLOAD:      /* ...  ==> ..., content of local variable      */
                                      /* op1 = local variable                         */
 
-                       gen_LLOAD(cd, index2offset(iptr->s1.localindex));
+                       gen_LLOAD(cd, index2offset(iptr->s1.varindex));
                        break;
 
                case ICMD_ALOAD:      /* ...  ==> ..., content of local variable      */
                                      /* op1 = local variable                         */
 
-                       gen_ALOAD(cd, index2offset(iptr->s1.localindex));
+                       gen_ALOAD(cd, index2offset(iptr->s1.varindex));
                        break;
 
                case ICMD_FLOAD:      /* ...  ==> ..., content of local variable      */
                                      /* op1 = local variable                         */
 
-                       gen_ILOAD(cd, index2offset(iptr->s1.localindex));
+                       gen_ILOAD(cd, index2offset(iptr->s1.varindex));
                        break;
 
                case ICMD_DLOAD:      /* ...  ==> ..., content of local variable      */
                                      /* op1 = local variable                         */
 
-                       gen_LLOAD(cd, index2offset(iptr->s1.localindex));
+                       gen_LLOAD(cd, index2offset(iptr->s1.varindex));
                        break;
 
 
                case ICMD_ISTORE:     /* ..., value  ==> ...                          */
                                      /* op1 = local variable                         */
 
-                       gen_ISTORE(cd, index2offset(iptr->dst.localindex));
+                       gen_ISTORE(cd, index2offset(iptr->dst.varindex));
                        break;
 
                case ICMD_LSTORE:     /* ..., value  ==> ...                          */
                                      /* op1 = local variable                         */
 
-                       gen_LSTORE(cd, index2offset(iptr->dst.localindex));
+                       gen_LSTORE(cd, index2offset(iptr->dst.varindex));
                        break;
 
                case ICMD_ASTORE:     /* ..., value  ==> ...                          */
                                      /* op1 = local variable                         */
 
-                       gen_ASTORE(cd, index2offset(iptr->dst.localindex));
+                       gen_ASTORE(cd, index2offset(iptr->dst.varindex));
                        break;
 
 
                case ICMD_FSTORE:     /* ..., value  ==> ...                          */
                                      /* op1 = local variable                         */
 
-                       gen_ISTORE(cd, index2offset(iptr->dst.localindex));
+                       gen_ISTORE(cd, index2offset(iptr->dst.varindex));
                        break;
 
                case ICMD_DSTORE:     /* ..., value  ==> ...                          */
                                      /* op1 = local variable                         */
 
-                       gen_LSTORE(cd, index2offset(iptr->dst.localindex));
+                       gen_LSTORE(cd, index2offset(iptr->dst.varindex));
                        break;
 
 
                /* pop/dup/swap operations ********************************************/
 
-               /* attention: double and longs are only one entry in CACAO ICMDs      */
-
-               /* stack.c changes stack manipulation operations to treat
-                  longs/doubles as occupying a single slot.  Here we are
-                  undoing that (and only those things that stack.c did). */
-
                case ICMD_POP:        /* ..., value  ==> ...                          */
 
                        gen_POP(cd);
@@ -606,71 +728,31 @@ bool intrp_codegen(jitdata *jd)
                        gen_IADD(cd);
                        break;
 
-               case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
-                                     /* val.i = constant                             */
-
-                       gen_ICONST(cd, iptr->sx.val.i);
-                       gen_IADD(cd);
-                       break;
-
                case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
 
                        gen_LADD(cd);
                        break;
 
-               case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
-                                     /* val.l = constant                             */
-
-                       gen_LCONST(cd, iptr->sx.val.l);
-                       gen_LADD(cd);
-                       break;
-
                case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
 
                        gen_ISUB(cd);
                        break;
 
-               case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
-                                     /* val.i = constant                             */
-
-                       gen_ICONST(cd, iptr->sx.val.i);
-                       gen_ISUB(cd);
-                       break;
-
                case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
 
                        gen_LSUB(cd);
                        break;
 
-               case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
-                                     /* val.l = constant                             */
-
-                       gen_LCONST(cd, iptr->sx.val.l);
-                       gen_LSUB(cd);
-                       break;
-
                case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
 
                        gen_IMUL(cd);
                        break;
 
-               case ICMD_IMULCONST:  /* ..., val1, val2  ==> ..., val1 * val2        */
-
-                       gen_ICONST(cd, iptr->sx.val.i);
-                       gen_IMUL(cd);
-                       break;
-
                case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
 
                        gen_LMUL(cd);
                        break;
 
-               case ICMD_LMULCONST:  /* ..., val1, val2  ==> ..., val1 * val2        */
-
-                       gen_LCONST(cd, iptr->sx.val.l);
-                       gen_LMUL(cd);
-                       break;
-
                case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
 
                        gen_IDIV(cd);
@@ -720,148 +802,82 @@ bool intrp_codegen(jitdata *jd)
                        gen_ISHL(cd);
                        break;
 
-               case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
-                                     /* val.i = constant                             */
-
-                       gen_ICONST(cd, iptr->sx.val.i);
-                       gen_ISHL(cd);
-                       break;
-
                case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
 
                        gen_ISHR(cd);
                        break;
 
-               case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
-                                     /* val.i = constant                             */
-
-                       gen_ICONST(cd, iptr->sx.val.i);
-                       gen_ISHR(cd);
-                       break;
-
                case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
 
                        gen_IUSHR(cd);
                        break;
 
-               case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
-                                     /* val.i = constant                             */
-
-                       gen_ICONST(cd, iptr->sx.val.i);
-                       gen_IUSHR(cd);
-                       break;
-
                case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
 
                        gen_LSHL(cd);
                        break;
 
-               case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
-                                     /* val.i = constant                             */
-
-                       gen_ICONST(cd, iptr->sx.val.i);
-                       gen_LSHL(cd);
-                       break;
-
                case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
 
                        gen_LSHR(cd);
                        break;
 
-               case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
-                                     /* val.i = constant                             */
-
-                       gen_ICONST(cd, iptr->sx.val.i);
-                       gen_LSHR(cd);
-                       break;
-
                case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
 
                        gen_LUSHR(cd);
                        break;
 
-               case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
-                                     /* val.i = constant                             */
-
-                       gen_ICONST(cd, iptr->sx.val.i);
-                       gen_LUSHR(cd);
-                       break;
-
                case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
 
                        gen_IAND(cd);
                        break;
 
-               case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
-                                     /* val.i = constant                             */
-
-                       gen_ICONST(cd, iptr->sx.val.i);
-                       gen_IAND(cd);
-                       break;
-
                case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
 
                        gen_LAND(cd);
                        break;
 
-               case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
-                                     /* val.l = constant                             */
-
-                       gen_LCONST(cd, iptr->sx.val.l);
-                       gen_LAND(cd);
-                       break;
-
                case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
 
                        gen_IOR(cd);
                        break;
 
-               case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
-                                     /* val.i = constant                             */
-
-                       gen_ICONST(cd, iptr->sx.val.i);
-                       gen_IOR(cd);
-                       break;
-
                case ICMD_LOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
 
                        gen_LOR(cd);
                        break;
 
-               case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
-                                     /* val.l = constant                             */
-
-                       gen_LCONST(cd, iptr->sx.val.l);
-                       gen_LOR(cd);
-                       break;
-
                case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
 
                        gen_IXOR(cd);
                        break;
 
-               case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
-                                     /* val.i = constant                             */
-
-                       gen_ICONST(cd, iptr->sx.val.i);
-                       gen_IXOR(cd);
-                       break;
-
                case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
 
                        gen_LXOR(cd);
                        break;
 
-               case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
-                                     /* val.l = constant                             */
-
-                       gen_LCONST(cd, iptr->sx.val.l);
-                       gen_LXOR(cd);
-                       break;
-
 
                case ICMD_LCMP:       /* ..., val1, val2  ==> ..., val1 cmp val2      */
 
+                       /* optimize LCMP .. IFxx (0) --> IF_LCMPxx */
+
+                       if (len >= 2 && iptr[1].sx.val.i == 0) {
+                               switch (iptr[1].opc) {
+                                       case ICMD_IFEQ: iptr[0].opc = ICMD_IF_LCMPEQ; break;
+                                       case ICMD_IFNE: iptr[0].opc = ICMD_IF_LCMPNE; break;
+                                       case ICMD_IFLT: iptr[0].opc = ICMD_IF_LCMPLT; break;
+                                       case ICMD_IFLE: iptr[0].opc = ICMD_IF_LCMPLE; break;
+                                       case ICMD_IFGT: iptr[0].opc = ICMD_IF_LCMPGT; break;
+                                       case ICMD_IFGE: iptr[0].opc = ICMD_IF_LCMPGE; break;
+                                       default:        goto dont_opt_IF_LCMPxx;
+                               }
+                               iptr[0].dst.insindex = iptr[1].dst.insindex;
+                               iptr[1].opc = ICMD_NOP;
+                               goto switch_again;
+                       }
+dont_opt_IF_LCMPxx:
+
                        gen_LCMP(cd);
                        break;
 
@@ -869,7 +885,7 @@ bool intrp_codegen(jitdata *jd)
                case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
                                      /* op1 = variable, val.i = constant             */
 
-                       gen_IINC(cd, index2offset(iptr->s1.localindex), iptr->sx.val.i);
+                       gen_IINC(cd, index2offset(iptr->s1.varindex), iptr->sx.val.i);
                        break;
 
 
@@ -1093,6 +1109,7 @@ bool intrp_codegen(jitdata *jd)
                        }
                        else {
                                fi        = iptr->sx.s23.s3.fmiref->p.field;
+                               uf        = NULL;
                                fieldtype = fi->type;
                        }
 
@@ -1143,6 +1160,7 @@ bool intrp_codegen(jitdata *jd)
                        }
                        else {
                                fi        = iptr->sx.s23.s3.fmiref->p.field;
+                               uf        = NULL;
                                fieldtype = fi->type;
                        }
 
@@ -1194,6 +1212,7 @@ bool intrp_codegen(jitdata *jd)
                        }
                        else {
                                fi        = iptr->sx.s23.s3.fmiref->p.field;
+                               uf        = NULL;
                                fieldtype = fi->type;
                        }
 
@@ -1236,6 +1255,7 @@ bool intrp_codegen(jitdata *jd)
                        }
                        else {
                                fi        = iptr->sx.s23.s3.fmiref->p.field;
+                               uf        = NULL;
                                fieldtype = fi->type;
                        }
 
@@ -1277,7 +1297,6 @@ bool intrp_codegen(jitdata *jd)
                        break;
 
                case ICMD_GOTO:         /* ... ==> ...                                */
-               case ICMD_RET:          /* ... ==> ...                                */
                                        /* op1 = target JavaVM pc                     */
                        gen_branch(GOTO);
                        break;
@@ -1286,9 +1305,15 @@ bool intrp_codegen(jitdata *jd)
                                        /* op1 = target JavaVM pc                     */
 
                        gen_JSR(cd, NULL);
-                       codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
+                       codegen_addreference(cd, BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex));
                        break;
-                       
+
+               case ICMD_RET:          /* ... ==> ...                                */
+                                       /* op1 = local variable                       */
+
+                       gen_RET(cd, index2offset(iptr->s1.varindex));
+                       break;
+
                case ICMD_IFNULL:       /* ..., value ==> ...                         */
                                        /* op1 = target JavaVM pc                     */
 
@@ -1367,6 +1392,7 @@ bool intrp_codegen(jitdata *jd)
                        }
                        break;
 
+
                case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
                                        /* op1 = target JavaVM pc, val.l = constant   */
 
@@ -1409,88 +1435,89 @@ bool intrp_codegen(jitdata *jd)
                        gen_branch(IF_LCMPGE);
                        break;
 
-               case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
+               case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
                                        /* op1 = target JavaVM pc                     */
 
-                       gen_branch(IF_ICMPEQ);
+                       gen_branch(IF_LCMPEQ);
                        break;
 
-               case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
+               case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
                                        /* op1 = target JavaVM pc                     */
 
-                       gen_branch(IF_LCMPEQ);
+                       gen_branch(IF_LCMPNE);
                        break;
 
-               case ICMD_IF_ACMPEQ:    /* ..., value, value ==> ...                  */
+               case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
                                        /* op1 = target JavaVM pc                     */
 
-                       gen_branch(IF_ACMPEQ);
+                       gen_branch(IF_LCMPLT);
                        break;
 
-               case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
+               case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
                                        /* op1 = target JavaVM pc                     */
 
-                       gen_branch(IF_ICMPNE);
+                       gen_branch(IF_LCMPGT);
                        break;
 
-               case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
+               case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
                                        /* op1 = target JavaVM pc                     */
 
-                       gen_branch(IF_LCMPNE);
+                       gen_branch(IF_LCMPLE);
                        break;
 
-               case ICMD_IF_ACMPNE:    /* ..., value, value ==> ...                  */
+               case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
                                        /* op1 = target JavaVM pc                     */
 
-                       gen_branch(IF_ACMPNE);
+                       gen_branch(IF_LCMPGE);
                        break;
 
-               case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
+
+               case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
                                        /* op1 = target JavaVM pc                     */
 
-                       gen_branch(IF_ICMPLT);
+                       gen_branch(IF_ICMPEQ);
                        break;
 
-               case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
+               case ICMD_IF_ACMPEQ:    /* ..., value, value ==> ...                  */
                                        /* op1 = target JavaVM pc                     */
 
-                       gen_branch(IF_LCMPLT);
+                       gen_branch(IF_ACMPEQ);
                        break;
 
-               case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
+               case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
                                        /* op1 = target JavaVM pc                     */
 
-                       gen_branch(IF_ICMPGT);
+                       gen_branch(IF_ICMPNE);
                        break;
 
-               case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
+               case ICMD_IF_ACMPNE:    /* ..., value, value ==> ...                  */
                                        /* op1 = target JavaVM pc                     */
 
-                       gen_branch(IF_LCMPGT);
+                       gen_branch(IF_ACMPNE);
                        break;
 
-               case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
+               case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
                                        /* op1 = target JavaVM pc                     */
 
-                       gen_branch(IF_ICMPLE);
+                       gen_branch(IF_ICMPLT);
                        break;
 
-               case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
+               case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
                                        /* op1 = target JavaVM pc                     */
 
-                       gen_branch(IF_LCMPLE);
+                       gen_branch(IF_ICMPGT);
                        break;
 
-               case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
+               case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
                                        /* op1 = target JavaVM pc                     */
 
-                       gen_branch(IF_ICMPGE);
+                       gen_branch(IF_ICMPLE);
                        break;
 
-               case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
+               case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
                                        /* op1 = target JavaVM pc                     */
 
-                       gen_branch(IF_LCMPGE);
+                       gen_branch(IF_ICMPGE);
                        break;
 
 
@@ -1503,7 +1530,7 @@ bool intrp_codegen(jitdata *jd)
                                if (m->flags & ACC_STATIC) {
                                        gen_ACONST(cd, (java_objectheader *) m->class);
                                } else {
-                                       gen_ALOAD(cd, 0);
+                                       gen_ALOAD(cd, index2offset(m->maxlocals));
                                }
                                gen_MONITOREXIT(cd);
                        }
@@ -1511,7 +1538,7 @@ bool intrp_codegen(jitdata *jd)
                        if (opt_verbosecall)
                                gen_TRACERETURN(cd, m);
 
-                       gen_IRETURN(cd, index2offset(cd->maxlocals));
+                       gen_IRETURN(cd, index2offset(cd->stackframesize));
                        break;
 
                case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
@@ -1522,7 +1549,7 @@ bool intrp_codegen(jitdata *jd)
                                if (m->flags & ACC_STATIC) {
                                        gen_ACONST(cd, (java_objectheader *) m->class);
                                } else {
-                                       gen_ALOAD(cd, 0);
+                                       gen_ALOAD(cd, index2offset(m->maxlocals));
                                }
                                gen_MONITOREXIT(cd);
                        }
@@ -1530,7 +1557,7 @@ bool intrp_codegen(jitdata *jd)
                        if (opt_verbosecall)
                                gen_TRACELRETURN(cd, m);
 
-                       gen_LRETURN(cd, index2offset(cd->maxlocals));
+                       gen_LRETURN(cd, index2offset(cd->stackframesize));
                        break;
 
                case ICMD_RETURN:       /* ...  ==> ...                               */
@@ -1540,7 +1567,7 @@ bool intrp_codegen(jitdata *jd)
                                if (m->flags & ACC_STATIC) {
                                        gen_ACONST(cd, (java_objectheader *) m->class);
                                } else {
-                                       gen_ALOAD(cd, 0);
+                                       gen_ALOAD(cd, index2offset(m->maxlocals));
                                }
                                gen_MONITOREXIT(cd);
                        }
@@ -1548,7 +1575,7 @@ bool intrp_codegen(jitdata *jd)
                        if (opt_verbosecall)
                                gen_TRACERETURN(cd, m);
 
-                       gen_RETURN(cd, index2offset(cd->maxlocals));
+                       gen_RETURN(cd, index2offset(cd->stackframesize));
                        break;
 
 
@@ -1575,19 +1602,19 @@ bool intrp_codegen(jitdata *jd)
                        dseg_adddata(cd);
                        cd->mcodeptr = (u1 *) cd->mcodeptr + 2 * sizeof(Inst);
 
-                       codegen_addreference(cd, table[0].block);
+                       codegen_addreference(cd, BLOCK_OF(table[0].insindex));
 
                        /* build jump table top down and use address of lowest entry */
 
                        table += i;
 
                        while (--i >= 0) {
-                               dseg_addtarget(cd, table->block); 
+                               dseg_add_target(cd, BLOCK_OF(table->insindex)); 
                                --table;
                        }
                        }
 
-                       /* length of dataseg after last dseg_addtarget is used by load */
+                       /* length of dataseg after last dseg_add_target is used by load */
                        ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
                        break;
 
@@ -1614,15 +1641,15 @@ bool intrp_codegen(jitdata *jd)
                        /* build jump table top down and use address of lowest entry */
 
                        while (--i >= 0) {
-                               dseg_addtarget(cd, lookup->target.block); 
-                               dseg_addaddress(cd, lookup->value);
+                               dseg_add_target(cd, BLOCK_OF(lookup->target.insindex)); 
+                               dseg_add_unique_address(cd, lookup->value);
                                lookup++;
                        }
 
-                       codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
+                       codegen_addreference(cd, BLOCK_OF(iptr->sx.s23.s3.lookupdefault.insindex));
                        }
 
-                       /* length of dataseg after last dseg_addtarget is used by load */
+                       /* length of dataseg after last dseg_add_target is used by load */
                        ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
                        break;
 
@@ -1750,7 +1777,8 @@ bool intrp_codegen(jitdata *jd)
                        break;
 
                default:
-                       *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
+                       exceptions_throw_internalerror("Unknown ICMD %d during code generation",
+                                                                                  iptr->opc);
                        return false;
        } /* switch */
                
@@ -1758,7 +1786,7 @@ bool intrp_codegen(jitdata *jd)
 
        gen_BBEND;
 
-       } /* if (bptr->flags >= BBREACHED) */
+       } /* if (bptr->flags != BBDELETED) */
        } /* for basic block */
 
        dseg_createlinenumbertable(cd);
@@ -1771,7 +1799,7 @@ bool intrp_codegen(jitdata *jd)
 
        /* branch resolving (walk through all basic blocks) */
 
-       for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
+       for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
                branchref *brefs;
 
                for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
@@ -1797,7 +1825,7 @@ bool intrp_codegen(jitdata *jd)
    +-------------+ <-- stub
    | codeptr     |
    +-------------+
-   | maxlocals   |
+   | framesize   |  (in ptrint units, does not include return address)
    +-------------+
    | TRANSLATE   |
    +-------------+
@@ -1810,7 +1838,7 @@ bool intrp_codegen(jitdata *jd)
 
 *******************************************************************************/
 
-#define COMPILERSTUB_DATASIZE    1
+#define COMPILERSTUB_DATASIZE    2
 #define COMPILERSTUB_CODESIZE    4
 
 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
@@ -1821,8 +1849,8 @@ u1 *intrp_createcompilerstub(methodinfo *m)
        Inst        *s;
        Inst        *d;
        codegendata *cd;
-       codeinfo    *code;
        s4           dumpsize;
+       s4           stackframesize;
 
        s = CNEW(Inst, COMPILERSTUB_SIZE);
 
@@ -1831,11 +1859,11 @@ u1 *intrp_createcompilerstub(methodinfo *m)
        d = s;
        s = s + COMPILERSTUB_DATASIZE;
 
-       /* Store the codeinfo pointer in the same place as in the
-          methodheader for compiled methods. */
+       /* The codeinfo pointer is actually a pointer to the
+          methodinfo. This fakes a codeinfo structure. */
 
-       code = code_codeinfo_new(m);
-       d[0] = (Inst *) code;
+       d[0] = (Inst *) m;
+       d[1] = (Inst *) &d[0];                                    /* fake code->m */
 
        /* mark start of dump memory area */
 
@@ -1849,11 +1877,19 @@ u1 *intrp_createcompilerstub(methodinfo *m)
        genarg_ainst(cd, s + 2);
 
        if (m->flags & ACC_NATIVE) {
-               genarg_i(cd, m->parseddesc->paramslots);
-       } else {
-               genarg_i(cd, m->maxlocals);
+               stackframesize = m->parseddesc->paramslots;
+       } 
+       else {
+               stackframesize = m->maxlocals;
+
+#if defined(ENABLE_THREADS)
+               if (checksync && (m->flags & ACC_SYNCHRONIZED))
+                       stackframesize += 1;
+#endif
        }
 
+       genarg_i(cd, stackframesize);
+
        gen_BBSTART;
        gen_TRANSLATE(cd, m);
        gen_BBEND;
@@ -1958,28 +1994,29 @@ u1 *intrp_createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 #else
        u1      *cif;
 #endif
+       s4            stackframesize;
 
        /* get required compiler data */
 
-       m  = jd->m;
-       cd = jd->cd;
-       rd = jd->rd;
+       m    = jd->m;
+       code = jd->code;
+       cd   = jd->cd;
+       rd   = jd->rd;
 
-       /* create method header */
+       /* determine stackframe size (in units of ptrint) */
 
-       /* Store the codeinfo pointer in the same place as in the
-          methodheader for compiled methods. */
+       stackframesize = nmd->paramslots;
 
-       code = code_codeinfo_new(m);
+       /* create method header */
 
-       (void) dseg_addaddress(cd, code);                      /* CodeinfoPointer */
-       (void) dseg_adds4(cd, nmd->paramslots * SIZEOF_VOID_P); /* FrameSize      */
-       (void) dseg_adds4(cd, 0);                               /* IsSync         */
-       (void) dseg_adds4(cd, 0);                               /* IsLeaf         */
-       (void) dseg_adds4(cd, 0);                               /* IntSave        */
-       (void) dseg_adds4(cd, 0);                               /* FltSave        */
+       (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
+       (void) dseg_add_unique_s4(cd, stackframesize * SIZEOF_VOID_P); /*FrameSize*/
+       (void) dseg_add_unique_s4(cd, 0);                       /* IsSync         */
+       (void) dseg_add_unique_s4(cd, 0);                       /* IsLeaf         */
+       (void) dseg_add_unique_s4(cd, 0);                       /* IntSave        */
+       (void) dseg_add_unique_s4(cd, 0);                       /* FltSave        */
        dseg_addlinenumbertablesize(cd);
-       (void) dseg_adds4(cd, 0);                               /* ExTableSize    */
+       (void) dseg_add_unique_s4(cd, 0);                       /* ExTableSize    */
 
 #if defined(WITH_FFI)
        /* prepare ffi cif structure */
@@ -2102,7 +2139,7 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
 
        av_call(alist);
 
-       codegen_finish_native_call(((u1 *) &s) + sizeof(s));
+       *exceptionptr = codegen_finish_native_call(((u1 *) &s) + sizeof(s));
 
        CLEAR_global_sp;
 
@@ -2161,7 +2198,7 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
 
        ffi_call(pcif, FFI_FN(f), endsp, values);
 
-       codegen_finish_native_call(((u1 *) &s) + sizeof(s));
+       *exceptionptr = codegen_finish_native_call(((u1 *) &s) + sizeof(s));
 
        CLEAR_global_sp;
 
@@ -2211,14 +2248,14 @@ u1 *createcalljavafunction(methodinfo *m)
 
        /* create method header */
 
-       (void) dseg_addaddress(cd, NULL);                      /* CodeinfoPointer */
-       (void) dseg_adds4(cd, md->paramslots * SIZEOF_VOID_P);  /* FrameSize      */
-       (void) dseg_adds4(cd, 0);                               /* IsSync         */
-       (void) dseg_adds4(cd, 0);                               /* IsLeaf         */
-       (void) dseg_adds4(cd, 0);                               /* IntSave        */
-       (void) dseg_adds4(cd, 0);                               /* FltSave        */
+       (void) dseg_add_unique_address(cd, NULL);              /* CodeinfoPointer */
+       (void) dseg_add_unique_s4(cd, md->paramslots * SIZEOF_VOID_P);/* FrameSize*/
+       (void) dseg_add_unique_s4(cd, 0);                       /* IsSync         */
+       (void) dseg_add_unique_s4(cd, 0);                       /* IsLeaf         */
+       (void) dseg_add_unique_s4(cd, 0);                       /* IntSave        */
+       (void) dseg_add_unique_s4(cd, 0);                       /* FltSave        */
        dseg_addlinenumbertablesize(cd);
-       (void) dseg_adds4(cd, 0);                               /* ExTableSize    */
+       (void) dseg_add_unique_s4(cd, 0);                       /* ExTableSize    */
 
 
        /* generate code */