* src/vm/jit/parse.cpp,
[cacao.git] / src / vm / jit / intrp / codegen.c
index 16550f75fc8af67128535da8080e746efd8b6c12..4fbca4a70d15856dfe575b7af0675374fcef8cea 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/intrp/codegen.c - code generator for Interpreter
 
-   Copyright (C) 1996-2005, 2006 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
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-            Reinhard Grafl
-
-   Changes: Christian Thalinger
-            Anton Ertl
-
-   $Id: codegen.c 4550 2006-03-01 17:00:33Z twisti $
-
 */
 
 
 #include <assert.h>
 #include <stdio.h>
 
+#if defined(WITH_FFI)
+# include <ffi.h>
+#elif defined(WITH_FFCALL)
+# include <avcall.h>
+#else
+# error neither WITH_FFI nor WITH_FFCALL defined
+#endif
+
 #include "vm/types.h"
 
 #include "arch.h"
 #include "vm/jit/intrp/codegen.h"
 #include "vm/jit/intrp/intrp.h"
 
-#include "native/native.h"
-#include "vm/builtin.h"
-#include "vm/class.h"
-#include "vm/exceptions.h"
+#include "mm/memory.h"
+
+#include "native/native.hpp"
+
+#include "vm/jit/builtin.hpp"
+#include "vm/class.hpp"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/options.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
+
 #include "vm/jit/asmpart.h"
-#include "vm/jit/codegen-common.h"
+#include "vm/jit/codegen-common.hpp"
 #include "vm/jit/dseg.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/parse.h"
+#include "vm/jit/jit.hpp"
+#include "vm/jit/parse.hpp"
 #include "vm/jit/patcher.h"
-
-#if defined(WITH_FFI)
-# include <ffi.h>
-#elif defined(WITH_FFCALL)
-# include <avcall.h>
-#else
-# error neither WITH_FFI nor WITH_FFCALL defined
-#endif
+#include "vm/jit/stack.h"
+#include "vm/jit/stacktrace.hpp"
 
 
 #define gen_branch(_inst) { \
   gen_##_inst(cd, 0); \
-  codegen_addreference(cd, (basicblock *) (iptr->target), cd->mcodeptr); \
+  codegen_addreference(cd, BLOCK_OF(iptr->dst.insindex)); \
 }
 
 #define index2offset(_i) (-(_i) * SIZEOF_VOID_P)
@@ -163,6 +156,13 @@ void genarg_af(codegendata *cd1, functionptr a)
        (*mcodepp)++;
 }
 
+void genarg_afi(codegendata *cd1, fieldinfo *a)
+{
+       Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
+       *((fieldinfo **) *mcodepp) = a;
+       (*mcodepp)++;
+}
+
 void genarg_am(codegendata *cd1, methodinfo *a)
 {
        Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
@@ -208,7 +208,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 *);
@@ -233,9 +234,9 @@ struct builtin_gen builtin_gen_table[] = {
     {BUILTIN_newarray_double,         gen_NEWARRAY_DOUBLE, },
     {BUILTIN_arrayinstanceof,         gen_ARRAYINSTANCEOF, },
 
-#if defined(USE_THREADS)
-    {BUILTIN_monitorenter,            gen_MONITORENTER,    },
-    {BUILTIN_monitorexit,             gen_MONITOREXIT,     },
+#if defined(ENABLE_THREADS)
+    {LOCK_monitor_enter,              gen_MONITORENTER,    },
+    {LOCK_monitor_exit,               gen_MONITOREXIT,     },
 #endif
 
 #if !(SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_F2L)
@@ -275,18 +276,30 @@ struct builtin_gen builtin_gen_table[] = {
 
 *******************************************************************************/
 
-bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
+#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;
        u2                  currentline;
        methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
        unresolved_method  *um;
        builtintable_entry *bte;
        methoddesc         *md;
+       fieldinfo          *fi;
+       unresolved_field   *uf;
+       s4                  fieldtype;
+
+       /* get required compiler data */
+
+       m  = jd->m;
+       cd = jd->cd;
+       rd = jd->rd;
 
        /* prevent compiler warnings */
 
@@ -295,34 +308,33 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
        lm = NULL;
        bte = NULL;
 
-       /* create method header */
+       /* determine stackframe size (in units of ptrint slots) */
 
-       (void) dseg_addaddress(cd, m);                          /* MethodPointer  */
-       (void) dseg_adds4(cd, m->maxlocals * SIZEOF_VOID_P);    /* FrameSize      */
+       cd->stackframesize = m->maxlocals;
 
-#if defined(USE_THREADS)
-       if (checksync && (m->flags & ACC_SYNCHRONIZED))
-               (void) dseg_adds4(cd, 1);                           /* IsSync         */
-       else
+#if defined(ENABLE_THREADS)
+       if (checksync && code_is_synchronized(code))
+               cd->stackframesize += 1;
 #endif
-               (void) dseg_adds4(cd, 0);                           /* IsSync         */
-                                              
-       (void) dseg_adds4(cd, 0);                               /* IsLeaf         */
-       (void) dseg_adds4(cd, 0);                               /* IntSave        */
-       (void) dseg_adds4(cd, 0);                               /* FltSave        */
 
-       dseg_addlinenumbertablesize(cd);
+       /* create method header */
 
-       (void) dseg_adds4(cd, cd->exceptiontablelength);        /* ExTableSize    */
+       (void) dseg_add_unique_address(cd, jd->code);
+       (void) dseg_add_unique_s4(cd, cd->stackframesize * SIZEOF_VOID_P);
 
-       /* create exception table */
+       code->synchronizedoffset = rd->memuse * 8;
 
-       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.cls);
-       }
+       /* REMOVEME: We still need it for exception handling in assembler. */
+
+       if (code_is_leafmethod(code))
+               (void) dseg_add_unique_s4(cd, 1);
+       else
+               (void) dseg_add_unique_s4(cd, 0);
+
+       (void) dseg_add_unique_s4(cd, 0);
+       (void) dseg_add_unique_s4(cd, 0);
+
+       dseg_addlinenumbertablesize(cd);
 
 #if 0  
        /* initialize mcode variables */
@@ -333,12 +345,16 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
        gen_BBSTART;
 
-#if defined(USE_THREADS)
-       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
-               if (m->flags & ACC_STATIC)
-                       gen_ACONST(cd, (java_objectheader *) m->class);
-               else
+#if defined(ENABLE_THREADS)
+       if (checksync && code_is_synchronized(code)) {
+               if (m->flags & ACC_STATIC) {
+                       gen_ACONST(cd, (java_objectheader *) m->clazz);
+               }
+               else {
                        gen_ALOAD(cd, 0);
+                       gen_DUP(cd);
+                       gen_ASTORE(cd, index2offset(m->maxlocals));
+               }
                
                gen_MONITORENTER(cd);
        }                       
