* Removed all Id tags.
[cacao.git] / src / vm / jit / intrp / codegen.c
index ebe8b20d7acfa6c4b883751af0c98ecfc3af4cc2..e49678bea92f6f5d4c51fb37c8c0a4068351a4c4 100644 (file)
@@ -1,9 +1,9 @@
 /* src/vm/jit/intrp/codegen.c - code generator for Interpreter
 
-   Copyright (C) 1996-2005 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 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
 
    This file is part of CACAO.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.
-
-   Contact: cacao@complang.tuwien.ac.at
-
-   Authors: Andreas Krall
-            Reinhard Grafl
-
-   Changes: Christian Thalinger
-            Anton Ertl
-
-   $Id: codegen.c 4172 2006-01-12 22:37:33Z twisti $
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
 */
 
 #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 "cacao/cacao.h"
+#include "mm/memory.h"
+
 #include "native/native.h"
+
 #include "vm/builtin.h"
-#include "vm/class.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/loader.h"
-#include "vm/options.h"
 #include "vm/stringlocal.h"
+#include "vm/vm.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/dseg.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher.h"
+#include "vm/jit/stack.h"
+#include "vm/jit/stacktrace.h"
 
-#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 "vmcore/class.h"
+#include "vmcore/options.h"
 
 
 #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 +160,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 +212,8 @@ void genarg_avftbl(codegendata *cd1, vftbl_t *a)
 
 /* include the interpreter generation functions *******************************/
 
-#include "vm/jit/intrp/java-gen.i"
+/* Do not use "java-gen.i", it does not work with builddir. */
+#include <java-gen.i>
 
 
 typedef void (*genfunctionptr) (codegendata *);
@@ -233,9 +238,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 +280,31 @@ 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;
+       exception_entry    *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,33 +313,42 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
        lm = NULL;
        bte = NULL;
 
+       /* determine stackframe size (in units of ptrint slots) */
+
+       cd->stackframesize = m->maxlocals;
+
+#if defined(ENABLE_THREADS)
+       if (checksync && (m->flags & ACC_SYNCHRONIZED))
+               cd->stackframesize += 1;
+#endif
+
        /* create method header */
 
-       (void) dseg_addaddress(cd, m);                          /* MethodPointer  */
-       (void) dseg_adds4(cd, m->maxlocals * SIZEOF_VOID_P);    /* FrameSize      */
+       (void) dseg_add_unique_address(cd, jd->code);
+       (void) dseg_add_unique_s4(cd, cd->stackframesize * SIZEOF_VOID_P);
 
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
        if (checksync && (m->flags & ACC_SYNCHRONIZED))
-               (void) dseg_adds4(cd, 1);                           /* IsSync         */
+               (void) dseg_add_unique_s4(cd, 1);
        else
 #endif
-               (void) dseg_adds4(cd, 0);                           /* IsSync         */
+               (void) dseg_add_unique_s4(cd, 0);
                                               
-       (void) dseg_adds4(cd, 0);                               /* IsLeaf         */
-       (void) dseg_adds4(cd, 0);                               /* IntSave        */
-       (void) dseg_adds4(cd, 0);                               /* FltSave        */
+       (void) dseg_add_unique_s4(cd, 0);
+       (void) dseg_add_unique_s4(cd, 0);
+       (void) dseg_add_unique_s4(cd, 0);
 
        dseg_addlinenumbertablesize(cd);
 
-       (void) dseg_adds4(cd, cd->exceptiontablelength);        /* ExTableSize    */
+       (void) dseg_add_unique_s4(cd, jd->exceptiontablelength);
 
        /* create exception table */
 
-       for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
-               dseg_addtarget(cd, ex->start);
-               dseg_addtarget(cd, ex->end);
-               dseg_addtarget(cd, ex->handler);
-               (void) dseg_addaddress(cd, ex->catchtype.cls);
+       for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
+               dseg_add_target(cd, ex->start);
+               dseg_add_target(cd, ex->end);
+               dseg_add_target(cd, ex->handler);
+               (void) dseg_add_unique_address(cd, ex->catchtype.any);
        }
 
 #if 0  
@@ -333,45 +360,49 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
        gen_BBSTART;
 
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
        if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
-               if (m->flags & ACC_STATIC)
+               if (m->flags & ACC_STATIC) {
                        gen_ACONST(cd, (java_objectheader *) m->class);
-               else
+               }
+               else {
                        gen_ALOAD(cd, 0);
+                       gen_DUP(cd);
+                       gen_ASTORE(cd, index2offset(m->maxlocals));
+               }
                
                gen_MONITORENTER(cd);
        }                       
 #endif
 
-       if (runverbose)
-               gen_TRACECALL(cd);
+       if (opt_verbosecall)
+               gen_TRACECALL(cd, m);
 
        gen_BBEND;
 
        /* 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,21 +422,136 @@ 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                       */
                                      /* op1 = 0, val.f = constant                    */
                        {
-                               s4 fi;
+                               ptrint fi;
 
-                               vm_f2Cell(iptr->val.f, fi);
+                               vm_f2Cell(iptr->sx.val.f, fi);
                                gen_ICONST(cd, fi);
                        }
                        break;
@@ -413,16 +559,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 +577,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 +651,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 +671,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 +728,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 +776,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 +802,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 +885,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;
 
 
@@ -1035,11 +1045,15 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        break;
 
                case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
-               case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
 
                        gen_IALOAD(cd);
                        break;
 
+               case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
+
+                       gen_FALOAD(cd);
+                       break;
+
                case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
                case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
 
@@ -1064,11 +1078,15 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        break;
 
                case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
-               case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
 
                        gen_IASTORE(cd);
                        break;
 
+               case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
+
+                       gen_FASTORE(cd);
+                       break;
+
                case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
                case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
 
@@ -1084,142 +1102,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:
-                       case TYPE_FLT:
-                               if ((fi == NULL) || !(fi->class->state & CLASS_INITIALIZED)) {
+                               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->class))
+                                       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)
+                                       gen_PATCHER_GETSTATIC_FLOAT(cd, 0, uf);
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+                                       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) || !(fi->class->state & CLASS_INITIALIZED)) {
+                               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->class))
+                                       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) || !(fi->class->state & CLASS_INITIALIZED)) {
+                               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->class))
+                                       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:
-                       case TYPE_FLT:
-                               if ((fi == NULL) || !(fi->class->state & CLASS_INITIALIZED)) {
+                               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->class))
+                                       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)
+                                       gen_PATCHER_PUTSTATIC_FLOAT(cd, 0, uf);
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+                                       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) || !(fi->class->state & CLASS_INITIALIZED)) {
+                               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->class))
+                                       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) || !(fi->class->state & CLASS_INITIALIZED)) {
+                               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->class))
+                                       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:
-                       case TYPE_FLT:
-                               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)
+                                       gen_PATCHER_GETFIELD_FLOAT(cd, 0, 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:
-                       case TYPE_FLT:
-                               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)
+                                       gen_PATCHER_PUTFIELD_FLOAT(cd, 0, 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;
 
 
@@ -1237,13 +1303,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 ==> ...                         */
@@ -1261,10 +1329,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;
@@ -1272,10 +1340,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;
@@ -1283,10 +1351,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;
@@ -1294,10 +1362,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;
@@ -1305,10 +1373,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;
@@ -1316,138 +1384,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;
 
 
@@ -1455,133 +1525,138 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
                case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
 
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
                        if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
                                if (m->flags & ACC_STATIC) {
                                        gen_ACONST(cd, (java_objectheader *) m->class);
                                } else {
-                                       gen_ALOAD(cd, 0);
+                                       gen_ALOAD(cd, index2offset(m->maxlocals));
                                }
                                gen_MONITOREXIT(cd);
                        }
 #endif
-                       if (runverbose)
-                               gen_TRACERETURN(cd);
+                       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 defined(ENABLE_THREADS)
                        if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
                                if (m->flags & ACC_STATIC) {
                                        gen_ACONST(cd, (java_objectheader *) m->class);
                                } else {
-                                       gen_ALOAD(cd, 0);
+                                       gen_ALOAD(cd, index2offset(m->maxlocals));
                                }
                                gen_MONITOREXIT(cd);
                        }
 #endif
-                       if (runverbose)
-                               gen_TRACELRETURN(cd);
+                       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 defined(ENABLE_THREADS)
                        if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
                                if (m->flags & ACC_STATIC) {
                                        gen_ACONST(cd, (java_objectheader *) m->class);
                                } else {
-                                       gen_ALOAD(cd, 0);
+                                       gen_ALOAD(cd, index2offset(m->maxlocals));
                                }
                                gen_MONITOREXIT(cd);
                        }
 #endif
-                       if (runverbose)
-                               gen_TRACERETURN(cd);
+                       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;
 
-                       /* arguments: low, range, datasegment address, table offset in     */
-                       /* datasegment, default target                                    */
+                       /* arguments: low, range, datasegment address, table
+                      offset in datasegment, default target */
+
                        gen_TABLESWITCH(cd, l, i, NULL, 0, NULL);
-                       dseg_adddata(cd, (cd->mcodeptr - 2*sizeof(Inst))); /* actually -3 cells offset*/
-                       codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
+
+                       /* actually -3 cells offset */
+
+                       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];
@@ -1590,70 +1665,68 @@ 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]) -
@@ -1661,7 +1734,7 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
                                s2 = sizeof(methodptr) * (lm - lm->class->methods);
 
-                               gen_INVOKEINTERFACE(cd, s1, s2, md->paramslots, um);
+                               gen_INVOKEINTERFACE(cd, s1, s2, md->paramslots, lm);
                        }
                        break;
 
@@ -1670,16 +1743,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;
 
@@ -1687,24 +1761,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 */
                
@@ -1712,25 +1786,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);
                }
        }
 
@@ -1740,33 +1814,57 @@ bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 }
 
 
-/* a stub consists of
+/* createcompilerstub **********************************************************
 
-+---------+
-|codeptr  |
-+---------+
-|maxlocals|
-+---------+
-|TRANSLATE|
-+---------+
-|methodinf|
-+---------+
+   Creates a stub routine which calls the compiler.
 
-codeptr points either to TRANSLATE or to the translated threaded code
+   A stub consists of:
 
-all methods are called indirectly through methodptr
-*/
+   +-------------+
+   | codeinfo *  |
+   +-------------+ <-- stub
+   | codeptr     |
+   +-------------+
+   | framesize   |  (in ptrint units, does not include return address)
+   +-------------+
+   | TRANSLATE   |
+   +-------------+
+   | methodinfo  |
+   +-------------+
+
+   codeptr points either to TRANSLATE or to the translated threaded code
+
+   all methods are called indirectly through methodptr
+
+*******************************************************************************/
+
+#define COMPILERSTUB_DATASIZE    2
+#define COMPILERSTUB_CODESIZE    4
+
+#define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
 
-#define COMPILERSTUB_SIZE 4
 
 u1 *intrp_createcompilerstub(methodinfo *m)
 {
        Inst        *s;
+       Inst        *d;
        codegendata *cd;
        s4           dumpsize;
+       s4           stackframesize;
 
        s = CNEW(Inst, COMPILERSTUB_SIZE);
 
+       /* set data pointer and code pointer */
+
+       d = s;
+       s = s + COMPILERSTUB_DATASIZE;
+
+       /* 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();
@@ -1779,11 +1877,19 @@ u1 *intrp_createcompilerstub(methodinfo *m)
        genarg_ainst(cd, s + 2);
 
        if (m->flags & ACC_NATIVE) {
-               genarg_i(cd, m->parseddesc->paramslots);
-       } else {
-               genarg_i(cd, m->maxlocals);
+               stackframesize = m->parseddesc->paramslots;
+       } 
+       else {
+               stackframesize = m->maxlocals;
+
+#if defined(ENABLE_THREADS)
+               if (checksync && (m->flags & ACC_SYNCHRONIZED))
+                       stackframesize += 1;
+#endif
        }
 
+       genarg_i(cd, stackframesize);
+
        gen_BBSTART;
        gen_TRANSLATE(cd, m);
        gen_BBEND;
@@ -1805,6 +1911,33 @@ u1 *intrp_createcompilerstub(methodinfo *m)
 }
 
 
+#if defined(WITH_FFI)
+static ffi_type *cacaotype2ffitype(s4 cacaotype)
+{
+       switch (cacaotype) {
+       case TYPE_INT:
+#if SIZEOF_VOID_P == 8
+               return &ffi_type_sint64;
+#else
+               return &ffi_type_sint32;
+#endif
+       case TYPE_LNG:
+               return &ffi_type_sint64;
+       case TYPE_FLT:
+               return &ffi_type_float;
+       case TYPE_DBL:
+               return &ffi_type_double;
+       case TYPE_ADR:
+               return &ffi_type_pointer;
+       case TYPE_VOID:
+               return &ffi_type_void;
+       default:
+               assert(false);
+       }
+}
+#endif
+
+
 /* native stub:
 +---------+
 |NATIVECALL|
@@ -1850,25 +1983,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 */
@@ -1880,13 +2028,13 @@ u1 *intrp_createnativestub(functionptr f, methodinfo *m, codegendata *cd,
 
        gen_BBSTART;
 
-       if (runverbose)
-               gen_TRACECALL(cd);
+       if (opt_verbosecall)
+               gen_TRACECALL(cd, m);
 
        if (f == NULL) {
                gen_PATCHER_NATIVECALL(cd, m, f, (u1 *)cif);
        } else {
-               if (runverbose)
+               if (opt_verbosecall)
                        gen_TRACENATIVECALL(cd, m, f, (u1 *)cif);
                else
                        gen_NATIVECALL(cd, m, f, (u1 *)cif);
@@ -1894,37 +2042,14 @@ 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;
-}
-
-
-#if defined(WITH_FFI)
-ffi_type *cacaotype2ffitype(s4 cacaotype)
-{
-       switch (cacaotype) {
-       case TYPE_INT:
-               return &ffi_type_uint;
-       case TYPE_LNG:
-               return &ffi_type_sint64;
-       case TYPE_FLT:
-               return &ffi_type_float;
-       case TYPE_DBL:
-               return &ffi_type_double;
-       case TYPE_ADR:
-               return &ffi_type_pointer;
-       case TYPE_VOID:
-               return &ffi_type_void;
-       default:
-               assert(false);
-       }
+       return jd->code->entrypoint;
 }
-#endif
 
 
 /* call jni function */
@@ -1947,7 +2072,7 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
        switch (md->returntype.type) {
        case TYPE_INT:
                endsp = sp - 1 + md->paramslots;
-               av_start_int(alist, f, endsp);
+               av_start_long(alist, f, endsp);
                break;
        case TYPE_LNG:
                endsp = sp - 2 + md->paramslots;
@@ -1973,7 +2098,7 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
                assert(false);
        }
 
-       av_ptr(alist, JNIEnv *, &env);
+       av_ptr(alist, _Jv_JNIEnv *, _Jv_env);
 
        if (m->flags & ACC_STATIC)
                av_ptr(alist, classinfo *, m->class);
@@ -1982,7 +2107,7 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
                switch (md->paramtypes[i].type) {
                case TYPE_INT:
                        p -= 1;
-                       av_int(alist, *p);
+                       av_long(alist, *p);
                        break;
                case TYPE_LNG:
                        p -= 2;
@@ -1990,7 +2115,7 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
                        break;
                case TYPE_FLT:
                        p -= 1;
-                       av_float(alist, *(float *) p);
+                       av_float(alist, *((float *) p));
                        break;
                case TYPE_DBL:
                        p -= 2;
@@ -2009,12 +2134,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;
 
@@ -2027,7 +2152,7 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
        Cell        *p;
        Cell        *endsp;
        s4           i;
-       JNIEnv      *penv;
+       _Jv_JNIEnv  *penv;
 
        struct {
                stackframeinfo sfi;
@@ -2038,14 +2163,13 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
 
        /* pass env pointer */
 
-       penv = (JNIEnv *) &env;
+       penv = (_Jv_JNIEnv *) _Jv_env;
        *pvalues++ = &penv;
 
        /* for static methods, pass class pointer */
 
-       if (m->flags & ACC_STATIC) {
+       if (m->flags & ACC_STATIC)
                *pvalues++ = &m->class;
-       }
 
        /* pass parameter to native function */
 
@@ -2069,12 +2193,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;
 
@@ -2087,9 +2211,9 @@ u1 *createcalljavafunction(methodinfo *m)
 {
        methodinfo         *tmpm;
        u1                 *entrypoint;
+       jitdata            *jd;
        codegendata        *cd;
        registerdata       *rd;
-       t_inlining_globals *id;
        s4                  dumpsize;
        methoddesc         *md;
 
@@ -2097,30 +2221,41 @@ u1 *createcalljavafunction(methodinfo *m)
 
        dumpsize = dump_size();
 
+       /* allocate memory */
+
+       jd = DNEW(jitdata);
+
        tmpm = DNEW(methodinfo);
        cd = DNEW(codegendata);
        rd = DNEW(registerdata);
-       id = DNEW(t_inlining_globals);
+
+       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));
 
-       inlining_setup(tmpm, id);
-       codegen_setup(tmpm, cd, id);
+       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 */
@@ -2131,12 +2266,12 @@ 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 */
 
@@ -2157,4 +2292,5 @@ u1 *createcalljavafunction(methodinfo *m)
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */