* src/vm/jit/parse.c (parse_resolve_exception_table): Do not use
[cacao.git] / src / vm / jit / parse.c
index 5261fd80cffb01b744f3b66d32583f2a6dd9b021..e604a943136eafe8babe812a0ee8b4f8c44ef6bc 100644 (file)
@@ -31,7 +31,7 @@
             Joseph Wenninger
             Christian Thalinger
 
-   $Id: parse.c 4760 2006-04-12 20:06:23Z edwin $
+   $Id: parse.c 5790 2006-10-16 09:59:52Z edwin $
 
 */
 
 
 #include "mm/memory.h"
 #include "native/native.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#endif
+
 #include "toolbox/logging.h"
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/options.h"
 #include "vm/statistics.h"
 #include "vm/stringlocal.h"
+#include "vm/suck.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher.h"
 #include "vm/jit/loop/loop.h"
 
-/*******************************************************************************
+#define INSTRUCTIONS_INCREMENT  5  /* number of additional instructions to    */
+                                   /* allocate if space runs out              */
 
-       function 'parse' scans the JavaVM code and generates intermediate code
 
-       During parsing the block index table is used to store at bit pos 0
-       a flag which marks basic block starts and at position 1 to 31 the
-       intermediate instruction index. After parsing the block index table
-       is scanned, for marked positions a block is generated and the block
-       number is stored in the block index table.
+/* parserdata_t ***************************************************************/
+
+typedef struct parsedata_t parsedata_t;
+
+struct parsedata_t {
+       instruction *instructions;          /* instruction array                  */
+       s4           instructionslength;    /* length of the instruction array    */
+       u1          *instructionstart;
+};
+
+
+/* parse_setup *****************************************************************
+
+   Fills the passed parsedata_t structure.
+
+*******************************************************************************/
+
+static void parse_setup(jitdata *jd, parsedata_t *pd)
+{
+       methodinfo *m;
+
+       /* get required compiler data */
+
+       m = jd->m;
+
+       /* Allocate instruction array and block index table (1 additional
+          for end ipc). */
+
+       jd->basicblockindex = DMNEW(s4, m->jcodelength + 1);
+       pd->instructionstart = DMNEW(u1, m->jcodelength + 1);
+
+       MZERO(jd->basicblockindex, s4, m->jcodelength + 1);
+       MZERO(pd->instructionstart, u1, m->jcodelength + 1);
+
+       /* Set the length of the instruction array.  We simply add 5 more
+          instruction, as this seems to be a reasonable value. */
+
+       pd->instructionslength = m->jcodelength + 1;
+
+       /* allocate the instruction array */
+
+       pd->instructions = DMNEW(instruction, pd->instructionslength);
+
+       /* Zero the intermediate instructions array so we don't have any
+          invalid pointers in it if we cannot finish stack_analyse(). */
+
+       MZERO(pd->instructions, instruction, pd->instructionslength);
+}
+
+
+/* parse_realloc_instructions **************************************************
+
+   Reallocate the instructions array so there is room for at least N 
+   additional instructions.
+
+   RETURN VALUE:
+       the new value for iptr
+
+*******************************************************************************/
+
+static instruction *parse_realloc_instructions(parsedata_t *pd, s4 ipc, s4 n)
+{
+       /* increase the size of the instruction array */
+
+       pd->instructionslength += (n + INSTRUCTIONS_INCREMENT);
+
+       /* reallocate the array */
+
+       pd->instructions = DMREALLOC(pd->instructions, instruction, ipc,
+                                                                pd->instructionslength);
+
+       /* return the iptr */
+
+       return pd->instructions + ipc;
+}
+
+
+/* parse_mark_exception_boundaries *********************************************
+
+   Mark exception handlers and the boundaries of the handled regions as
+   basic block boundaries.
+
+   IN:
+       jd...............current jitdata
+
+   RETURN VALUE:
+       >= 0.............the number of new basic blocks marked
+          -1...............an exception has been thrown
 
 *******************************************************************************/
 
-static exceptiontable * fillextable(methodinfo *m, 
-                                                                       exceptiontable *extable, 
-                                                                       exceptiontable *raw_extable, 
-                                                               int exceptiontablelength, 
-                                                                       int *block_count)
+static int parse_mark_exception_boundaries(jitdata *jd)
 {
-       int b_count, p, src;
+       s4                   b_count;
+       s4                   pc;
+       s4                   i;
+       s4                   len;
+       raw_exception_entry *rex;
+       methodinfo          *m;
+
+       m = jd->m;
        
-       if (exceptiontablelength == 0) 
-               return extable;
+       len = m->rawexceptiontablelength;
 
-       b_count = *block_count;
+       if (len == 0)
+               return 0;
+
+       b_count = 0;
+       rex = m->rawexceptiontable;
+
+       for (i = 0; i < len; ++i, ++rex) {
 
-       for (src = exceptiontablelength-1; src >=0; src--) {
                /* the start of the handled region becomes a basic block start */
-               p = raw_extable[src].startpc;
-               CHECK_BYTECODE_INDEX(p);
-               extable->startpc = p;
-               block_insert(p);
+
+               pc = rex->startpc;
+               CHECK_BYTECODE_INDEX(pc);
+               MARK_BASICBLOCK(pc);
                
-               p = raw_extable[src].endpc; /* see JVM Spec 4.7.3 */
-               CHECK_BYTECODE_INDEX_EXCLUSIVE(p);
+               pc = rex->endpc; /* see JVM Spec 4.7.3 */
+               CHECK_BYTECODE_INDEX_EXCLUSIVE(pc);
+
+               /* check that the range is valid */
 
 #if defined(ENABLE_VERIFIER)
-               if (p <= raw_extable[src].startpc) {
-                       *exceptionptr = new_verifyerror(m,
+               if (pc <= rex->startpc) {
+                       exceptions_throw_verifyerror(m,
                                "Invalid exception handler range");
-                       return NULL;
+                       return -1;
                }
 #endif
-               extable->endpc = p;
                
                /* end of handled region becomes a basic block boundary  */
                /* (If it is the bytecode end, we'll use the special     */
                /* end block that is created anyway.)                    */
-               if (p < m->jcodelength) 
-                       block_insert(p);
+
+               if (pc < m->jcodelength)
+                       MARK_BASICBLOCK(pc);
 
                /* the start of the handler becomes a basic block start  */
-               p = raw_extable[src].handlerpc;
-               CHECK_BYTECODE_INDEX(p);
-               extable->handlerpc = p;
-               block_insert(p);
-
-               extable->catchtype = raw_extable[src].catchtype;
-               extable->next = NULL;
-               extable->down = &extable[1];
-               extable--;
+
+               pc = rex->handlerpc;
+               CHECK_BYTECODE_INDEX(pc);
+               MARK_BASICBLOCK(pc);
        }
 
-       *block_count = b_count;
-       
        /* everything ok */
-       return extable;
+
+       return b_count;
 
 #if defined(ENABLE_VERIFIER)
 throw_invalid_bytecode_index:
-       *exceptionptr =
-               new_verifyerror(m, "Illegal bytecode index in exception table");
-       return NULL;
+       exceptions_throw_verifyerror(m,
+                                                                "Illegal bytecode index in exception table");
+       return -1;
 #endif
 }
 
+
+/* parse_resolve_exception_table ***********************************************
+
+   Enter the exception handlers and their ranges, resolved to basicblock *s,
+   in the jitdata.
+
+   IN:
+       jd...............current jitdata
+
+   RETURN VALUE:
+          true.............everything ok
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+static bool parse_resolve_exception_table(jitdata *jd)
+{
+       methodinfo          *m;
+       raw_exception_entry *rex;
+       exception_entry     *ex;
+       s4                   i;
+       s4                   len;
+       classinfo           *exclass;
+
+       m = jd->m;
+
+       len = m->rawexceptiontablelength;
+
+       /* common case: no handler entries */
+
+       if (len == 0)
+               return true;
+
+       /* allocate the exception table */
+
+       jd->exceptiontablelength = len;
+       jd->exceptiontable = DMNEW(exception_entry, len + 1); /* XXX why +1? */
+
+       /* copy and resolve the entries */
+
+       ex = jd->exceptiontable;
+       rex = m->rawexceptiontable;
+
+       for (i = 0; i < len; ++i, ++rex, ++ex) {
+               /* resolve instruction indices to basic blocks */
+
+               ex->start   = BLOCK_OF(rex->startpc);
+               ex->end     = BLOCK_OF(rex->endpc);
+               ex->handler = BLOCK_OF(rex->handlerpc);
+
+               /* lazily resolve the catchtype */
+
+               if (rex->catchtype.any != NULL) {
+                       if (!resolve_classref_or_classinfo(m,
+                                                                                          rex->catchtype,
+                                                                                          resolveLazy, true, false,
+                                                                                          &exclass))
+                               return false;
+
+                       /* if resolved, enter the result of resolution in the table */
+
+                       if (exclass != NULL)
+                               rex->catchtype.cls = exclass;
+               }
+
+               ex->catchtype = rex->catchtype;
+               ex->next = NULL;   /* set by loop analysis */
+               ex->down = ex + 1; /* link to next exception entry */
+       }
+
+       /* terminate the ->down linked list */
+
+       assert(ex != jd->exceptiontable);
+       ex[-1].down = NULL;
+
+       return true;
+}
+
+
+/*******************************************************************************
+
+       function 'parse' scans the JavaVM code and generates intermediate code
+
+       During parsing the block index table is used to store at bit pos 0
+       a flag which marks basic block starts and at position 1 to 31 the
+       intermediate instruction index. After parsing the block index table
+       is scanned, for marked positions a block is generated and the block
+       number is stored in the block index table.
+
+*******************************************************************************/
+
 /*** macro for checking the length of the bytecode ***/
 
 #if defined(ENABLE_VERIFIER)
@@ -150,95 +333,99 @@ throw_invalid_bytecode_index:
 
 bool parse(jitdata *jd)
 {
-       methodinfo  *m;
-       codegendata *cd;
-       int  p;                     /* java instruction counter           */
-       int  nextp;                 /* start of next java instruction     */
-       int  opcode;                /* java opcode                        */
-       int  i;                     /* temporary for different uses (ctrs)*/
-       int  ipc = 0;               /* intermediate instruction counter   */
-       int  b_count = 0;           /* basic block counter                */
-       int  s_count = 0;           /* stack element counter              */
-       bool blockend = false;      /* true if basic block end has been reached   */
-       bool iswide = false;        /* true if last instruction was a wide*/
-       instruction *iptr;          /* current ptr into instruction array */
-       int gp;                     /* global java instruction counter    */
-
-       u1 *instructionstart;       /* 1 for pcs which are valid instr. starts    */
-
+       methodinfo  *m;                     /* method being parsed                */
+       codeinfo    *code;
+       parsedata_t  pd;
+       instruction *iptr;                  /* current ptr into instruction array */
+       s4           ipc;                   /* intermediate instruction counter   */
+       s4           p;                     /* java instruction counter           */
+       s4           nextp;                 /* start of next java instruction     */
+       s4           opcode;                /* java opcode                        */
+       s4           i;
+       s4           j;
+       int  b_count;               /* basic block counter                      */
+       int  s_count = 0;           /* stack element counter                    */
+       bool blockend = false;      /* true if basic block end has been reached */
+       bool iswide = false;        /* true if last instruction was a wide      */
        constant_classref  *cr;
        constant_classref  *compr;
        classinfo          *c;
        builtintable_entry *bte;
-
-       constant_FMIref   *mr;
-       methoddesc        *md;
-       unresolved_method *um;
-       methodinfo        *mi;
-       resolve_result_t   result;
-
-       u2 lineindex = 0;
-       u2 currentline = 0;
-       u2 linepcchange = 0;
-
+       constant_FMIref    *mr;
+       methoddesc         *md;
+       unresolved_method  *um;
+       resolve_result_t    result;
+       u2                  lineindex = 0;
+       u2                  currentline = 0;
+       u2                  linepcchange = 0;
+       u4                  flags;
+       basicblock         *bptr;
+
+       int                *local_map; /* local pointer to renaming structore     */
+                                      /* is assigned to rd->local_map at the end */
        /* get required compiler data */
 
-       m  = jd->m;
-       cd = jd->cd;
-
-       /* allocate instruction array and block index table */
-       
-       /* 1 additional for end ipc  */
-       m->basicblockindex = DMNEW(s4, m->jcodelength + 1);
-       memset(m->basicblockindex, 0, sizeof(s4) * (m->jcodelength + 1));
-
-       instructionstart = DMNEW(u1, m->jcodelength + 1);
-       memset(instructionstart, 0, sizeof(u1) * (m->jcodelength + 1));
-
-       /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
-       /* additional MONITOREXITS are reached by branches which are 3 bytes */
-       
-       iptr = m->instructions = DMNEW(instruction, m->jcodelength + 5);
-
-       /* Zero the intermediate instructions array so we don't have any
-        * invalid pointers in it if we cannot finish analyse_stack(). */
-
-       memset(iptr, 0, sizeof(instruction) * (m->jcodelength + 5));
-       
-       /* compute branch targets of exception table */
+       m    = jd->m;
+       code = jd->code;
+
+       /* allocate buffers for local variable renaming */
+       local_map = DMNEW(int, m->maxlocals * 5);
+       for (i = 0; i < m->maxlocals; i++) {
+               local_map[i * 5 + 0] = 0;
+               local_map[i * 5 + 1] = 0;
+               local_map[i * 5 + 2] = 0;
+               local_map[i * 5 + 3] = 0;
+               local_map[i * 5 + 4] = 0;
+       }
 
-       if (!fillextable(m, 
-                       &(cd->exceptiontable[cd->exceptiontablelength-1]), 
-                       m->exceptiontable, 
-                       m->exceptiontablelength, 
-                       &b_count))
-       {
+       /* initialize the parse data structures */
+  
+       parse_setup(jd, &pd);
+  
+       /* initialize local variables */
+  
+       iptr = pd.instructions;
+       ipc  = 0;
+  
+       /* mark basic block boundaries for exception table */
+
+       b_count = parse_mark_exception_boundaries(jd);
+       if (b_count < 0)
                return false;
-       }
 
-       s_count = 1 + m->exceptiontablelength; /* initialize stack element counter   */
+       /* initialize stack element counter */
 
-#if defined(USE_THREADS)
-       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
-               m->isleafmethod = false;
-       }                       
+       s_count = 1 + m->rawexceptiontablelength;
+
+#if defined(ENABLE_THREADS)
+       if (checksync && (m->flags & ACC_SYNCHRONIZED))
+               jd->isleafmethod = false;
 #endif
 
-       /* scan all java instructions */
+       /* setup line number info */
+
        currentline = 0;
        linepcchange = 0;
 
        if (m->linenumbercount == 0) {
                lineindex = 0;
-       } 
+       }
        else {
                linepcchange = m->linenumbers[0].start_pc;
        }
 
-       for (p = 0, gp = 0; p < m->jcodelength; gp += (nextp - p), p = nextp) {
-         
+       /*** LOOP OVER ALL BYTECODE INSTRUCTIONS **********************************/
+
+       for (p = 0; p < m->jcodelength; p = nextp) {
+
                /* mark this position as a valid instruction start */
-               instructionstart[gp] = 1;
+
+               pd.instructionstart[p] = 1;
+
+               /* change the current line number, if necessary */
+
+               /* XXX rewrite this using pointer arithmetic */
+
                if (linepcchange == p) {
                        if (m->linenumbercount > lineindex) {
 next_linenumber:
@@ -252,53 +439,79 @@ next_linenumber:
                        }
                }
 
-               /* fetch next opcode  */
 fetch_opcode:
-               opcode = code_get_u1(p, m);
+               /* fetch next opcode  */        
 
-               m->basicblockindex[gp] |= (ipc << 1); /*store intermed cnt*/
+               opcode = SUCK_BE_U1(m->jcode + p);
 
                /* some compilers put a JAVA_NOP after a blockend instruction */
 
                if (blockend && (opcode != JAVA_NOP)) {
                        /* start new block */
 
-                       block_insert(gp);
+                       MARK_BASICBLOCK(p);
                        blockend = false;
                }
 
-               nextp = p + jcommandsize[opcode];   /* compute next instruction start */
+               /* We need a NOP as last instruction in each basic block
+                  for basic block reordering (may be replaced with a GOTO
+                  later). */
+
+               if (jd->basicblockindex[p] & 1) {
+                       INSTRUCTIONS_CHECK(1);
+                       OP(ICMD_NOP);
+               }
+
+               /* store intermediate instruction count (bit 0 mark block starts) */
+
+               jd->basicblockindex[p] |= (ipc << 1);
+
+               /* compute next instruction start */
+
+               nextp = p + jcommandsize[opcode];
 
                CHECK_END_OF_BYTECODE(nextp);
 
-               s_count += stackreq[opcode];            /* compute stack element count    */
+               /* add stack elements produced by this instruction */
+
+               s_count += stackreq[opcode];
+
+               /* We check here for the space of 1 instruction in the
+                  instruction array.  If an opcode is converted to more than
+                  1 instruction, this is checked in the corresponding
+                  case. */
+
+               INSTRUCTIONS_CHECK(1);
+
+               /* translate this bytecode instruction */
                switch (opcode) {
+
                case JAVA_NOP:
                        break;
 
-                       /* pushing constants onto the stack p */
+               /* pushing constants onto the stack ***********************************/
 
                case JAVA_BIPUSH:
-                       LOADCONST_I(code_get_s1(p+1,m));
+                       OP_LOADCONST_I(SUCK_BE_S1(m->jcode + p + 1));
                        break;
 
                case JAVA_SIPUSH:
-                       LOADCONST_I(code_get_s2(p+1,m));
+                       OP_LOADCONST_I(SUCK_BE_S2(m->jcode + p + 1));
                        break;
 
                case JAVA_LDC1:
-                       i = code_get_u1(p + 1, m);
+                       i = SUCK_BE_U1(m->jcode + p + 1);
                        goto pushconstantitem;
 
                case JAVA_LDC2:
                case JAVA_LDC2W:
-                       i = code_get_u2(p + 1, m);
+                       i = SUCK_BE_U2(m->jcode + p + 1);
 
                pushconstantitem:
 
 #if defined(ENABLE_VERIFIER)
                        if (i >= m->class->cpcount) {
-                               *exceptionptr = new_verifyerror(m,
+                               exceptions_throw_verifyerror(m,
                                        "Attempt to access constant outside range");
                                return false;
                        }
@@ -306,35 +519,35 @@ fetch_opcode:
 
                        switch (m->class->cptags[i]) {
                        case CONSTANT_Integer:
-                               LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
                                break;
                        case CONSTANT_Long:
-                               LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
                                break;
                        case CONSTANT_Float:
-                               LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
                                break;
                        case CONSTANT_Double:
-                               LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
                                break;
                        case CONSTANT_String:
-                               LOADCONST_A(literalstring_new((utf *) (m->class->cpinfos[i])));
+                               OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
                                break;
                        case CONSTANT_Class:
                                cr = (constant_classref *) (m->class->cpinfos[i]);
 
-                               if (!resolve_classref(m, cr, resolveLazy, true,
-                                                                         true, &c))
+                               if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
                                        return false;
 
                                /* if not resolved, c == NULL */
 
-                               LOADCONST_A_CLASS(c, cr);
+                               OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr);
+
                                break;
 
 #if defined(ENABLE_VERIFIER)
                        default:
-                               *exceptionptr = new_verifyerror(m,
+                               exceptions_throw_verifyerror(m,
                                                "Invalid constant type to push");
                                return false;
 #endif
@@ -342,7 +555,7 @@ fetch_opcode:
                        break;
 
                case JAVA_ACONST_NULL:
-                       LOADCONST_A(NULL);
+                       OP_LOADCONST_NULL();
                        break;
 
                case JAVA_ICONST_M1:
@@ -352,185 +565,243 @@ fetch_opcode:
                case JAVA_ICONST_3:
                case JAVA_ICONST_4:
                case JAVA_ICONST_5:
-                       LOADCONST_I(opcode - JAVA_ICONST_0);
+                       OP_LOADCONST_I(opcode - JAVA_ICONST_0);
                        break;
 
                case JAVA_LCONST_0:
                case JAVA_LCONST_1:
-                       LOADCONST_L(opcode - JAVA_LCONST_0);
+                       OP_LOADCONST_L(opcode - JAVA_LCONST_0);
                        break;
 
                case JAVA_FCONST_0:
                case JAVA_FCONST_1:
                case JAVA_FCONST_2:
-                       LOADCONST_F(opcode - JAVA_FCONST_0);
+                       OP_LOADCONST_F(opcode - JAVA_FCONST_0);
                        break;
 
                case JAVA_DCONST_0:
                case JAVA_DCONST_1:
-                       LOADCONST_D(opcode - JAVA_DCONST_0);
+                       OP_LOADCONST_D(opcode - JAVA_DCONST_0);
+                       break;
+
+               /* stack operations ***************************************************/
+
+               /* We need space for additional ICMDs so we can translate these       */
+               /* instructions to sequences of ICMD_COPY and ICMD_MOVE instructions. */
+
+               case JAVA_DUP_X1:
+                       INSTRUCTIONS_CHECK(4);
+                       OP(opcode);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       break;
+
+               case JAVA_DUP_X2:
+                       INSTRUCTIONS_CHECK(6);
+                       OP(opcode);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       break;
+
+               case JAVA_DUP2:
+                       INSTRUCTIONS_CHECK(2);
+                       OP(opcode);
+                       OP(ICMD_NOP);
+                       break;
+
+               case JAVA_DUP2_X1:
+                       INSTRUCTIONS_CHECK(7);
+                       OP(opcode);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       break;
+
+               case JAVA_DUP2_X2:
+                       INSTRUCTIONS_CHECK(9);
+                       OP(opcode);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       break;
+
+               case JAVA_SWAP:
+                       INSTRUCTIONS_CHECK(3);
+                       OP(opcode);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
                        break;
 
-                       /* loading variables onto the stack */
+               /* local variable access instructions *********************************/
 
                case JAVA_ILOAD:
                case JAVA_FLOAD:
                case JAVA_ALOAD:
-                       if (!iswide) {
-                               i = code_get_u1(p + 1,m);
-                       } 
+                       if (iswide == false) {
+                               i = SUCK_BE_U1(m->jcode + p + 1);
+                       }
                        else {
-                               i = code_get_u2(p + 1,m);
+                               i = SUCK_BE_U2(m->jcode + p + 1);
                                nextp = p + 3;
                                iswide = false;
                        }
-                       OP1LOAD_ONEWORD(opcode, i);
+                       OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
                        break;
 
                case JAVA_LLOAD:
                case JAVA_DLOAD:
-                       if (!iswide) {
-                               i = code_get_u1(p + 1,m);
-                       } 
+                       if (iswide == false) {
+                               i = SUCK_BE_U1(m->jcode + p + 1);
+                       }
                        else {
-                               i = code_get_u2(p + 1,m);
+                               i = SUCK_BE_U2(m->jcode + p + 1);
                                nextp = p + 3;
                                iswide = false;
                        }
-                       OP1LOAD_TWOWORD(opcode, i);
+                       OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
                        break;
 
                case JAVA_ILOAD_0:
                case JAVA_ILOAD_1:
                case JAVA_ILOAD_2:
                case JAVA_ILOAD_3:
-                       OP1LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0);
+                       OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
                        break;
 
                case JAVA_LLOAD_0:
                case JAVA_LLOAD_1:
                case JAVA_LLOAD_2:
                case JAVA_LLOAD_3:
-                       OP1LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0);
+                       OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
                        break;
 
                case JAVA_FLOAD_0:
                case JAVA_FLOAD_1:
                case JAVA_FLOAD_2:
                case JAVA_FLOAD_3:
-                       OP1LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0);
+                       OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
                        break;
 
                case JAVA_DLOAD_0:
                case JAVA_DLOAD_1:
                case JAVA_DLOAD_2:
                case JAVA_DLOAD_3:
-                       OP1LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0);
+                       OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
                        break;
 
                case JAVA_ALOAD_0:
                case JAVA_ALOAD_1:
                case JAVA_ALOAD_2:
                case JAVA_ALOAD_3:
-                       OP1LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0);
+                       OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
                        break;
 
-                       /* storing stack values into local variables */
-
                case JAVA_ISTORE:
                case JAVA_FSTORE:
                case JAVA_ASTORE:
-                       if (!iswide) {
-                               i = code_get_u1(p + 1,m);
-                       } 
+                       if (iswide == false) {
+                               i = SUCK_BE_U1(m->jcode + p + 1);
+                       }
                        else {
-                               i = code_get_u2(p + 1,m);
+                               i = SUCK_BE_U2(m->jcode + p + 1);
                                iswide = false;
                                nextp = p + 3;
                        }
-                       OP1STORE_ONEWORD(opcode, i);
+                       OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
                        break;
 
                case JAVA_LSTORE:
                case JAVA_DSTORE:
-                       if (!iswide) {
-                               i = code_get_u1(p + 1,m);
-                       } 
+                       if (iswide == false) {
+                               i = SUCK_BE_U1(m->jcode + p + 1);
+                       }
                        else {
-                               i = code_get_u2(p + 1,m);
+                               i = SUCK_BE_U2(m->jcode + p + 1);
                                iswide = false;
                                nextp = p + 3;
                        }
-                       OP1STORE_TWOWORD(opcode, i);
+                       OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
                        break;
 
                case JAVA_ISTORE_0:
                case JAVA_ISTORE_1:
                case JAVA_ISTORE_2:
                case JAVA_ISTORE_3:
-                       OP1STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0);
+                       OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
                        break;
 
                case JAVA_LSTORE_0:
                case JAVA_LSTORE_1:
                case JAVA_LSTORE_2:
                case JAVA_LSTORE_3:
-                       OP1STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0);
+                       OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
                        break;
 
                case JAVA_FSTORE_0:
                case JAVA_FSTORE_1:
                case JAVA_FSTORE_2:
                case JAVA_FSTORE_3:
-                       OP1STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0);
+                       OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
                        break;
 
                case JAVA_DSTORE_0:
                case JAVA_DSTORE_1:
                case JAVA_DSTORE_2:
                case JAVA_DSTORE_3:
-                       OP1STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0);
+                       OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
                        break;
 
                case JAVA_ASTORE_0:
                case JAVA_ASTORE_1:
                case JAVA_ASTORE_2:
                case JAVA_ASTORE_3:
-                       OP1STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0);
+                       OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0, TYPE_ADR);
                        break;
 
                case JAVA_IINC:
                        {
                                int v;
-                               
-                               if (!iswide) {
-                                       i = code_get_u1(p + 1,m);
-                                       v = code_get_s1(p + 2,m);
 
-                               } 
+                               if (iswide == false) {
+                                       i = SUCK_BE_U1(m->jcode + p + 1);
+                                       v = SUCK_BE_S1(m->jcode + p + 2);
+
+                               }
                                else {
-                                       i = code_get_u2(p + 1,m);
-                                       v = code_get_s2(p + 3,m);
+                                       i = SUCK_BE_U2(m->jcode + p + 1);
+                                       v = SUCK_BE_S2(m->jcode + p + 3);
                                        iswide = false;
                                        nextp = p + 5;
                                }
                                INDEX_ONEWORD(i);
-                               OP2I(opcode, i, v);
+                               LOCALTYPE_USED(i, TYPE_INT);
+                               OP_LOCALINDEX_I(opcode, i, v);
                        }
                        break;
 
-                       /* wider index for loading, storing and incrementing */
+               /* wider index for loading, storing and incrementing ******************/
 
                case JAVA_WIDE:
                        iswide = true;
-                       gp++;
                        p++;
                        goto fetch_opcode;
 
                /* managing arrays ****************************************************/
 
                case JAVA_NEWARRAY:
-                       switch (code_get_s1(p + 1, m)) {
+                       switch (SUCK_BE_S1(m->jcode + p + 1)) {
                        case 4:
                                bte = builtintable_get_internal(BUILTIN_newarray_boolean);
                                break;
@@ -557,16 +828,15 @@ fetch_opcode:
                                break;
 #if defined(ENABLE_VERIFIER)
                        default:
-                               *exceptionptr = new_verifyerror(m,
-                                               "Invalid array-type to create");
+                               exceptions_throw_verifyerror(m, "Invalid array-type to create");
                                return false;
 #endif
                        }
-                       BUILTIN(bte, true, NULL, currentline);
+                       OP_BUILTIN_CHECK_EXCEPTION(bte);
                        break;
 
                case JAVA_ANEWARRAY:
-                       i = code_get_u2(p + 1, m);
+                       i = SUCK_BE_U2(m->jcode + p + 1);
                        compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
                        if (!compr)
                                return false;
@@ -577,30 +847,33 @@ fetch_opcode:
                        if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
                                return false;
 
-                       LOADCONST_A_BUILTIN(c, cr);
+                       INSTRUCTIONS_CHECK(2);
+                       OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
                        bte = builtintable_get_internal(BUILTIN_newarray);
-                       BUILTIN(bte, true, NULL, currentline);
+                       OP_BUILTIN_CHECK_EXCEPTION(bte);
                        s_count++;
                        break;
 
                case JAVA_MULTIANEWARRAY:
-                       m->isleafmethod = false;
-                       i = code_get_u2(p + 1, m);
-                       {
-                               s4 v = code_get_u1(p + 3, m);
-
-                               cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
-                               if (!cr)
-                                       return false;
-
-                               if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
-                                       return false;
-
-                               /* if unresolved, c == NULL */
-                               OP2AT(opcode, v, c, cr, currentline);
-                       }
+                       jd->isleafmethod = false;
+                       i = SUCK_BE_U2(m->jcode + p + 1);
+                       j = SUCK_BE_U1(m->jcode + p + 3);
+  
+                       cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
+                       if (cr == NULL)
+                               return false;
+  
+                       if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
+                               return false;
+  
+                       /* if unresolved, c == NULL */
+  
+                       iptr->s1.argcount = j;
+                       OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags */);
                        break;
 
+               /* control flow instructions ******************************************/
+
                case JAVA_IFEQ:
                case JAVA_IFLT:
                case JAVA_IFLE:
@@ -618,35 +891,48 @@ fetch_opcode:
                case JAVA_IF_ACMPEQ:
                case JAVA_IF_ACMPNE:
                case JAVA_GOTO:
-               case JAVA_JSR:
-                       i = p + code_get_s2(p + 1,m);
+                       i = p + SUCK_BE_S2(m->jcode + p + 1);
                        CHECK_BYTECODE_INDEX(i);
-                       block_insert(i);
+                       MARK_BASICBLOCK(i);
                        blockend = true;
-                       OP1(opcode, i);
+                       OP_INSINDEX(opcode, i);
                        break;
 
                case JAVA_GOTO_W:
-               case JAVA_JSR_W:
-                       i = p + code_get_s4(p + 1,m);
+                       i = p + SUCK_BE_S4(m->jcode + p + 1);
                        CHECK_BYTECODE_INDEX(i);
-                       block_insert(i);
+                       MARK_BASICBLOCK(i);
                        blockend = true;
-                       OP1(opcode, i);
+                       OP_INSINDEX(opcode, i);
                        break;
 
+               case JAVA_JSR:
+                       i = p + SUCK_BE_S2(m->jcode + p + 1);
+jsr_tail:
+                       CHECK_BYTECODE_INDEX(i);
+                       MARK_BASICBLOCK(i);
+                       blockend = true;
+                       OP_PREPARE_ZEROFLAGS(JAVA_JSR);
+                       iptr->sx.s23.s3.jsrtarget.insindex = i;
+                       PINC;
+                       break;
+
+               case JAVA_JSR_W:
+                       i = p + SUCK_BE_S4(m->jcode + p + 1);
+                       goto jsr_tail;
+
                case JAVA_RET:
-                       if (!iswide) {
-                               i = code_get_u1(p + 1,m);
-                       } 
+                       if (iswide == false) {
+                               i = SUCK_BE_U1(m->jcode + p + 1);
+                       }
                        else {
-                               i = code_get_u2(p + 1,m);
+                               i = SUCK_BE_U2(m->jcode + p + 1);
                                nextp = p + 3;
                                iswide = false;
                        }
                        blockend = true;
-                               
-                       OP1LOAD_ONEWORD(opcode, i);
+
+                       OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
                        break;
 
                case JAVA_IRETURN:
@@ -656,86 +942,84 @@ fetch_opcode:
                case JAVA_ARETURN:
                case JAVA_RETURN:
                        blockend = true;
-                       /* zero val.a so no patcher is inserted */
-                       /* the type checker may set this later  */
-                       iptr->val.a = NULL;
+                       /* XXX ARETURN will need a flag in the typechecker */
                        OP(opcode);
                        break;
 
                case JAVA_ATHROW:
                        blockend = true;
-                       /* zero val.a so no patcher is inserted */
-                       /* the type checker may set this later  */
-                       iptr->val.a = NULL;
+                       /* XXX ATHROW will need a flag in the typechecker */
                        OP(opcode);
                        break;
-                               
+
 
                /* table jumps ********************************************************/
 
                case JAVA_LOOKUPSWITCH:
                        {
                                s4 num, j;
-                               s4 *tablep;
+                               lookup_target_t *lookup;
 #if defined(ENABLE_VERIFIER)
                                s4 prevvalue = 0;
 #endif
-
                                blockend = true;
                                nextp = ALIGN((p + 1), 4);
 
                                CHECK_END_OF_BYTECODE(nextp + 8);
 
-                               tablep = (s4 *) (m->jcode + nextp);
-
-                               OP2A(opcode, 0, tablep, currentline);
+                               OP_PREPARE_ZEROFLAGS(opcode);
 
                                /* default target */
 
-                               j =  p + code_get_s4(nextp, m);
-                               *tablep = j;     /* restore for little endian */
-                               tablep++;
+                               j = p + SUCK_BE_S4(m->jcode + nextp);
+                               iptr->sx.s23.s3.lookupdefault.insindex = j;
                                nextp += 4;
                                CHECK_BYTECODE_INDEX(j);
-                               block_insert(j);
+                               MARK_BASICBLOCK(j);
 
                                /* number of pairs */
 
-                               num = code_get_u4(nextp, m);
-                               *tablep = num;
-                               tablep++;
+                               num = SUCK_BE_U4(m->jcode + nextp);
+                               iptr->sx.s23.s2.lookupcount = num;
                                nextp += 4;
 
+                               /* allocate the intermediate code table */
+
+                               lookup = DMNEW(lookup_target_t, num);
+                               iptr->dst.lookup = lookup;
+
+                               /* iterate over the lookup table */
+
                                CHECK_END_OF_BYTECODE(nextp + 8 * num);
 
                                for (i = 0; i < num; i++) {
                                        /* value */
 
-                                       j = code_get_s4(nextp, m);
-                                       *tablep = j; /* restore for little endian */
-                                       tablep++;
+                                       j = SUCK_BE_S4(m->jcode + nextp);
+                                       lookup->value = j;
+
                                        nextp += 4;
 
 #if defined(ENABLE_VERIFIER)
                                        /* check if the lookup table is sorted correctly */
-                                       
+
                                        if (i && (j <= prevvalue)) {
-                                               *exceptionptr = new_verifyerror(m, "Unsorted lookup switch");
+                                               exceptions_throw_verifyerror(m, "Unsorted lookup switch");
                                                return false;
                                        }
                                        prevvalue = j;
 #endif
-
                                        /* target */
 
-                                       j = p + code_get_s4(nextp,m);
-                                       *tablep = j; /* restore for little endian */
-                                       tablep++;
+                                       j = p + SUCK_BE_S4(m->jcode + nextp);
+                                       lookup->target.insindex = j;
+                                       lookup++;
                                        nextp += 4;
                                        CHECK_BYTECODE_INDEX(j);
-                                       block_insert(j);
+                                       MARK_BASICBLOCK(j);
                                }
 
+                               PINC;
                                break;
                        }
 
@@ -743,61 +1027,66 @@ fetch_opcode:
                case JAVA_TABLESWITCH:
                        {
                                s4 num, j;
-                               s4 *tablep;
+                               s4 deftarget;
+                               branch_target_t *table;
 
                                blockend = true;
                                nextp = ALIGN((p + 1), 4);
 
                                CHECK_END_OF_BYTECODE(nextp + 12);
 
-                               tablep = (s4 *) (m->jcode + nextp);
-
-                               OP2A(opcode, 0, tablep, currentline);
+                               OP_PREPARE_ZEROFLAGS(opcode);
 
                                /* default target */
 
-                               j = p + code_get_s4(nextp, m);
-                               *tablep = j;     /* restore for little endian */
-                               tablep++;
+                               deftarget = p + SUCK_BE_S4(m->jcode + nextp);
                                nextp += 4;
-                               CHECK_BYTECODE_INDEX(j);
-                               block_insert(j);
+                               CHECK_BYTECODE_INDEX(deftarget);
+                               MARK_BASICBLOCK(deftarget);
 
                                /* lower bound */
 
-                               j = code_get_s4(nextp, m);
-                               *tablep = j;     /* restore for little endian */
-                               tablep++;
+                               j = SUCK_BE_S4(m->jcode + nextp);
+                               iptr->sx.s23.s2.tablelow = j;
                                nextp += 4;
 
                                /* upper bound */
 
-                               num = code_get_s4(nextp, m);
-                               *tablep = num;   /* restore for little endian */
-                               tablep++;
+                               num = SUCK_BE_S4(m->jcode + nextp);
+                               iptr->sx.s23.s3.tablehigh = num;
                                nextp += 4;
 
-                               num -= j;  /* difference of upper - lower */
+                               /* calculate the number of table entries */
+
+                               num = num - j + 1;
 
 #if defined(ENABLE_VERIFIER)
-                               if (num < 0) {
-                                       *exceptionptr = new_verifyerror(m,
+                               if (num < 1) {
+                                       exceptions_throw_verifyerror(m,
                                                        "invalid TABLESWITCH: upper bound < lower bound");
                                        return false;
                                }
 #endif
+                               /* create the intermediate code table */
+                               /* the first entry is the default target */
 
-                               CHECK_END_OF_BYTECODE(nextp + 4 * (num + 1));
+                               table = MNEW(branch_target_t, 1 + num);
+                               iptr->dst.table = table;
+                               (table++)->insindex = deftarget;
 
-                               for (i = 0; i <= num; i++) {
-                                       j = p + code_get_s4(nextp,m);
-                                       *tablep = j; /* restore for little endian */
-                                       tablep++;
+                               /* iterate over the target table */
+
+                               CHECK_END_OF_BYTECODE(nextp + 4 * num);
+
+                               for (i = 0; i < num; i++) {
+                                       j = p + SUCK_BE_S4(m->jcode + nextp);
+                                       (table++)->insindex = j;
                                        nextp += 4;
                                        CHECK_BYTECODE_INDEX(j);
-                                       block_insert(j);
+                                       MARK_BASICBLOCK(j);
                                }
 
+                               PINC;
                                break;
                        }
 
@@ -806,7 +1095,7 @@ fetch_opcode:
 
                case JAVA_AASTORE:
                        OP(opcode);
-                       m->isleafmethod = false;
+                       jd->isleafmethod = false;
                        break;
 
                case JAVA_GETSTATIC:
@@ -817,166 +1106,172 @@ fetch_opcode:
                                constant_FMIref  *fr;
                                unresolved_field *uf;
 
-                               i = code_get_u2(p + 1, m);
-                               fr = class_getconstant(m->class, i,
-                                                                          CONSTANT_Fieldref);
+                               i = SUCK_BE_U2(m->jcode + p + 1);
+                               fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
                                if (!fr)
                                        return false;
 
-                               OP2A_NOINC(opcode, fr->parseddesc.fd->type, fr, currentline);
+                               OP_PREPARE_ZEROFLAGS(opcode);
+                               iptr->sx.s23.s3.fmiref = fr;
 
                                /* only with -noverify, otherwise the typechecker does this */
 
-                               if (!opt_verify) {
-                                       result = resolve_field_lazy(iptr,NULL,m);
+#if defined(ENABLE_VERIFIER)
+                               if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
+#endif
+                                       result = resolve_field_lazy(m, fr);
                                        if (result == resolveFailed)
                                                return false;
 
                                        if (result != resolveSucceeded) {
-                                               uf = create_unresolved_field(m->class,
-                                                                                                        m, iptr);
+                                               uf = resolve_create_unresolved_field(m->class, m, iptr);
 
-                                               if (!uf)
+                                               if (uf == NULL)
                                                        return false;
 
                                                /* store the unresolved_field pointer */
 
-                                               /* XXX this will be changed */
-                                               iptr->val.a = uf;
-                                               iptr->target = (void*)1; /* XXX target temporarily used as flag */
-                                       }
-                                       else {
-                                               iptr->target = NULL;
+                                               iptr->sx.s23.s3.uf = uf;
+                                               iptr->flags.bits = INS_FLAG_UNRESOLVED;
                                        }
+#if defined(ENABLE_VERIFIER)
                                }
-                               else {
-                                       iptr->target = NULL;
-                               }
+#endif
                                PINC;
                        }
                        break;
-                               
+
 
                /* method invocation **************************************************/
 
                case JAVA_INVOKESTATIC:
-                       i = code_get_u2(p + 1, m);
-                       mr = class_getconstant(m->class, i,
-                                       CONSTANT_Methodref);
-                       if (!mr)
+                       i = SUCK_BE_U2(m->jcode + p + 1);
+                       mr = class_getconstant(m->class, i, CONSTANT_Methodref);
+
+                       if (mr == NULL)
                                return false;
 
                        md = mr->parseddesc.md;
 
-                       if (!md->params)
+                       if (md->params == NULL)
                                if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
                                        return false;
 
                        goto invoke_method;
 
                case JAVA_INVOKEINTERFACE:
-                       i = code_get_u2(p + 1, m);
-                               
-                       mr = class_getconstant(m->class, i,
-                                       CONSTANT_InterfaceMethodref);
+                       i = SUCK_BE_U2(m->jcode + p + 1);
+
+                       mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
 
                        goto invoke_nonstatic_method;
 
                case JAVA_INVOKESPECIAL:
                case JAVA_INVOKEVIRTUAL:
-                       i = code_get_u2(p + 1, m);
-                       mr = class_getconstant(m->class, i,
-                                       CONSTANT_Methodref);
+                       i = SUCK_BE_U2(m->jcode + p + 1);
+                       mr = class_getconstant(m->class, i, CONSTANT_Methodref);
 
 invoke_nonstatic_method:
-                       if (!mr)
+                       if (mr == NULL)
                                return false;
 
                        md = mr->parseddesc.md;
 
-                       if (!md->params)
+                       if (md->params == NULL)
                                if (!descriptor_params_from_paramtypes(md, 0))
                                        return false;
 
 invoke_method:
-                       m->isleafmethod = false;
+                       jd->isleafmethod = false;
 
-                       OP2A_NOINC(opcode, 0, mr, currentline);
+                       OP_PREPARE_ZEROFLAGS(opcode);
+                       iptr->sx.s23.s3.fmiref = mr;
 
                        /* only with -noverify, otherwise the typechecker does this */
 
-                       if (!opt_verify) {
-                               result = resolve_method_lazy(iptr,NULL,m);
+#if defined(ENABLE_VERIFIER)
+                       if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
+#endif
+                               result = resolve_method_lazy(m, mr, 
+                                               (opcode == JAVA_INVOKESPECIAL));
                                if (result == resolveFailed)
                                        return false;
 
-                               if (result != resolveSucceeded) {
-                                       um = create_unresolved_method(m->class,
-                                                       m, iptr);
+                               if (result == resolveSucceeded) {
+                                       methodinfo *mi = iptr->sx.s23.s3.fmiref->p.method;
+
+                                       /* if this call is monomorphic, turn it into an INVOKESPECIAL */
+
+                                       assert(IS_FMIREF_RESOLVED(iptr->sx.s23.s3.fmiref));
+
+                                       if ((iptr->opc == ICMD_INVOKEVIRTUAL)
+                                               && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
+                                       {
+                                               iptr->opc = ICMD_INVOKESPECIAL;
+                                       }
+                               }
+                               else {
+                                       um = resolve_create_unresolved_method(m->class, m, mr,
+                                                       (opcode == JAVA_INVOKESTATIC),
+                                                       (opcode == JAVA_INVOKESPECIAL));
 
                                        if (!um)
                                                return false;
 
                                        /* store the unresolved_method pointer */
 
-                                       /* XXX this will be changed */
-                                       iptr->val.a = um;
-                                       iptr->target = (void*)1; /* XXX target temporarily used as flag */
+                                       iptr->sx.s23.s3.um = um;
+                                       iptr->flags.bits = INS_FLAG_UNRESOLVED;
                                }
-                               else {
-                                       iptr->target = NULL;
-                               }
-                       }
-                       else {
-                               iptr->target = NULL;
+#if defined(ENABLE_VERIFIER)
                        }
+#endif
                        PINC;
                        break;
 
-               /* miscellaneous object operations ************************************/
+               /* instructions taking class arguments ********************************/
 
                case JAVA_NEW:
-                       i = code_get_u2(p + 1, m);
+                       i = SUCK_BE_U2(m->jcode + p + 1);
                        cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
                        if (!cr)
                                return false;
 
-                       if (!resolve_classref(m, cr, resolveLazy, true, true,
-                                                                 &c))
+                       if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
                                return false;
 
-                       LOADCONST_A_BUILTIN(c, cr);
+                       INSTRUCTIONS_CHECK(2);
+                       OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
                        bte = builtintable_get_internal(BUILTIN_new);
-                       BUILTIN(bte, true, NULL, currentline);
+                       OP_BUILTIN_CHECK_EXCEPTION(bte);
                        s_count++;
                        break;
 
                case JAVA_CHECKCAST:
-                       i = code_get_u2(p + 1, m);
+                       i = SUCK_BE_U2(m->jcode + p + 1);
                        cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
-                       if (!cr)
+                       if (cr == NULL)
                                return false;
 
-                       if (!resolve_classref(m, cr, resolveLazy, true,
-                                                                 true, &c))
+                       if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
                                return false;
 
                        if (cr->name->text[0] == '[') {
                                /* array type cast-check */
-                               OP2AT(opcode, 0, c, cr, currentline);
-                               m->isleafmethod = false;
-
-                       } 
+                               flags = INS_FLAG_ARRAY;
+                               jd->isleafmethod = false;
+                       }
                        else {
                                /* object type cast-check */
-                               OP2AT(opcode, 1, c, cr, currentline);
+                               flags = 0;
                        }
+                       OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
                        break;
 
                case JAVA_INSTANCEOF:
-                       i = code_get_u2(p + 1,m);
+                       i = SUCK_BE_U2(m->jcode + p + 1);
                        cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
-                       if (!cr)
+                       if (cr == NULL)
                                return false;
 
                        if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
@@ -984,53 +1279,52 @@ invoke_method:
 
                        if (cr->name->text[0] == '[') {
                                /* array type cast-check */
-                               LOADCONST_A_BUILTIN(c, cr);
+                               INSTRUCTIONS_CHECK(2);
+                               OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
                                bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
-                               BUILTIN(bte, false, NULL, currentline);
+                               OP_BUILTIN_NO_EXCEPTION(bte);
                                s_count++;
-
-                       } 
+                       }
                        else {
                                /* object type cast-check */
-                               OP2AT(opcode, 1, c, cr, currentline);
+                               OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
                        }
                        break;
 
+               /* synchronization instructions ***************************************/
+
                case JAVA_MONITORENTER:
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
                        if (checksync) {
-                               OP(ICMD_CHECKNULL);
-                               bte = builtintable_get_internal(BUILTIN_monitorenter);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } 
+                               bte = builtintable_get_internal(LOCK_monitor_enter);
+                               OP_BUILTIN_CHECK_EXCEPTION(bte);
+                       }
                        else
 #endif
-                               {
-                                       OP(ICMD_CHECKNULL);
-                                       OP(ICMD_POP);
-                               }
+                       {
+                               OP(ICMD_CHECKNULL_POP);
+                       }
                        break;
 
                case JAVA_MONITOREXIT:
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
                        if (checksync) {
-                               bte = builtintable_get_internal(BUILTIN_monitorexit);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } 
+                               bte = builtintable_get_internal(LOCK_monitor_exit);
+                               OP_BUILTIN_CHECK_EXCEPTION(bte);
+                       }
                        else
 #endif
-                               {
-                                       OP(ICMD_POP);
-                               }
+                       {
+                               OP(ICMD_CHECKNULL_POP);
+                       }
                        break;
 
-               /* any other basic operation ******************************************/
+               /* arithmetic instructions that may become builtin functions **********/
 
                case JAVA_IDIV:
 #if !SUPPORT_DIVISION
                        bte = builtintable_get_internal(BUILTIN_idiv);
-                       OP2A(opcode, bte->md->paramcount, bte, currentline);
-                       m->isleafmethod = false;
+                       OP_BUILTIN_ARITHMETIC(opcode, bte);
 #else
                        OP(opcode);
 #endif
@@ -1039,8 +1333,7 @@ invoke_method:
                case JAVA_IREM:
 #if !SUPPORT_DIVISION
                        bte = builtintable_get_internal(BUILTIN_irem);
-                       OP2A(opcode, bte->md->paramcount, bte, currentline);
-                       m->isleafmethod = false;
+                       OP_BUILTIN_ARITHMETIC(opcode, bte);
 #else
                        OP(opcode);
 #endif
@@ -1049,8 +1342,7 @@ invoke_method:
                case JAVA_LDIV:
 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
                        bte = builtintable_get_internal(BUILTIN_ldiv);
-                       OP2A(opcode, bte->md->paramcount, bte, currentline);
-                       m->isleafmethod = false;
+                       OP_BUILTIN_ARITHMETIC(opcode, bte);
 #else
                        OP(opcode);
 #endif
@@ -1059,8 +1351,7 @@ invoke_method:
                case JAVA_LREM:
 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
                        bte = builtintable_get_internal(BUILTIN_lrem);
-                       OP2A(opcode, bte->md->paramcount, bte, currentline);
-                       m->isleafmethod = false;
+                       OP_BUILTIN_ARITHMETIC(opcode, bte);
 #else
                        OP(opcode);
 #endif
@@ -1071,7 +1362,7 @@ invoke_method:
                        OP(opcode);
 #else
                        bte = builtintable_get_internal(BUILTIN_frem);
-                       BUILTIN(bte, false, NULL, currentline);
+                       OP_BUILTIN_NO_EXCEPTION(bte);
 #endif
                        break;
 
@@ -1080,7 +1371,7 @@ invoke_method:
                        OP(opcode);
 #else
                        bte = builtintable_get_internal(BUILTIN_drem);
-                       BUILTIN(bte, false, NULL, currentline);
+                       OP_BUILTIN_NO_EXCEPTION(bte);
 #endif
                        break;
 
@@ -1088,59 +1379,60 @@ invoke_method:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_f2i);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } 
+                               OP_BUILTIN_NO_EXCEPTION(bte);
+                       }
                        else
 #endif
-                               {
-                                       OP(opcode);
-                               }
+                       {
+                               OP(opcode);
+                       }
                        break;
 
                case JAVA_F2L:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_f2l);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } 
-                       else 
+                               OP_BUILTIN_NO_EXCEPTION(bte);
+                       }
+                       else
 #endif
-                               {
-                                       OP(opcode);
-                               }
+                       {
+                               OP(opcode);
+                       }
                        break;
 
                case JAVA_D2I:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_d2i);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } 
+                               OP_BUILTIN_NO_EXCEPTION(bte);
+                       }
                        else
 #endif
-                               {
-                                       OP(opcode);
-                               }
+                       {
+                               OP(opcode);
+                       }
                        break;
 
                case JAVA_D2L:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_d2l);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } 
+                               OP_BUILTIN_NO_EXCEPTION(bte);
+                       }
                        else
 #endif
-                               {
-                                       OP(opcode);
-                               }
+                       {
+                               OP(opcode);
+                       }
                        break;
 
+               /* invalid opcodes ****************************************************/
+
                        /* check for invalid opcodes if the verifier is enabled */
 #if defined(ENABLE_VERIFIER)
                case JAVA_BREAKPOINT:
-                       *exceptionptr =
-                               new_verifyerror(m, "Quick instructions shouldn't appear yet.");
+                       exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
                        return false;
 
                case 186: /* unused opcode */
@@ -1197,24 +1489,27 @@ invoke_method:
                case 253:
                case 254:
                case 255:
-                       *exceptionptr =
-                               new_verifyerror(m,"Illegal opcode %d at instr %d\n",
-                                                                 opcode, ipc);
+                       exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
+                                                                                opcode, ipc);
                        return false;
                        break;
 #endif /* defined(ENABLE_VERIFIER) */
 
+               /* opcodes that don't require translation *****************************/
+
                default:
                        /* straight-forward translation to ICMD */
                        OP(opcode);
                        break;
-                               
+
                } /* end switch */
 
+               /* verifier checks ****************************************************/
+
 #if defined(ENABLE_VERIFIER)
                /* If WIDE was used correctly, iswide should have been reset by now. */
                if (iswide) {
-                       *exceptionptr = new_verifyerror(m,
+                       exceptions_throw_verifyerror(m,
                                        "Illegal instruction: WIDE before incompatible opcode");
                        return false;
                }
@@ -1222,156 +1517,209 @@ invoke_method:
 
        } /* end for */
 
+       if (JITDATA_HAS_FLAG_REORDER(jd)) {
+               /* add a NOP to the last basic block */
+
+               INSTRUCTIONS_CHECK(1);
+               OP(ICMD_NOP);
+       }
+
+       /*** END OF LOOP **********************************************************/
+
+       /* assert that we did not write more ICMDs than allocated */
+
+       assert(ipc <= pd.instructionslength);
+       assert(ipc == (iptr - pd.instructions));
+
+       /*** verifier checks ******************************************************/
+
 #if defined(ENABLE_VERIFIER)
        if (p != m->jcodelength) {
-               *exceptionptr = new_verifyerror(m,
+               exceptions_throw_verifyerror(m,
                                "Command-sequence crosses code-boundary");
                return false;
        }
 
        if (!blockend) {
-               *exceptionptr = new_verifyerror(m, "Falling off the end of the code");
+               exceptions_throw_verifyerror(m, "Falling off the end of the code");
                return false;
        }
 #endif /* defined(ENABLE_VERIFIER) */
 
+       /*** setup the methodinfo, allocate stack and basic blocks ****************/
+
        /* adjust block count if target 0 is not first intermediate instruction */
 
-       if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1))
+       if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1))
                b_count++;
 
        /* copy local to method variables */
 
-       m->instructioncount = ipc;
-       m->basicblockcount = b_count;
-       m->stackcount = s_count + m->basicblockcount * m->maxstack;
+       jd->instructions = pd.instructions;
+       jd->instructioncount = ipc;
+       jd->basicblockcount = b_count;
+       jd->stackcount = s_count + jd->basicblockcount * m->maxstack; /* in-stacks */
 
        /* allocate stack table */
 
-       m->stack = DMNEW(stackelement, m->stackcount);
+       jd->stack = DMNEW(stackelement, jd->stackcount);
 
-       {
-               basicblock *bptr;
+       /* build basic block list */
 
-               bptr = m->basicblocks = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
+       bptr = jd->basicblocks = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
 
-               b_count = 0;
-               m->c_debug_nr = 0;
-       
-               /* additional block if target 0 is not first intermediate instruction */
+       /* zero out all basic block structures */
 
-               if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1)) {
-                       BASICBLOCK_INIT(bptr,m);
+       MZERO(bptr, basicblock, b_count + 1);
 
-                       bptr->iinstr = m->instructions;
-                       /* bptr->icount is set when the next block is allocated */
+       b_count = 0;
 
-                       bptr++;
-                       b_count++;
-                       bptr[-1].next = bptr;
-               }
+       /* additional block if target 0 is not first intermediate instruction */
+
+       if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1)) {
+               BASICBLOCK_INIT(bptr, m);
 
-               /* allocate blocks */
+               bptr->iinstr = jd->instructions;
+               /* bptr->icount is set when the next block is allocated */
 
-               for (p = 0; p < m->jcodelength; p++) { 
-                       if (m->basicblockindex[p] & 1) {
-                               /* Check if this block starts at the beginning of an          */
-                               /* instruction.                                               */
+               bptr->nr = b_count++;
+               bptr++;
+               bptr[-1].next = bptr;
+       }
+
+       /* allocate blocks */
+
+       for (p = 0; p < m->jcodelength; p++) {
+               if (jd->basicblockindex[p] & 1) {
 #if defined(ENABLE_VERIFIER)
-                               if (!instructionstart[p]) {
-                                       *exceptionptr = new_verifyerror(m,
+                       /* Check if this block starts at the beginning of an
+                          instruction. */
+
+                       if (!pd.instructionstart[p]) {
+                               exceptions_throw_verifyerror(m,
                                                "Branch into middle of instruction");
-                                       return false;
-                               }
+                               return false;
+                       }
 #endif
 
-                               /* allocate the block */
+                       /* allocate the block */
 
-                               BASICBLOCK_INIT(bptr,m);
+                       BASICBLOCK_INIT(bptr, m);
 
-                               bptr->iinstr = m->instructions + (m->basicblockindex[p] >> 1);
-                               if (b_count) {
-                                       bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
-                               }
-                               /* bptr->icount is set when the next block is allocated */
+                       bptr->iinstr = jd->instructions + (jd->basicblockindex[p] >> 1);
+                       if (b_count) {
+                               bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
+                       }
+                       /* bptr->icount is set when the next block is allocated */
 
-                               m->basicblockindex[p] = b_count;
+                       jd->basicblockindex[p] = b_count;
 
-                               bptr++;
-                               b_count++;
-                               bptr[-1].next = bptr;
-                       }
+                       bptr->nr = b_count++;
+                       bptr++;
+                       bptr[-1].next = bptr;
                }
+       }
 
-               /* set instruction count of last real block */
+       /* set instruction count of last real block */
 
-               if (b_count) {
-                       bptr[-1].icount = (m->instructions + m->instructioncount) - bptr[-1].iinstr;
-               }
+       if (b_count) {
+               bptr[-1].icount = (jd->instructions + jd->instructioncount) - bptr[-1].iinstr;
+       }
 
-               /* allocate additional block at end */
+       /* allocate additional block at end */
 
-               BASICBLOCK_INIT(bptr,m);
-               
-               bptr->instack = bptr->outstack = NULL;
-               bptr->indepth = bptr->outdepth = 0;
-               bptr->iinstr = NULL;
-               bptr->icount = 0;
-               bptr->next = NULL;
+       BASICBLOCK_INIT(bptr,m);
+       bptr->nr = b_count;
+       jd->basicblockindex[m->jcodelength] = b_count;
+
+       /* set basicblock pointers in exception table */
+
+       if (!parse_resolve_exception_table(jd))
+               return false;
+
+       /* store the local map */
+
+       jd->local_map = local_map;
+
+       /* calculate local variable renaming */
+
+       {
+               s4 nlocals = 0;
+               s4 i;
+
+               s4 *mapptr;
 
-               /* set basicblock pointers in exception table */
+               mapptr = local_map;
 
-               if (cd->exceptiontablelength > 0) {
-                       cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
+               /* iterate over local_map[0..m->maxlocals*5] and set all existing  */
+               /* index,type pairs (local_map[index*5+type]==1) to an unique value */
+               /* -> == new local var index */
+               for(i = 0; i < (m->maxlocals * 5); i++, mapptr++) {
+                       if (*mapptr)
+                               *mapptr = nlocals++;
+                       else
+                               *mapptr = UNUSED;
                }
-               
-               for (i = 0; i < cd->exceptiontablelength; ++i) {
-                       p = cd->exceptiontable[i].startpc;
-                       cd->exceptiontable[i].start = m->basicblocks + m->basicblockindex[p];
 
-                       p = cd->exceptiontable[i].endpc;
-                       cd->exceptiontable[i].end = (p == m->jcodelength) ? (m->basicblocks + m->basicblockcount /*+ 1*/) : (m->basicblocks + m->basicblockindex[p]);
+               jd->localcount = nlocals;
+
+               /* calculate the (maximum) number of variables needed */
 
-                       p = cd->exceptiontable[i].handlerpc;
-                       cd->exceptiontable[i].handler = m->basicblocks + m->basicblockindex[p];
-           }
+               jd->varcount = 
+                         nlocals                                      /* local variables */
+                       + jd->basicblockcount * m->maxstack                 /* invars */
+                       + s_count;         /* variables created within blocks (non-invar) */
 
-               /* XXX activate this if you want to try inlining */
-#if 0
-               for (i = 0; i < m->exceptiontablelength; ++i) {
-                       p = m->exceptiontable[i].startpc;
-                       m->exceptiontable[i].start = m->basicblocks + m->basicblockindex[p];
+               /* reserve the first indices for local variables */
 
-                       p = m->exceptiontable[i].endpc;
-                       m->exceptiontable[i].end = (p == m->jcodelength) ? (m->basicblocks + m->basicblockcount /*+ 1*/) : (m->basicblocks + m->basicblockindex[p]);
+               jd->vartop = nlocals;
 
-                       p = m->exceptiontable[i].handlerpc;
-                       m->exceptiontable[i].handler = m->basicblocks + m->basicblockindex[p];
-           }
+               /* reserve extra variables needed by stack analyse */
+
+               jd->varcount += STACK_EXTRA_VARS;
+               jd->vartop   += STACK_EXTRA_VARS;
+
+               /* The verifier needs space for saving invars in some cases and */
+               /* extra variables.                                             */
+
+#if defined(ENABLE_VERIFIER)
+               if (JITDATA_HAS_FLAG_VERIFY(jd)) {
+                       jd->varcount += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
+                       jd->vartop   += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
+               }
 #endif
+               /* allocate and initialize the variable array */
 
+               jd->var = DMNEW(varinfo, jd->varcount);
+               MZERO(jd->var, varinfo, jd->varcount);
+
+               /* set types of all locals in jd->var */
+
+               for(mapptr = local_map, i = 0; i < (m->maxlocals * 5); i++, mapptr++)
+                       if (*mapptr != UNUSED)
+                               VAR(*mapptr)->type = i%5;
        }
 
        /* everything's ok */
 
        return true;
 
+       /*** goto labels for throwing verifier exceptions *************************/
+
 #if defined(ENABLE_VERIFIER)
 
 throw_unexpected_end_of_bytecode:
-       *exceptionptr = new_verifyerror(m, "Unexpected end of bytecode");
+       exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
        return false;
 
 throw_invalid_bytecode_index:
-       *exceptionptr =
-               new_verifyerror(m, "Illegal target of branch instruction");
+       exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
        return false;
 
 throw_illegal_local_variable_number:
-       *exceptionptr =
-               new_verifyerror(m, "Illegal local variable number");
+       exceptions_throw_verifyerror(m, "Illegal local variable number");
        return false;
-               
+
 #endif /* ENABLE_VERIFIER */
 }