@@ -351,27 +367,27 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
        /* walk through all basic blocks */
 
-       for (bptr = m->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;
 
-               for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
+               for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
                        if (iptr->line != currentline) {
-                               dseg_addlinenumber(cd, iptr->line, cd->mcodeptr);
+                               dseg_addlinenumber(cd, iptr->line);
                                currentline = iptr->line;
                        }
 
                MCODECHECK(64);       /* an instruction usually needs < 64 words      */
 
+switch_again:
                switch (iptr->opc) {
 
                case ICMD_INLINE_START:
@@ -391,13 +407,128 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_ICONST:     /* ...  ==> ..., constant                       */
                                      /* op1 = 0, val.i = constant                    */
 
-                       gen_ICONST(cd, iptr->val.i);
+                       /* 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                    */
 
-                       gen_LCONST(cd, iptr->val.l);
+                       /* 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;
 
                case ICMD_FCONST:     /* ...  ==> ..., constant                       */
@@ -405,7 +536,7 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        {
                                ptrint fi;
 
-                               vm_f2Cell(iptr->val.f, fi);
+                               vm_f2Cell(iptr->sx.val.f, fi);
                                gen_ICONST(cd, fi);
                        }
                        break;
@@ -413,16 +544,16 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_DCONST:     /* ...  ==> ..., constant                       */
                                      /* op1 = 0, val.d = constant                    */
 
-                       gen_LCONST(cd, *(s8 *)&(iptr->val.d));
+                       gen_LCONST(cd, *(s8 *)&(iptr->sx.val.d));
                        break;
 
                case ICMD_ACONST:     /* ...  ==> ..., constant                       */
                                      /* op1 = 0, val.a = constant                    */
 
-                       if ((iptr->target != NULL) && (iptr->val.a == NULL))
-                               gen_PATCHER_ACONST(cd, NULL, iptr->target);
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr))
+                               gen_PATCHER_ACONST(cd, NULL, iptr->sx.val.c.ref);
                        else
-                               gen_ACONST(cd, iptr->val.a);
+                               gen_ACONST(cd, iptr->sx.val.anyptr);
                        break;
 
 
@@ -431,80 +562,71 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
                                      /* op1 = local variable                         */
 
-                       gen_ILOAD(cd, index2offset(iptr->op1));
+                       gen_ILOAD(cd, index2offset(iptr->s1.varindex));
                        break;
 
                case ICMD_LLOAD:      /* ...  ==> ..., content of local variable      */
                                      /* op1 = local variable                         */
 
-                       gen_LLOAD(cd, index2offset(iptr->op1));
+                       gen_LLOAD(cd, index2offset(iptr->s1.varindex));
                        break;
 
                case ICMD_ALOAD:      /* ...  ==> ..., content of local variable      */
                                      /* op1 = local variable                         */
 
-                       gen_ALOAD(cd, index2offset(iptr->op1));
+                       gen_ALOAD(cd, index2offset(iptr->s1.varindex));
                        break;
 
                case ICMD_FLOAD:      /* ...  ==> ..., content of local variable      */
                                      /* op1 = local variable                         */
 
-                       gen_ILOAD(cd, index2offset(iptr->op1));
+                       gen_ILOAD(cd, index2offset(iptr->s1.varindex));
                        break;
 
                case ICMD_DLOAD:      /* ...  ==> ..., content of local variable      */
                                      /* op1 = local variable                         */
 
-                       gen_LLOAD(cd, index2offset(iptr->op1));
+                       gen_LLOAD(cd, index2offset(iptr->s1.varindex));
                        break;
 
 
                case ICMD_ISTORE:     /* ..., value  ==> ...                          */
                                      /* op1 = local variable                         */
 
-                       gen_ISTORE(cd, index2offset(iptr->op1));
+                       gen_ISTORE(cd, index2offset(iptr->dst.varindex));
                        break;
 
                case ICMD_LSTORE:     /* ..., value  ==> ...                          */
                                      /* op1 = local variable                         */
 
-                       gen_LSTORE(cd, index2offset(iptr->op1));
+                       gen_LSTORE(cd, index2offset(iptr->dst.varindex));
                        break;
 
                case ICMD_ASTORE:     /* ..., value  ==> ...                          */
                                      /* op1 = local variable                         */
 
-                       gen_ASTORE(cd, index2offset(iptr->op1));
+                       gen_ASTORE(cd, index2offset(iptr->dst.varindex));
                        break;
 
 
                case ICMD_FSTORE:     /* ..., value  ==> ...                          */
                                      /* op1 = local variable                         */
 
-                       gen_ISTORE(cd, index2offset(iptr->op1));
+                       gen_ISTORE(cd, index2offset(iptr->dst.varindex));
                        break;
 
                case ICMD_DSTORE:     /* ..., value  ==> ...                          */
                                      /* op1 = local variable                         */
 
-                       gen_LSTORE(cd, index2offset(iptr->op1));
+                       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  ==> ...                          */
 
-                       if (IS_2_WORD_TYPE(src->type))
-                               gen_POP2(cd);
-                       else
-                               gen_POP(cd);
+                       gen_POP(cd);
                        break;
 
                case ICMD_POP2:       /* ..., value, value  ==> ...                   */
@@ -514,35 +636,17 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
                case ICMD_DUP:        /* ..., a ==> ..., a, a                         */
 
-                       if (IS_2_WORD_TYPE(src->type))
-                               gen_DUP2(cd);
-                       else
-                               gen_DUP(cd);
+                       gen_DUP(cd);
                        break;
 
                case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
 
-                       if (IS_2_WORD_TYPE(src->type)) {
-                               if (IS_2_WORD_TYPE(src->prev->type)) {
-                                       gen_DUP2_X2(cd);
-                               } else {
-                                       gen_DUP2_X1(cd);
-                               }
-                       } else {
-                               if (IS_2_WORD_TYPE(src->prev->type)) {
-                                       gen_DUP_X2(cd);
-                               } else {
-                                       gen_DUP_X1(cd);
-                               }
-                       }
+                       gen_DUP_X1(cd);
                        break;
 
                case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
 
-                       if (IS_2_WORD_TYPE(src->type)) {
-                               gen_DUP2_X2(cd);
-                       } else
-                               gen_DUP_X2(cd);
+                       gen_DUP_X2(cd);
                        break;
 
                case ICMD_DUP2:       /* ..., a, b ==> ..., a, b, a, b                */
@@ -552,10 +656,7 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
                case ICMD_DUP2_X1:    /* ..., a, b, c ==> ..., b, c, a, b, c          */
 
-                       if (IS_2_WORD_TYPE(src->prev->prev->type))
-                               gen_DUP2_X2(cd);
-                       else
-                               gen_DUP2_X1(cd);
+                       gen_DUP2_X1(cd);
                        break;
 
                case ICMD_DUP2_X2:    /* ..., a, b, c, d ==> ..., c, d, a, b, c, d    */
@@ -612,71 +713,31 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        gen_IADD(cd);
                        break;
 
-               case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
-                                     /* val.i = constant                             */
-
-                       gen_ICONST(cd, iptr->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->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->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->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->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->val.l);
-                       gen_LMUL(cd);
-                       break;
-
                case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
 
                        gen_IDIV(cd);
@@ -700,25 +761,25 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value << constant       */
                                      /* val.i = constant                             */
                                      
-                       gen_IDIVPOW2(cd, iptr->val.i);
+                       gen_IDIVPOW2(cd, iptr->sx.val.i);
                        break;
 
                case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
                                      /* val.i = constant                             */
 
-                       gen_IREMPOW2(cd, iptr->val.i);
+                       gen_IREMPOW2(cd, iptr->sx.val.i);
                        break;
 
                case ICMD_LDIVPOW2:   /* ..., value  ==> ..., value << constant       */
                                      /* val.i = constant                             */
                                      
-                       gen_LDIVPOW2(cd, iptr->val.i);
+                       gen_LDIVPOW2(cd, iptr->sx.val.i);
                        break;
 
                case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
                                      /* val.l = constant                             */
 
-                       gen_LREMPOW2(cd, iptr->val.i);
+                       gen_LREMPOW2(cd, iptr->sx.val.i);
                        break;
 
                case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
@@ -726,148 +787,82 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        gen_ISHL(cd);
                        break;
 
-               case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
-                                     /* val.i = constant                             */
-
-                       gen_ICONST(cd, iptr->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->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->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->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->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->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->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->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->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->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->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->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;
 
@@ -875,7 +870,7 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
                                      /* op1 = variable, val.i = constant             */
 
-                       gen_IINC(cd, index2offset(iptr->op1), iptr->val.i);
+                       gen_IINC(cd, index2offset(iptr->s1.varindex), iptr->sx.val.i);
                        break;
 
 
@@ -1092,166 +1087,190 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
                                      /* op1 = type, val.a = field address            */
 
-                       {
-                       fieldinfo *fi = iptr->val.a;
-                       unresolved_field *uf = iptr->target;
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               fi        = NULL;
+                               uf        = iptr->sx.s23.s3.uf;
+                               fieldtype = uf->fieldref->parseddesc.fd->type;
+                       }
+                       else {
+                               fi        = iptr->sx.s23.s3.fmiref->p.field;
+                               uf        = NULL;
+                               fieldtype = fi->type;
+                       }
 
-                       switch (iptr->op1) {
+                       switch (fieldtype) {
                        case TYPE_INT:
-                               if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               if (fi == NULL)
                                        gen_PATCHER_GETSTATIC_INT(cd, 0, uf);
-                               } else {
-                                       gen_GETSTATIC_INT(cd, (u1 *)&(fi->value.i), uf);
-                               }
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       gen_PATCHER_GETSTATIC_CLINIT_INT(cd, 0, fi);
+                               else
+                                       gen_GETSTATIC_INT(cd, (u1 *) &(fi->value.i), fi);
                                break;
                        case TYPE_FLT:
-                               if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               if (fi == NULL)
                                        gen_PATCHER_GETSTATIC_FLOAT(cd, 0, uf);
-                               } else {
-                                       gen_GETSTATIC_FLOAT(cd, (u1 *)&(fi->value.i), uf);
-                               }
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       gen_PATCHER_GETSTATIC_CLINIT_FLOAT(cd, 0, fi);
+                               else
+                                       gen_GETSTATIC_FLOAT(cd, (u1 *) &(fi->value.i), fi);
                                break;
                        case TYPE_LNG:
                        case TYPE_DBL:
-                               if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               if (fi == NULL)
                                        gen_PATCHER_GETSTATIC_LONG(cd, 0, uf);
-                               } else {
-                                       gen_GETSTATIC_LONG(cd, (u1 *)&(fi->value.l), uf);
-                               }
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       gen_PATCHER_GETSTATIC_CLINIT_LONG(cd, 0, fi);
+                               else
+                                       gen_GETSTATIC_LONG(cd, (u1 *) &(fi->value.l), fi);
                                break;
                        case TYPE_ADR:
-                               if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               if (fi == NULL)
                                        gen_PATCHER_GETSTATIC_CELL(cd, 0, uf);
-                               } else {
-                                       gen_GETSTATIC_CELL(cd, (u1 *)&(fi->value.a), uf);
-                               }
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       gen_PATCHER_GETSTATIC_CLINIT_CELL(cd, 0, fi);
+                               else
+                                       gen_GETSTATIC_CELL(cd, (u1 *) &(fi->value.a), fi);
                                break;
                        }
-                       }
                        break;
 
                case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
                                      /* op1 = type, val.a = field address            */
 
-                       {
-                       fieldinfo *fi = iptr->val.a;
-                       unresolved_field *uf = iptr->target;
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               fi        = NULL;
+                               uf        = iptr->sx.s23.s3.uf;
+                               fieldtype = uf->fieldref->parseddesc.fd->type;
+                       }
+                       else {
+                               fi        = iptr->sx.s23.s3.fmiref->p.field;
+                               uf        = NULL;
+                               fieldtype = fi->type;
+                       }
 
-                       switch (iptr->op1) {
+                       switch (fieldtype) {
                        case TYPE_INT:
-                               if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               if (fi == NULL)
                                        gen_PATCHER_PUTSTATIC_INT(cd, 0, uf);
-                               } else {
-                                       gen_PUTSTATIC_INT(cd, (u1 *)&(fi->value.i), uf);
-                               }
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       gen_PATCHER_PUTSTATIC_CLINIT_INT(cd, 0, fi);
+                               else
+                                       gen_PUTSTATIC_INT(cd, (u1 *) &(fi->value.i), fi);
                                break;
                        case TYPE_FLT:
-                               if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               if (fi == NULL)
                                        gen_PATCHER_PUTSTATIC_FLOAT(cd, 0, uf);
-                               } else {
-                                       gen_PUTSTATIC_FLOAT(cd, (u1 *)&(fi->value.i), uf);
-                               }
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       gen_PATCHER_PUTSTATIC_CLINIT_FLOAT(cd, 0, fi);
+                               else
+                                       gen_PUTSTATIC_FLOAT(cd, (u1 *) &(fi->value.i), fi);
                                break;
                        case TYPE_LNG:
                        case TYPE_DBL:
-                               if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               if (fi == NULL)
                                        gen_PATCHER_PUTSTATIC_LONG(cd, 0, uf);
-                               } else {
-                                       gen_PUTSTATIC_LONG(cd, (u1 *)&(fi->value.l), uf);
-                               }
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       gen_PATCHER_PUTSTATIC_CLINIT_LONG(cd, 0, fi);
+                               else
+                                       gen_PUTSTATIC_LONG(cd, (u1 *) &(fi->value.l), fi);
                                break;
                        case TYPE_ADR:
-                               if ((fi == NULL) ||     !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               if (fi == NULL)
                                        gen_PATCHER_PUTSTATIC_CELL(cd, 0, uf);
-                               } else {
-                                       gen_PUTSTATIC_CELL(cd, (u1 *)&(fi->value.a), uf);
-                               }
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       gen_PATCHER_PUTSTATIC_CLINIT_CELL(cd, 0, fi);
+                               else
+                                       gen_PUTSTATIC_CELL(cd, (u1 *) &(fi->value.a), fi);
                                break;
                        }
-                       }
                        break;
 
 
                case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
                                      /* op1 = type, val.a = field address            */
 
-                       {
-                       fieldinfo *fi = iptr->val.a;
-                       unresolved_field *uf = iptr->target;
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               fi        = NULL;
+                               uf        = iptr->sx.s23.s3.uf;
+                               fieldtype = uf->fieldref->parseddesc.fd->type;
+                       }
+                       else {
+                               fi        = iptr->sx.s23.s3.fmiref->p.field;
+                               uf        = NULL;
+                               fieldtype = fi->type;
+                       }
 
-                       switch (iptr->op1) {
+                       switch (fieldtype) {
                        case TYPE_INT:
-                               if (fi == NULL) {
+                               if (fi == NULL)
                                        gen_PATCHER_GETFIELD_INT(cd, 0, uf);
-                               } else {
-                                       gen_GETFIELD_INT(cd, fi->offset, uf);
-                               }
+                               else
+                                       gen_GETFIELD_INT(cd, fi->offset, fi);
                                break;
                        case TYPE_FLT:
-                               if (fi == NULL) {
+                               if (fi == NULL)
                                        gen_PATCHER_GETFIELD_FLOAT(cd, 0, uf);
-                               } else {
-                                       gen_GETFIELD_FLOAT(cd, fi->offset, uf);
-                               }
+                               else
+                                       gen_GETFIELD_FLOAT(cd, fi->offset, fi);
                                break;
                        case TYPE_LNG:
                        case TYPE_DBL:
-                               if (fi == NULL) {
+                               if (fi == NULL)
                                        gen_PATCHER_GETFIELD_LONG(cd, 0, uf);
-                               } else {
-                                       gen_GETFIELD_LONG(cd, fi->offset, uf);
-                               }
+                               else
+                                       gen_GETFIELD_LONG(cd, fi->offset, fi);
                                break;
                        case TYPE_ADR:
-                               if (fi == NULL) {
+                               if (fi == NULL)
                                        gen_PATCHER_GETFIELD_CELL(cd, 0, uf);
-                               } else {
-                                       gen_GETFIELD_CELL(cd, fi->offset, uf);
-                               }
+                               else
+                                       gen_GETFIELD_CELL(cd, fi->offset, fi);
                                break;
                        }
-                       }
                        break;
 
                case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
                                      /* op1 = type, val.a = field address            */
 
-                       {
-                       fieldinfo *fi = iptr->val.a;
-                       unresolved_field *uf = iptr->target;
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               fi        = NULL;
+                               uf        = iptr->sx.s23.s3.uf;
+                               fieldtype = uf->fieldref->parseddesc.fd->type;
+                       }
+                       else {
+                               fi        = iptr->sx.s23.s3.fmiref->p.field;
+                               uf        = NULL;
+                               fieldtype = fi->type;
+                       }
 
-                       switch (iptr->op1) {
+                       switch (fieldtype) {
                        case TYPE_INT:
-                               if (fi == NULL) {
+                               if (fi == NULL)
                                        gen_PATCHER_PUTFIELD_INT(cd, 0, uf);
-                               } else {
-                                       gen_PUTFIELD_INT(cd, fi->offset, uf);
-                               }
+                               else
+                                       gen_PUTFIELD_INT(cd, fi->offset, fi);
                                break;
                        case TYPE_FLT:
-                               if (fi == NULL) {
+                               if (fi == NULL)
                                        gen_PATCHER_PUTFIELD_FLOAT(cd, 0, uf);
-                               } else {
-                                       gen_PUTFIELD_FLOAT(cd, fi->offset, uf);
-                               }
+                               else
+                                       gen_PUTFIELD_FLOAT(cd, fi->offset, fi);
                                break;
                        case TYPE_LNG:
                        case TYPE_DBL:
-                               if (fi == NULL) {
+                               if (fi == NULL)
                                        gen_PATCHER_PUTFIELD_LONG(cd, 0, uf);
-                               } else {
-                                       gen_PUTFIELD_LONG(cd, fi->offset, uf);
-                               }
+                               else
+                                       gen_PUTFIELD_LONG(cd, fi->offset, fi);
                                break;
                        case TYPE_ADR:
-                               if (fi == NULL) {
+                               if (fi == NULL)
                                        gen_PATCHER_PUTFIELD_CELL(cd, 0, uf);
-                               } else {
-                                       gen_PUTFIELD_CELL(cd, fi->offset, uf);
-                               }
+                               else
+                                       gen_PUTFIELD_CELL(cd, fi->offset, fi);
                                break;
                        }
-                       }
                        break;
 
 
@@ -1269,13 +1288,15 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
                case ICMD_JSR:          /* ... ==> ...                                */
                                        /* op1 = target JavaVM pc                     */
-                       gen_branch(JSR);
+
+                       gen_JSR(cd, NULL);
+                       codegen_addreference(cd, BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex));
                        break;
-                       
+
                case ICMD_RET:          /* ... ==> ...                                */
                                        /* op1 = local variable                       */
 
-                       gen_RET(cd, index2offset(iptr->op1));
+                       gen_RET(cd, index2offset(iptr->s1.varindex));
                        break;
 
                case ICMD_IFNULL:       /* ..., value ==> ...                         */
@@ -1293,10 +1314,10 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_IFEQ:         /* ..., value ==> ...                         */
                                        /* op1 = target JavaVM pc, val.i = constant   */
 
-                       if (iptr->val.i == 0) {
+                       if (iptr->sx.val.i == 0) {
                                gen_branch(IFEQ);
                        } else {
-                               gen_ICONST(cd, iptr->val.i);
+                               gen_ICONST(cd, iptr->sx.val.i);
                                gen_branch(IF_ICMPEQ);
                        }
                        break;
@@ -1304,10 +1325,10 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_IFLT:         /* ..., value ==> ...                         */
                                        /* op1 = target JavaVM pc, val.i = constant   */
 
-                       if (iptr->val.i == 0) {
+                       if (iptr->sx.val.i == 0) {
                                gen_branch(IFLT);
                        } else {
-                               gen_ICONST(cd, iptr->val.i);
+                               gen_ICONST(cd, iptr->sx.val.i);
                                gen_branch(IF_ICMPLT);
                        }
                        break;
@@ -1315,10 +1336,10 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_IFLE:         /* ..., value ==> ...                         */
                                        /* op1 = target JavaVM pc, val.i = constant   */
 
-                       if (iptr->val.i == 0) {
+                       if (iptr->sx.val.i == 0) {
                                gen_branch(IFLE);
                        } else {
-                               gen_ICONST(cd, iptr->val.i);
+                               gen_ICONST(cd, iptr->sx.val.i);
                                gen_branch(IF_ICMPLE);
                        }
                        break;
@@ -1326,10 +1347,10 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_IFNE:         /* ..., value ==> ...                         */
                                        /* op1 = target JavaVM pc, val.i = constant   */
 
-                       if (iptr->val.i == 0) {
+                       if (iptr->sx.val.i == 0) {
                                gen_branch(IFNE);
                        } else {
-                               gen_ICONST(cd, iptr->val.i);
+                               gen_ICONST(cd, iptr->sx.val.i);
                                gen_branch(IF_ICMPNE);
                        }
                        break;
@@ -1337,10 +1358,10 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_IFGT:         /* ..., value ==> ...                         */
                                        /* op1 = target JavaVM pc, val.i = constant   */
 
-                       if (iptr->val.i == 0) {
+                       if (iptr->sx.val.i == 0) {
                                gen_branch(IFGT);
                        } else {
-                               gen_ICONST(cd, iptr->val.i);
+                               gen_ICONST(cd, iptr->sx.val.i);
                                gen_branch(IF_ICMPGT);
                        }
                        break;
@@ -1348,138 +1369,140 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_IFGE:         /* ..., value ==> ...                         */
                                        /* op1 = target JavaVM pc, val.i = constant   */
 
-                       if (iptr->val.i == 0) {
+                       if (iptr->sx.val.i == 0) {
                                gen_branch(IFGE);
                        } else {
-                               gen_ICONST(cd, iptr->val.i);
+                               gen_ICONST(cd, iptr->sx.val.i);
                                gen_branch(IF_ICMPGE);
                        }
                        break;
 
+
                case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
                                        /* op1 = target JavaVM pc, val.l = constant   */
 
-                       gen_LCONST(cd, iptr->val.l);
+                       gen_LCONST(cd, iptr->sx.val.l);
                        gen_branch(IF_LCMPEQ);
                        break;
 
                case ICMD_IF_LLT:       /* ..., value ==> ...                         */
                                        /* op1 = target JavaVM pc, val.l = constant   */
 
-                       gen_LCONST(cd, iptr->val.l);
+                       gen_LCONST(cd, iptr->sx.val.l);
                        gen_branch(IF_LCMPLT);
                        break;
 
                case ICMD_IF_LLE:       /* ..., value ==> ...                         */
                                        /* op1 = target JavaVM pc, val.l = constant   */
 
-                       gen_LCONST(cd, iptr->val.l);
+                       gen_LCONST(cd, iptr->sx.val.l);
                        gen_branch(IF_LCMPLE);
                        break;
 
                case ICMD_IF_LNE:       /* ..., value ==> ...                         */
                                        /* op1 = target JavaVM pc, val.l = constant   */
 
-                       gen_LCONST(cd, iptr->val.l);
+                       gen_LCONST(cd, iptr->sx.val.l);
                        gen_branch(IF_LCMPNE);
                        break;
 
                case ICMD_IF_LGT:       /* ..., value ==> ...                         */
                                        /* op1 = target JavaVM pc, val.l = constant   */
 
-                       gen_LCONST(cd, iptr->val.l);
+                       gen_LCONST(cd, iptr->sx.val.l);
                        gen_branch(IF_LCMPGT);
                        break;
 
                case ICMD_IF_LGE:       /* ..., value ==> ...                         */
                                        /* op1 = target JavaVM pc, val.l = constant   */
 
-                       gen_LCONST(cd, iptr->val.l);
+                       gen_LCONST(cd, iptr->sx.val.l);
                        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;
 
 
@@ -1487,12 +1510,12 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
                case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
 
-#if defined(USE_THREADS)
-                       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+#if defined(ENABLE_THREADS)
+                       if (checksync && code_is_synchronized(code)) {
                                if (m->flags & ACC_STATIC) {
-                                       gen_ACONST(cd, (java_objectheader *) m->class);
+                                       gen_ACONST(cd, (java_objectheader *) m->clazz);
                                } else {
-                                       gen_ALOAD(cd, 0);
+                                       gen_ALOAD(cd, index2offset(m->maxlocals));
                                }
                                gen_MONITOREXIT(cd);
                        }
@@ -1500,18 +1523,18 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        if (opt_verbosecall)
                                gen_TRACERETURN(cd, m);
 
-                       gen_IRETURN(cd, index2offset(cd->maxlocals));
+                       gen_IRETURN(cd, index2offset(cd->stackframesize));
                        break;
 
                case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
                case ICMD_DRETURN:      /* ..., retvalue ==> ...                      */
 
-#if defined(USE_THREADS)
-                       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+#if defined(ENABLE_THREADS)
+                       if (checksync && code_is_synchronized(code)) {
                                if (m->flags & ACC_STATIC) {
-                                       gen_ACONST(cd, (java_objectheader *) m->class);
+                                       gen_ACONST(cd, (java_objectheader *) m->clazz);
                                } else {
-                                       gen_ALOAD(cd, 0);
+                                       gen_ALOAD(cd, index2offset(m->maxlocals));
                                }
                                gen_MONITOREXIT(cd);
                        }
@@ -1519,17 +1542,17 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        if (opt_verbosecall)
                                gen_TRACELRETURN(cd, m);
 
-                       gen_LRETURN(cd, index2offset(cd->maxlocals));
+                       gen_LRETURN(cd, index2offset(cd->stackframesize));
                        break;
 
                case ICMD_RETURN:       /* ...  ==> ...                               */
 
-#if defined(USE_THREADS)
-                       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+#if defined(ENABLE_THREADS)
+                       if (checksync && code_is_synchronized(code)) {
                                if (m->flags & ACC_STATIC) {
-                                       gen_ACONST(cd, (java_objectheader *) m->class);
+                                       gen_ACONST(cd, (java_objectheader *) m->clazz);
                                } else {
-                                       gen_ALOAD(cd, 0);
+                                       gen_ALOAD(cd, index2offset(m->maxlocals));
                                }
                                gen_MONITOREXIT(cd);
                        }
@@ -1537,20 +1560,19 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        if (opt_verbosecall)
                                gen_TRACERETURN(cd, m);
 
-                       gen_RETURN(cd, index2offset(cd->maxlocals));
+                       gen_RETURN(cd, index2offset(cd->stackframesize));
                        break;
 
 
                case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
                        {
-                       s4 i, l, *s4ptr;
-                       void **tptr;
+                       s4 i, l;
+                       branch_target_t *table;
 
-                       tptr = (void **) iptr->target;
+                       table = iptr->dst.table;
 
-                       s4ptr = iptr->val.a;
-                       l = s4ptr[1];                          /* low     */
-                       i = s4ptr[2];                          /* high    */
+                       l = iptr->sx.s23.s2.tablelow;
+                       i = iptr->sx.s23.s3.tablehigh;
                        
                        i = i - l + 1;
 
@@ -1561,63 +1583,65 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
                        /* actually -3 cells offset */
 
-                       dseg_adddata(cd, (cd->mcodeptr - 2 * sizeof(Inst)));
-                       codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
+                       cd->mcodeptr = (u1 *) cd->mcodeptr - 2 * sizeof(Inst);
+                       dseg_adddata(cd);
+                       cd->mcodeptr = (u1 *) cd->mcodeptr + 2 * sizeof(Inst);
+
+                       codegen_addreference(cd, BLOCK_OF(table[0].insindex));
 
                        /* build jump table top down and use address of lowest entry */
 
-                       tptr += i;
+                       table += i;
 
                        while (--i >= 0) {
-                               dseg_addtarget(cd, (basicblock *) tptr[0]); 
-                               --tptr;
+                               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;
 
 
                case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
                        {
-                       s4 i, *s4ptr;
-                       void **tptr;
+                       s4 i;
+                       lookup_target_t *lookup;
 
-                       tptr = (void **) iptr->target;
+                       lookup = iptr->dst.lookup;
 
-                       s4ptr = iptr->val.a;
-
-                       /* s4ptr[0] is equal to tptr[0] */
-                       i = s4ptr[1];                          /* count    */
+                       i = iptr->sx.s23.s2.lookupcount;
                        
                        /* arguments: count, datasegment address, table offset in         */
                        /* datasegment, default target                                    */
                        gen_LOOKUPSWITCH(cd, i, NULL, 0, NULL);
-                       dseg_adddata(cd, (cd->mcodeptr - 2*sizeof(Inst))); /* actually -3 cells offset*/
-                       codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
 
-                       /* build jump table top down and use address of lowest entry */
+                       /* actually -3 cells offset */
 
-                       tptr += i;
-                       s4ptr += i * 2;
+                       cd->mcodeptr = (u1 *) cd->mcodeptr - 2 * sizeof(Inst);
+                       dseg_adddata(cd);
+                       cd->mcodeptr = (u1 *) cd->mcodeptr + 2 * sizeof(Inst);
+
+                       /* build jump table top down and use address of lowest entry */
 
                        while (--i >= 0) {
-                               dseg_addtarget(cd, (basicblock *) tptr[0]); 
-                               dseg_addaddress(cd, s4ptr[0]);
-                               --tptr;
-                               s4ptr -= 2;
+                               dseg_add_target(cd, BLOCK_OF(lookup->target.insindex)); 
+                               dseg_add_unique_address(cd, lookup->value);
+                               lookup++;
                        }
+
+                       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;
 
 
                case ICMD_BUILTIN:      /* ..., arg1, arg2, arg3 ==> ...              */
                                        /* op1 = arg count val.a = builtintable entry */
-                       bte = iptr->val.a;
+                       bte = iptr->sx.s23.s3.bte;
 
                        for (i = 0; i < sizeof(builtin_gen_table)/sizeof(builtin_gen); i++) {
                                builtin_gen *bg = &builtin_gen_table[i];
@@ -1626,78 +1650,76 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                        goto gen_builtin_end;
                                }
                        }
-                       assert(0);
+
+                       vm_abort(0);
+
                gen_builtin_end:
                        break;
 
                case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
                                        /* op1 = arg count, val.a = method pointer    */
 
-                       lm = iptr->val.a;
-                       um = iptr->target;
-
-                       if (lm == NULL) {
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               um = iptr->sx.s23.s3.um;
                                md = um->methodref->parseddesc.md;
                                gen_PATCHER_INVOKESTATIC(cd, 0, md->paramslots, um);
-
-                       } else {
+                       }
+                       else {
+                               lm = iptr->sx.s23.s3.fmiref->p.method;
                                md = lm->parseddesc;
-                               gen_INVOKESTATIC(cd, (Inst **)lm->stubroutine, md->paramslots, um);
+                               gen_INVOKESTATIC(cd, (Inst **) lm->stubroutine, md->paramslots, lm);
                        }
                        break;
 
                case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
 
-                       lm = iptr->val.a;
-                       um = iptr->target;
-
-                       if (lm == NULL) {
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               um = iptr->sx.s23.s3.um;
                                md = um->methodref->parseddesc.md;
                                gen_PATCHER_INVOKESPECIAL(cd, 0, md->paramslots, um);
-
-                       } else {
+                       }
+                       else {
+                               lm = iptr->sx.s23.s3.fmiref->p.method;
                                md = lm->parseddesc;
-                               gen_INVOKESPECIAL(cd, (Inst **)lm->stubroutine, md->paramslots, um);
+                               gen_INVOKESPECIAL(cd, (Inst **) lm->stubroutine, md->paramslots, lm);
                        }
                        break;
 
                case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
 
-                       lm = iptr->val.a;
-                       um = iptr->target;
-
-                       if (lm == NULL) {
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               um = iptr->sx.s23.s3.um;
                                md = um->methodref->parseddesc.md;
                                gen_PATCHER_INVOKEVIRTUAL(cd, 0, md->paramslots, um);
-
-                       } else {
+                       }
+                       else {
+                               lm = iptr->sx.s23.s3.fmiref->p.method;
                                md = lm->parseddesc;
 
                                s1 = OFFSET(vftbl_t, table[0]) +
                                        sizeof(methodptr) * lm->vftblindex;
 
-                               gen_INVOKEVIRTUAL(cd, s1, md->paramslots, um);
+                               gen_INVOKEVIRTUAL(cd, s1, md->paramslots, lm);
                        }
                        break;
 
                case ICMD_INVOKEINTERFACE:/* op1 = arg count, val.a = method pointer  */
 
-                       lm = iptr->val.a;
-                       um = iptr->target;
-
-                       if (lm == NULL) {
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               um = iptr->sx.s23.s3.um;
                                md = um->methodref->parseddesc.md;
                                gen_PATCHER_INVOKEINTERFACE(cd, 0, 0, md->paramslots, um);
-
-                       } else {
+                       }
+                       else {
+                               lm = iptr->sx.s23.s3.fmiref->p.method;
                                md = lm->parseddesc;
 
                                s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                       sizeof(methodptr*) * lm->class->index;
+                                       sizeof(methodptr*) * lm->clazz->index;
 
-                               s2 = sizeof(methodptr) * (lm - lm->class->methods);
+                               s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
 
-                               gen_INVOKEINTERFACE(cd, s1, s2, md->paramslots, um);
+                               gen_INVOKEINTERFACE(cd, s1, s2, md->paramslots, lm);
                        }
                        break;
 
@@ -1706,16 +1728,17 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                      /* op1:   0 == array, 1 == class                */
                                      /* val.a: (classinfo *) superclass              */
 
-                       if (iptr->op1 == 1) {
-                               if (iptr->val.a == NULL)
-                                       gen_PATCHER_CHECKCAST(cd, NULL, iptr->target);
+                       if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
+                               if (INSTRUCTION_IS_UNRESOLVED(iptr))
+                                       gen_PATCHER_CHECKCAST(cd, NULL, iptr->sx.s23.s3.c.ref);
                                else
-                                       gen_CHECKCAST(cd, iptr->val.a, NULL);
-                       } else {
-                               if (iptr->val.a == NULL)
-                                       gen_PATCHER_ARRAYCHECKCAST(cd, NULL, iptr->target);
+                                       gen_CHECKCAST(cd, iptr->sx.s23.s3.c.cls, NULL);
+                       }
+                       else {
+                               if (INSTRUCTION_IS_UNRESOLVED(iptr))
+                                       gen_PATCHER_ARRAYCHECKCAST(cd, NULL, iptr->sx.s23.s3.c.ref);
                                else
-                                       gen_ARRAYCHECKCAST(cd, iptr->val.a, NULL);
+                                       gen_ARRAYCHECKCAST(cd, iptr->sx.s23.s3.c.cls, NULL);
                        }
                        break;
 
@@ -1723,24 +1746,24 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                      /* op1:   0 == array, 1 == class                */
                                      /* val.a: (classinfo *) superclass              */
 
-                       if (iptr->val.a == NULL)
-                               gen_PATCHER_INSTANCEOF(cd, NULL, iptr->target);
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr))
+                               gen_PATCHER_INSTANCEOF(cd, NULL, iptr->sx.s23.s3.c.ref);
                        else
-                               gen_INSTANCEOF(cd, iptr->val.a, iptr->target);
+                               gen_INSTANCEOF(cd, iptr->sx.s23.s3.c.cls, iptr->sx.s23.s3.c.ref);
                        break;
 
                case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
                                      /* op1 = dimension, val.a = class               */
 
-                       if (iptr->val.a == NULL) {
-                               gen_PATCHER_MULTIANEWARRAY(cd, NULL, iptr->op1, iptr->target);
-                       } else {
-                               gen_MULTIANEWARRAY(cd, iptr->val.a, iptr->op1, NULL);
-                       }
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr))
+                               gen_PATCHER_MULTIANEWARRAY(cd, NULL, iptr->s1.argcount, iptr->sx.s23.s3.c.ref);
+                       else
+                               gen_MULTIANEWARRAY(cd, iptr->sx.s23.s3.c.cls, iptr->s1.argcount, NULL);
                        break;
 
                default:
-                       *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
+                       exceptions_throw_internalerror("Unknown ICMD %d during code generation",
+                                                                                  iptr->opc);
                        return false;
        } /* switch */
                
@@ -1748,25 +1771,25 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
        gen_BBEND;
 
-       } /* if (bptr->flags >= BBREACHED) */
+       } /* if (bptr->flags != BBDELETED) */
        } /* for basic block */
 
        dseg_createlinenumbertable(cd);
 
-       codegen_finish(m, cd, (s4) (cd->mcodeptr - cd->mcodebase));
+       codegen_finish(jd);
 
 #ifdef VM_PROFILING
-       vm_block_insert(m->mcode + m->mcodelength);
+       vm_block_insert(jd->code->mcode + jd->code->mcodelength);
 #endif
 
        /* branch resolving (walk through all basic blocks) */
 
-       for (bptr = m->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) {
-                       gen_resolveanybranch(((u1*) m->entrypoint) + brefs->branchpos,
-                                            ((u1 *)m->entrypoint) + bptr->mpc);
+                       gen_resolveanybranch(((u1*) jd->code->entrypoint) + brefs->branchpos,
+                                            ((u1 *)jd->code->entrypoint) + bptr->mpc);
                }
        }
 
@@ -1783,11 +1806,11 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
    A stub consists of:
 
    +-------------+
-   | methodinfo* |
+   | codeinfo *  |
    +-------------+ <-- stub
    | codeptr     |
    +-------------+
-   | maxlocals   |
+   | framesize   |  (in ptrint units, does not include return address)
    +-------------+
    | TRANSLATE   |
    +-------------+
@@ -1800,7 +1823,7 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
 *******************************************************************************/
 
-#define COMPILERSTUB_DATASIZE    1
+#define COMPILERSTUB_DATASIZE    2
 #define COMPILERSTUB_CODESIZE    4
 
 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
@@ -1811,7 +1834,8 @@ u1 *intrp_createcompilerstub(methodinfo *m)
        Inst        *s;
        Inst        *d;
        codegendata *cd;
-       s4           dumpsize;
+       s4           stackframesize;
+       int32_t      dumpmarker;
 
        s = CNEW(Inst, COMPILERSTUB_SIZE);
 
@@ -1820,14 +1844,15 @@ u1 *intrp_createcompilerstub(methodinfo *m)
        d = s;
        s = s + COMPILERSTUB_DATASIZE;
 
-       /* Store the methodinfo* 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. */
 
        d[0] = (Inst *) m;
+       d[1] = (Inst *) &d[0];                                    /* fake code->m */
 
        /* mark start of dump memory area */
 
-       dumpsize = dump_size();
+       DMARKER;
        
        cd = DNEW(codegendata);
     cd->mcodeptr = (u1 *) s;
@@ -1837,11 +1862,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 && code_is_synchronized(code))
+                       stackframesize += 1;
+#endif
        }
 
+       genarg_i(cd, stackframesize);
+
        gen_BBSTART;
        gen_TRANSLATE(cd, m);
        gen_BBEND;
@@ -1857,7 +1890,7 @@ u1 *intrp_createcompilerstub(methodinfo *m)
 
        /* release dump area */
 
-       dump_release(dumpsize);
+       DRELEASE;
        
        return (u1 *) s;
 }
@@ -1935,25 +1968,40 @@ static ffi_cif *createnativecif(methodinfo *m, methoddesc *nmd)
 #endif
 
 
-u1 *intrp_createnativestub(functionptr f, methodinfo *m, codegendata *cd,
-                                                  registerdata *rd, methoddesc *nmd)
+u1 *intrp_createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 {
+       methodinfo   *m;
+       codeinfo     *code;
+       codegendata  *cd;
+       registerdata *rd;
 #if defined(WITH_FFI)
        ffi_cif *cif;
 #else
        u1      *cif;
 #endif
+       s4            stackframesize;
+
+       /* get required compiler data */
+
+       m    = jd->m;
+       code = jd->code;
+       cd   = jd->cd;
+       rd   = jd->rd;
+
+       /* determine stackframe size (in units of ptrint) */
+
+       stackframesize = nmd->paramslots;
 
        /* create method header */
 
-       (void) dseg_addaddress(cd, m);                          /* MethodPointer  */
-       (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 */
@@ -1979,13 +2027,13 @@ u1 *intrp_createnativestub(functionptr f, methodinfo *m, codegendata *cd,
 
        gen_BBEND;
 
-       codegen_finish(m, cd, (s4) (cd->mcodeptr - cd->mcodebase));
+       codegen_finish(jd);
 
 #ifdef VM_PROFILING
-       vm_block_insert(m->mcode + m->mcodelength);
+       vm_block_insert(jd->code->mcode + jd->code->mcodelength);
 #endif
 
-       return m->entrypoint;
+       return jd->code->entrypoint;
 }
 
 
@@ -2035,10 +2083,10 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
                assert(false);
        }
 
-       av_ptr(alist, _Jv_JNIEnv *, _Jv_env);
+       av_ptr(alist, _Jv_JNIEnv *, VM_get_jnienv());
 
        if (m->flags & ACC_STATIC)
-               av_ptr(alist, classinfo *, m->class);
+               av_ptr(alist, classinfo *, m->clazz);
 
        for (i = 0, p = sp + md->paramslots; i < md->paramcount; i++) {
                switch (md->paramtypes[i].type) {
@@ -2071,12 +2119,12 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
 
        /* create stackframe info structure */
 
-       codegen_start_native_call(((u1 *) &s) + sizeof(s), m->entrypoint,
+       codegen_start_native_call(((u1 *) &s) + sizeof(s), m->code->entrypoint,
                                                          (u1 *) fp, (u1 *) ra);
 
        av_call(alist);
 
-       codegen_finish_native_call(((u1 *) &s) + sizeof(s));
+       *exceptionptr = codegen_finish_native_call(((u1 *) &s) + sizeof(s));
 
        CLEAR_global_sp;
 
@@ -2100,13 +2148,13 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
 
        /* pass env pointer */
 
-       penv = (_Jv_JNIEnv *) _Jv_env;
+       penv = (_Jv_JNIEnv *) VM_get_jnienv();
        *pvalues++ = &penv;
 
        /* for static methods, pass class pointer */
 
        if (m->flags & ACC_STATIC)
-               *pvalues++ = &m->class;
+               *pvalues++ = &m->clazz;
 
        /* pass parameter to native function */
 
@@ -2130,12 +2178,12 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
 
        /* create stackframe info structure */
 
-       codegen_start_native_call(((u1 *) &s) + sizeof(s), m->entrypoint,
+       codegen_start_native_call(((u1 *) &s) + sizeof(s), m->code->entrypoint,
                                                          (u1 *) fp, (u1 *) ra);
 
        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;
 
@@ -2148,37 +2196,51 @@ u1 *createcalljavafunction(methodinfo *m)
 {
        methodinfo         *tmpm;
        u1                 *entrypoint;
+       jitdata            *jd;
        codegendata        *cd;
        registerdata       *rd;
-       s4                  dumpsize;
        methoddesc         *md;
+       int32_t             dumpmarker;
 
        /* mark dump memory */
 
-       dumpsize = dump_size();
+       DMARKER;
+
+       /* allocate memory */
+
+       jd = DNEW(jitdata);
 
        tmpm = DNEW(methodinfo);
        cd = DNEW(codegendata);
        rd = DNEW(registerdata);
 
+       jd->m = tmpm;
+       jd->flags = 0;
+       jd->cd = cd;
+       jd->rd = rd;
+
+       /* Allocate codeinfo memory from the heap as we need to keep them. */
+
+       jd->code = code_codeinfo_new(tmpm); /* XXX check allocation */
+
        /* setup code generation stuff */
 
        MSET(tmpm, 0, u1, sizeof(methodinfo));
 
-       codegen_setup(tmpm, cd);
+       codegen_setup(jd);
 
        md = m->parseddesc;
 
        /* create method header */
 
-       (void) dseg_addaddress(cd, NULL);                       /* MethodPointer  */
-       (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 */
@@ -2189,16 +2251,16 @@ u1 *createcalljavafunction(methodinfo *m)
 
        gen_BBEND;
 
-       codegen_finish(tmpm, cd, (s4) (cd->mcodeptr - cd->mcodebase));
+       codegen_finish(jd);
 
 #ifdef VM_PROFILING
-       vm_block_insert(tmpm->mcode + tmpm->mcodelength);
+       vm_block_insert(jd->code->mcode + jd->code->mcodelength);
 #endif
-       entrypoint = tmpm->entrypoint;
+       entrypoint = jd->code->entrypoint;
 
        /* release memory */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return entrypoint;
 }
@@ -2215,4 +2277,5 @@ u1 *createcalljavafunction(methodinfo *m)
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */