* Removed all Id tags.
[cacao.git] / src / vm / jit / parse.c
index fc7b4116edae01f4793c37780a3f19ef030702e3..068dc65afed4e81e1d102e31ffbf3505206554c9 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/parse.c - parser for JavaVM to intermediate code translation
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Author: Andreas Krall
-
-   Changes: Carolyn Oates
-            Edwin Steiner
-            Joseph Wenninger
-            Christian Thalinger
-
-   $Id: parse.c 5002 2006-05-31 22:56:17Z edwin $
-
 */
 
 
 #include "vm/types.h"
 
 #include "mm/memory.h"
+
 #include "native/native.h"
+
+#include "threads/lock-common.h"
+
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/linker.h"
-#include "vm/loader.h"
-#include "vm/resolve.h"
-#include "vm/options.h"
-#include "vm/statistics.h"
 #include "vm/stringlocal.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"
 
-/*******************************************************************************
+#include "vmcore/linker.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vm/resolve.h"
 
-       function 'parse' scans the JavaVM code and generates intermediate code
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
 
-       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.
+#include "vmcore/suck.h"
+
+#define INSTRUCTIONS_INCREMENT  5  /* number of additional instructions to    */
+                                   /* allocate if space runs out              */
+
+
+/* local macros ***************************************************************/
+
+#define BYTECODEINDEX_TO_BASICBLOCK(dst) \
+    do { \
+        (dst).block = \
+            parse_bytecodeindex_to_basicblock(jd, &pd, (dst).insindex); \
+    } while (0)
+
+
+/* parserdata_t ***************************************************************/
+
+typedef struct parsedata_t parsedata_t;
+
+struct parsedata_t {
+       u1          *bytecodestart;         /* start of bytecode instructions     */
+       u1          *basicblockstart;       /* start of bytecode basic-blocks     */
+
+       s4          *bytecodemap;           /* bytecode to IR mapping             */
+       
+       instruction *instructions;          /* instruction array                  */
+       s4           instructionslength;    /* length of the instruction array    */
+
+       s4          *instructionmap;        /* IR to basic-block mapping          */
+};
+
+
+/* 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;
+
+       /* bytecode start array */
+
+       pd->bytecodestart = DMNEW(u1, m->jcodelength + 1);
+       MZERO(pd->bytecodestart, u1, m->jcodelength + 1);
+
+       /* bytecode basic-block start array */
+
+       pd->basicblockstart = DMNEW(u1, m->jcodelength + 1);
+       MZERO(pd->basicblockstart, u1, m->jcodelength + 1);
+
+       /* bytecode instruction index to IR instruction mapping */
+
+       pd->bytecodemap = DMNEW(s4, m->jcodelength + 1);
+       MSET(pd->bytecodemap, -1, s4, m->jcodelength + 1);
+
+       /* allocate the instruction array */
+
+       pd->instructionslength = m->jcodelength + 1;
+       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);
+
+       /* The instructionmap is allocated later when we know the count of
+          instructions. */
+
+       pd->instructionmap = NULL;
+}
+
+
+/* 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 icount, s4 n)
+{
+       /* increase the size of the instruction array */
+
+       pd->instructionslength += (n + INSTRUCTIONS_INCREMENT);
+
+       /* reallocate the array */
+
+       pd->instructions = DMREALLOC(pd->instructions, instruction, icount,
+                                                                pd->instructionslength);
+       MZERO(pd->instructions + icount, instruction,
+                 (pd->instructionslength - icount));
+
+       /* return the iptr */
+
+       return pd->instructions + icount;
+}
+
+
+/* parse_bytecodeindex_to_basicblock *******************************************
+
+   Resolves a bytecode index to the corresponding basic block.
+
+*******************************************************************************/
+
+static basicblock *parse_bytecodeindex_to_basicblock(jitdata *jd,
+                                                                                                        parsedata_t *pd,
+                                                                                                        s4 bcindex)
+{
+       s4          irindex;
+       basicblock *bb;
+
+       irindex = pd->bytecodemap[bcindex];
+       bb      = jd->basicblocks + pd->instructionmap[irindex];
+
+       return bb;
+}
+
+
+/* parse_mark_exception_boundaries *********************************************
+
+   Mark exception handlers and the boundaries of the handled regions as
+   basic block boundaries.
+
+   IN:
+       jd...............current jitdata
+
+   RETURN VALUE:
+       true.............everything ok
+          false............an exception has been thrown
 
 *******************************************************************************/
 
-static exceptiontable * fillextable(methodinfo *m, 
-                                                                       exceptiontable *extable, 
-                                                                       exceptiontable *raw_extable, 
-                                                               int exceptiontablelength, 
-                                                                       int *block_count)
+static bool parse_mark_exception_boundaries(jitdata *jd, parsedata_t *pd)
 {
-       int b_count, p, src;
+       s4                   bcindex;
+       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 true;
+
+       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);
+
+               bcindex = rex->startpc;
+               CHECK_BYTECODE_INDEX(bcindex);
+               MARK_BASICBLOCK(pd, bcindex);
                
-               p = raw_extable[src].endpc; /* see JVM Spec 4.7.3 */
-               CHECK_BYTECODE_INDEX_EXCLUSIVE(p);
+               bcindex = rex->endpc; /* see JVM Spec 4.7.3 */
+               CHECK_BYTECODE_INDEX_EXCLUSIVE(bcindex);
+
+               /* check that the range is valid */
 
 #if defined(ENABLE_VERIFIER)
-               if (p <= raw_extable[src].startpc) {
-                       *exceptionptr = new_verifyerror(m,
-                               "Invalid exception handler range");
-                       return NULL;
+               if (bcindex <= rex->startpc) {
+                       exceptions_throw_verifyerror(m, "Invalid exception handler range");
+                       return false;
                }
 #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);
+               /* 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 (bcindex < m->jcodelength)
+                       MARK_BASICBLOCK(pd, bcindex);
+               else
+                       jd->branchtoend = true;
 
                /* 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--;
+
+               bcindex = rex->handlerpc;
+               CHECK_BYTECODE_INDEX(bcindex);
+               MARK_BASICBLOCK(pd, bcindex);
        }
 
-       *block_count = b_count;
-       
        /* everything ok */
-       return extable;
+
+       return true;
 
 #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 false;
 #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, parsedata_t *pd)
+{
+       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   = parse_bytecodeindex_to_basicblock(jd, pd, rex->startpc);
+               ex->end     = parse_bytecodeindex_to_basicblock(jd, pd, rex->endpc);
+               ex->handler = parse_bytecodeindex_to_basicblock(jd, pd, 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)
@@ -148,78 +368,87 @@ throw_invalid_bytecode_index:
 #define CHECK_END_OF_BYTECODE(neededlength)
 #endif /* ENABLE_VERIFIER */
 
-bool new_parse(jitdata *jd)
+bool parse(jitdata *jd)
 {
-       methodinfo  *m;             /* method being parsed                      */
-       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      */
-       new_instruction *iptr;      /* current ptr into instruction array       */
-       u1 *instructionstart;       /* 1 for pcs which are valid instr. starts  */
+       methodinfo  *m;                     /* method being parsed                */
+       parsedata_t  pd;
+       instruction *iptr;                  /* current ptr into instruction array */
+
+       s4           bcindex;               /* bytecode instruction index         */
+       s4           nextbc;                /* start of next bytecode instruction */
+       s4           opcode;                /* bytecode instruction opcode        */
+
+       s4           irindex;               /* IR instruction index               */
+       s4           ircount;               /* IR instruction count               */
+
+       s4           bbcount;               /* basic block count                  */
+
+       int  s_count = 0;             /* stack element counter                    */
+       bool blockend;                /* true if basic block end has been reached */
+       bool iswide;                  /* true if last instruction was a wide      */
+
        constant_classref  *cr;
        constant_classref  *compr;
        classinfo          *c;
        builtintable_entry *bte;
-       constant_FMIref    *mr;
+       constant_FMIref    *fmi;
        methoddesc         *md;
        unresolved_method  *um;
+       unresolved_field   *uf;
+
        resolve_result_t    result;
        u2                  lineindex = 0;
        u2                  currentline = 0;
        u2                  linepcchange = 0;
        u4                  flags;
+       basicblock         *bptr;
 
-       /* 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));
+       int                *local_map; /* local pointer to renaming map           */
+                                      /* is assigned to rd->local_map at the end */
+       branch_target_t *table;
+       lookup_target_t *lookup;
+       s4               i;
+       s4               j;
 
-       /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
-       /* additional MONITOREXITS are reached by branches which are 3 bytes */
+       /* get required compiler data */
 
-       iptr = jd->new_instructions = DMNEW(new_instruction, m->jcodelength + 5);
+       m = jd->m;
 
-       /* Zero the intermediate instructions array so we don't have any
-        * invalid pointers in it if we cannot finish analyse_stack(). */
+       /* allocate buffers for local variable renaming */
 
-       memset(iptr, 0, sizeof(new_instruction) * (m->jcodelength + 5)); /* XXX remove this? */
+       local_map = DMNEW(int, m->maxlocals * 5);
 
-       /* compute branch targets of exception table */
+       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;
+       ircount  = 0;
+       bbcount  = 0;
+       blockend = false;
+       iswide   = false;
+
+       /* mark basic block boundaries for exception table */
+
+       if (!parse_mark_exception_boundaries(jd, &pd))
                return false;
-       }
 
-       s_count = 1 + m->exceptiontablelength; /* initialize stack element counter   */
+       /* initialize stack element counter */
 
-#if defined(ENABLE_THREADS)
-       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
-               m->isleafmethod = false;
-       }
-#endif
+       s_count = 1 + m->rawexceptiontablelength;
+
+       /* setup line number info */
 
-       /* scan all java instructions */
        currentline = 0;
        linepcchange = 0;
 
@@ -232,56 +461,82 @@ bool new_parse(jitdata *jd)
 
        /*** LOOP OVER ALL BYTECODE INSTRUCTIONS **********************************/
 
-       for (p = 0; p < m->jcodelength; p = nextp) {
+       for (bcindex = 0; bcindex < m->jcodelength; bcindex = nextbc) {
 
-               /* mark this position as a valid instruction start */
+               /* mark this position as a valid bytecode instruction start */
 
-               instructionstart[p] = 1;
+               pd.bytecodestart[bcindex] = 1;
 
                /* change the current line number, if necessary */
 
-               if (linepcchange == p) {
+               /* XXX rewrite this using pointer arithmetic */
+
+               if (linepcchange == bcindex) {
                        if (m->linenumbercount > lineindex) {
 next_linenumber:
                                currentline = m->linenumbers[lineindex].line_number;
                                lineindex++;
                                if (lineindex < m->linenumbercount) {
                                        linepcchange = m->linenumbers[lineindex].start_pc;
-                                       if (linepcchange == p)
+                                       if (linepcchange == bcindex)
                                                goto next_linenumber;
                                }
                        }
                }
 
-               /* fetch next opcode  */
 fetch_opcode:
-               opcode = code_get_u1(p, m);
+               /* fetch next opcode  */        
 
-               /* store intermediate instruction count (bit 0 mark block starts) */
+               opcode = SUCK_BE_U1(m->jcode + bcindex);
 
-               m->basicblockindex[p] |= (ipc << 1);
+               /* If the previous instruction was a block-end instruction,
+                  mark the current bytecode instruction as basic-block
+                  starting instruction. */
 
-               /* some compilers put a JAVA_NOP after a blockend instruction */
+               /* NOTE: Some compilers put a JAVA_NOP after a blockend
+                  instruction. */
 
                if (blockend && (opcode != JAVA_NOP)) {
-                       /* start new block */
-
-                       block_insert(p);
+                       MARK_BASICBLOCK(&pd, bcindex);
                        blockend = false;
                }
 
+               /* If the current bytecode instruction was marked as
+                  basic-block starting instruction before (e.g. blockend,
+                  forward-branch target), mark the current IR instruction
+                  too. */
+
+               if (pd.basicblockstart[bcindex] != 0) {
+                       /* We need a NOP as last instruction in each basic block
+                          for basic block reordering (may be replaced with a GOTO
+                          later). */
+
+                       INSTRUCTIONS_CHECK(1);
+                       OP(ICMD_NOP);
+               }
+
+               /* store intermediate instruction count (bit 0 mark block starts) */
+
+               pd.bytecodemap[bcindex] = ircount;
+
                /* compute next instruction start */
 
-               nextp = p + jcommandsize[opcode];
+               nextbc = bcindex + jcommandsize[opcode];
 
-               CHECK_END_OF_BYTECODE(nextp);
+               CHECK_END_OF_BYTECODE(nextbc);
 
                /* add stack elements produced by this instruction */
 
                s_count += stackreq[opcode];
 
-               /* translate this bytecode instruction */
+               /* 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:
@@ -290,26 +545,26 @@ fetch_opcode:
                /* pushing constants onto the stack ***********************************/
 
                case JAVA_BIPUSH:
-                       NEW_OP_LOADCONST_I(code_get_s1(p+1,m));
+                       OP_LOADCONST_I(SUCK_BE_S1(m->jcode + bcindex + 1));
                        break;
 
                case JAVA_SIPUSH:
-                       NEW_OP_LOADCONST_I(code_get_s2(p+1,m));
+                       OP_LOADCONST_I(SUCK_BE_S2(m->jcode + bcindex + 1));
                        break;
 
                case JAVA_LDC1:
-                       i = code_get_u1(p + 1, m);
+                       i = SUCK_BE_U1(m->jcode + bcindex + 1);
                        goto pushconstantitem;
 
                case JAVA_LDC2:
                case JAVA_LDC2W:
-                       i = code_get_u2(p + 1, m);
+                       i = SUCK_BE_U2(m->jcode + bcindex + 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;
                        }
@@ -317,36 +572,35 @@ fetch_opcode:
 
                        switch (m->class->cptags[i]) {
                        case CONSTANT_Integer:
-                               NEW_OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
                                break;
                        case CONSTANT_Long:
-                               NEW_OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
                                break;
                        case CONSTANT_Float:
-                               NEW_OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
                                break;
                        case CONSTANT_Double:
-                               NEW_OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
                                break;
                        case CONSTANT_String:
-                               NEW_OP_LOADCONST_STRING(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 */
 
-                               NEW_OP_LOADCONST_CLASSINFO_OR_CLASSREF(c, cr, 0 /* no extra flags */);
+                               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
@@ -354,7 +608,7 @@ fetch_opcode:
                        break;
 
                case JAVA_ACONST_NULL:
-                       NEW_OP_LOADCONST_NULL();
+                       OP_LOADCONST_NULL();
                        break;
 
                case JAVA_ICONST_M1:
@@ -364,23 +618,83 @@ fetch_opcode:
                case JAVA_ICONST_3:
                case JAVA_ICONST_4:
                case JAVA_ICONST_5:
-                       NEW_OP_LOADCONST_I(opcode - JAVA_ICONST_0);
+                       OP_LOADCONST_I(opcode - JAVA_ICONST_0);
                        break;
 
                case JAVA_LCONST_0:
                case JAVA_LCONST_1:
-                       NEW_OP_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:
-                       NEW_OP_LOADCONST_F(opcode - JAVA_FCONST_0);
+                       OP_LOADCONST_F(opcode - JAVA_FCONST_0);
                        break;
 
                case JAVA_DCONST_0:
                case JAVA_DCONST_1:
-                       NEW_OP_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;
 
                /* local variable access instructions *********************************/
@@ -388,158 +702,159 @@ fetch_opcode:
                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 + bcindex + 1);
                        }
                        else {
-                               i = code_get_u2(p + 1,m);
-                               nextp = p + 3;
+                               i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                               nextbc = bcindex + 3;
                                iswide = false;
                        }
-                       NEW_OP_LOAD_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 + bcindex + 1);
                        }
                        else {
-                               i = code_get_u2(p + 1,m);
-                               nextp = p + 3;
+                               i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                               nextbc = bcindex + 3;
                                iswide = false;
                        }
-                       NEW_OP_LOAD_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:
-                       NEW_OP_LOAD_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:
-                       NEW_OP_LOAD_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:
-                       NEW_OP_LOAD_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:
-                       NEW_OP_LOAD_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:
-                       NEW_OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0);
+                       OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
                        break;
 
                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 + bcindex + 1);
                        }
                        else {
-                               i = code_get_u2(p + 1,m);
+                               i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                               nextbc = bcindex + 3;
                                iswide = false;
-                               nextp = p + 3;
                        }
-                       NEW_OP_STORE_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 + bcindex + 1);
                        }
                        else {
-                               i = code_get_u2(p + 1,m);
+                               i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                               nextbc = bcindex + 3;
                                iswide = false;
-                               nextp = p + 3;
                        }
-                       NEW_OP_STORE_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:
-                       NEW_OP_STORE_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:
-                       NEW_OP_STORE_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:
-                       NEW_OP_STORE_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:
-                       NEW_OP_STORE_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:
-                       NEW_OP_STORE_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 + bcindex + 1);
+                                       v = SUCK_BE_S1(m->jcode + bcindex + 2);
 
                                }
                                else {
-                                       i = code_get_u2(p + 1,m);
-                                       v = code_get_s2(p + 3,m);
+                                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                                       v = SUCK_BE_S2(m->jcode + bcindex + 3);
+                                       nextbc = bcindex + 5;
                                        iswide = false;
-                                       nextp = p + 5;
                                }
                                INDEX_ONEWORD(i);
-                               NEW_OP_LOCALINDEX_I(opcode, i, v);
+                               LOCALTYPE_USED(i, TYPE_INT);
+                               OP_LOCALINDEX_I(opcode, i, v);
                        }
                        break;
 
                /* wider index for loading, storing and incrementing ******************/
 
                case JAVA_WIDE:
+                       bcindex++;
                        iswide = true;
-                       p++;
                        goto fetch_opcode;
 
                /* managing arrays ****************************************************/
 
                case JAVA_NEWARRAY:
-                       switch (code_get_s1(p + 1, m)) {
+                       switch (SUCK_BE_S1(m->jcode + bcindex + 1)) {
                        case 4:
                                bte = builtintable_get_internal(BUILTIN_newarray_boolean);
                                break;
@@ -566,18 +881,17 @@ 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
                        }
-                       NEW_OP_BUILTIN_CHECK_EXCEPTION(bte);
+                       OP_BUILTIN_CHECK_EXCEPTION(bte);
                        break;
 
                case JAVA_ANEWARRAY:
-                       i = code_get_u2(p + 1, m);
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
                        compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
-                       if (!compr)
+                       if (compr == NULL)
                                return false;
 
                        if (!(cr = class_get_classref_multiarray_of(1, compr)))
@@ -586,30 +900,29 @@ fetch_opcode:
                        if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
                                return false;
 
-                       NEW_OP_LOADCONST_CLASSINFO_OR_CLASSREF(c, cr, INS_FLAG_NOCHECK);
+                       INSTRUCTIONS_CHECK(2);
+                       OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
                        bte = builtintable_get_internal(BUILTIN_newarray);
-                       NEW_OP_BUILTIN_CHECK_EXCEPTION(bte);
+                       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 */
-
-                               iptr->s1.argcount = v; /* XXX */
-                               NEW_OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags */);
-                       }
+                       jd->isleafmethod = false;
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       j = SUCK_BE_U1(m->jcode + bcindex + 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, INS_FLAG_CHECK);
                        break;
 
                /* control flow instructions ******************************************/
@@ -631,35 +944,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 = bcindex + SUCK_BE_S2(m->jcode + bcindex + 1);
                        CHECK_BYTECODE_INDEX(i);
-                       block_insert(i);
+                       MARK_BASICBLOCK(&pd, i);
                        blockend = true;
-                       NEW_OP_INSINDEX(opcode, i);
+                       OP_INSINDEX(opcode, i);
                        break;
 
                case JAVA_GOTO_W:
-               case JAVA_JSR_W:
-                       i = p + code_get_s4(p + 1,m);
+                       i = bcindex + SUCK_BE_S4(m->jcode + bcindex + 1);
+                       CHECK_BYTECODE_INDEX(i);
+                       MARK_BASICBLOCK(&pd, i);
+                       blockend = true;
+                       OP_INSINDEX(ICMD_GOTO, i);
+                       break;
+
+               case JAVA_JSR:
+                       i = bcindex + SUCK_BE_S2(m->jcode + bcindex + 1);
+jsr_tail:
                        CHECK_BYTECODE_INDEX(i);
-                       block_insert(i);
+                       MARK_BASICBLOCK(&pd, i);
                        blockend = true;
-                       NEW_OP_INSINDEX(opcode, i);
+                       OP_PREPARE_ZEROFLAGS(JAVA_JSR);
+                       iptr->sx.s23.s3.jsrtarget.insindex = i;
+                       PINC;
                        break;
 
+               case JAVA_JSR_W:
+                       i = bcindex + SUCK_BE_S4(m->jcode + bcindex + 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 + bcindex + 1);
                        }
                        else {
-                               i = code_get_u2(p + 1,m);
-                               nextp = p + 3;
+                               i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                               nextbc = bcindex + 3;
                                iswide = false;
                        }
                        blockend = true;
 
-                       NEW_OP_LOAD_ONEWORD(opcode, i);
+                       OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
                        break;
 
                case JAVA_IRETURN:
@@ -670,13 +996,13 @@ fetch_opcode:
                case JAVA_RETURN:
                        blockend = true;
                        /* XXX ARETURN will need a flag in the typechecker */
-                       NEW_OP(opcode);
+                       OP(opcode);
                        break;
 
                case JAVA_ATHROW:
                        blockend = true;
                        /* XXX ATHROW will need a flag in the typechecker */
-                       NEW_OP(opcode);
+                       OP(opcode);
                        break;
 
 
@@ -685,35 +1011,30 @@ fetch_opcode:
                case JAVA_LOOKUPSWITCH:
                        {
                                s4 num, j;
-                               const s4 *s4ptr;
                                lookup_target_t *lookup;
 #if defined(ENABLE_VERIFIER)
                                s4 prevvalue = 0;
 #endif
                                blockend = true;
-                               nextp = ALIGN((p + 1), 4);
+                               nextbc = MEMORY_ALIGN((bcindex + 1), 4);
 
-                               CHECK_END_OF_BYTECODE(nextp + 8);
+                               CHECK_END_OF_BYTECODE(nextbc + 8);
 
-                               s4ptr = (const s4 *) (m->jcode + nextp);
-
-                               NEW_OP_PREPARE(opcode);
+                               OP_PREPARE_ZEROFLAGS(opcode);
 
                                /* default target */
 
-                               j =  p + code_get_s4(nextp, m);
+                               j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
                                iptr->sx.s23.s3.lookupdefault.insindex = j;
-                               s4ptr++;
-                               nextp += 4;
+                               nextbc += 4;
                                CHECK_BYTECODE_INDEX(j);
-                               block_insert(j);
+                               MARK_BASICBLOCK(&pd, j);
 
                                /* number of pairs */
 
-                               num = code_get_u4(nextp, m);
+                               num = SUCK_BE_U4(m->jcode + nextbc);
                                iptr->sx.s23.s2.lookupcount = num;
-                               s4ptr++;
-                               nextp += 4;
+                               nextbc += 4;
 
                                /* allocate the intermediate code table */
 
@@ -722,35 +1043,33 @@ fetch_opcode:
 
                                /* iterate over the lookup table */
 
-                               CHECK_END_OF_BYTECODE(nextp + 8 * num);
+                               CHECK_END_OF_BYTECODE(nextbc + 8 * num);
 
                                for (i = 0; i < num; i++) {
                                        /* value */
 
-                                       j = code_get_s4(nextp, m);
+                                       j = SUCK_BE_S4(m->jcode + nextbc);
                                        lookup->value = j;
 
-                                       s4ptr++;
-                                       nextp += 4;
+                                       nextbc += 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);
+                                       j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
                                        lookup->target.insindex = j;
                                        lookup++;
-                                       s4ptr++;
-                                       nextp += 4;
+                                       nextbc += 4;
                                        CHECK_BYTECODE_INDEX(j);
-                                       block_insert(j);
+                                       MARK_BASICBLOCK(&pd, j);
                                }
 
                                PINC;
@@ -762,39 +1081,33 @@ fetch_opcode:
                        {
                                s4 num, j;
                                s4 deftarget;
-                               const s4 *s4ptr;
                                branch_target_t *table;
 
                                blockend = true;
-                               nextp = ALIGN((p + 1), 4);
-
-                               CHECK_END_OF_BYTECODE(nextp + 12);
+                               nextbc = MEMORY_ALIGN((bcindex + 1), 4);
 
-                               s4ptr = (const s4 *) (m->jcode + nextp);
+                               CHECK_END_OF_BYTECODE(nextbc + 12);
 
-                               NEW_OP_PREPARE(opcode);
+                               OP_PREPARE_ZEROFLAGS(opcode);
 
                                /* default target */
 
-                               deftarget = p + code_get_s4(nextp, m);
-                               s4ptr++;
-                               nextp += 4;
+                               deftarget = bcindex + SUCK_BE_S4(m->jcode + nextbc);
+                               nextbc += 4;
                                CHECK_BYTECODE_INDEX(deftarget);
-                               block_insert(deftarget);
+                               MARK_BASICBLOCK(&pd, deftarget);
 
                                /* lower bound */
 
-                               j = code_get_s4(nextp, m);
+                               j = SUCK_BE_S4(m->jcode + nextbc);
                                iptr->sx.s23.s2.tablelow = j;
-                               s4ptr++;
-                               nextp += 4;
+                               nextbc += 4;
 
                                /* upper bound */
 
-                               num = code_get_s4(nextp, m);
+                               num = SUCK_BE_S4(m->jcode + nextbc);
                                iptr->sx.s23.s3.tablehigh = num;
-                               s4ptr++;
-                               nextp += 4;
+                               nextbc += 4;
 
                                /* calculate the number of table entries */
 
@@ -802,7 +1115,7 @@ fetch_opcode:
 
 #if defined(ENABLE_VERIFIER)
                                if (num < 1) {
-                                       *exceptionptr = new_verifyerror(m,
+                                       exceptions_throw_verifyerror(m,
                                                        "invalid TABLESWITCH: upper bound < lower bound");
                                        return false;
                                }
@@ -810,21 +1123,20 @@ fetch_opcode:
                                /* create the intermediate code table */
                                /* the first entry is the default target */
 
-                               table = MNEW(branch_target_t, 1 + num);
+                               table = DMNEW(branch_target_t, 1 + num);
                                iptr->dst.table = table;
                                (table++)->insindex = deftarget;
 
                                /* iterate over the target table */
 
-                               CHECK_END_OF_BYTECODE(nextp + 4 * num);
+                               CHECK_END_OF_BYTECODE(nextbc + 4 * num);
 
                                for (i = 0; i < num; i++) {
-                                       j = p + code_get_s4(nextp,m);
+                                       j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
                                        (table++)->insindex = j;
-                                       s4ptr++;
-                                       nextp += 4;
+                                       nextbc += 4;
                                        CHECK_BYTECODE_INDEX(j);
-                                       block_insert(j);
+                                       MARK_BASICBLOCK(&pd, j);
                                }
 
                                PINC;
@@ -835,118 +1147,145 @@ fetch_opcode:
                /* load and store of object fields ************************************/
 
                case JAVA_AASTORE:
-                       NEW_OP(opcode);
-                       m->isleafmethod = false;
+                       OP(opcode);
+                       jd->isleafmethod = false;
                        break;
 
                case JAVA_GETSTATIC:
                case JAVA_PUTSTATIC:
                case JAVA_GETFIELD:
                case JAVA_PUTFIELD:
-                       {
-                               constant_FMIref  *fr;
-                               unresolved_field *uf;
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       fmi = class_getconstant(m->class, i, CONSTANT_Fieldref);
 
-                               i = code_get_u2(p + 1, m);
-                               fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
-                               if (!fr)
-                                       return false;
+                       if (fmi == NULL)
+                               return false;
 
-                               NEW_OP_PREPARE(opcode);
-                               iptr->sx.s23.s3.fmiref = fr;
+                       OP_PREPARE_ZEROFLAGS(opcode);
+                       iptr->sx.s23.s3.fmiref = fmi;
 
-                               /* only with -noverify, otherwise the typechecker does this */
+                       /* only with -noverify, otherwise the typechecker does this */
 
 #if defined(ENABLE_VERIFIER)
-                               if (!opt_verify) {
+                       if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
 #endif
-                                       result = resolve_field_lazy(/* XXX */(instruction *)iptr, NULL, m);
-                                       if (result == resolveFailed)
-                                               return false;
+                               result = resolve_field_lazy(m, fmi);
+
+                               if (result == resolveFailed)
+                                       return false;
 
-                                       if (result != resolveSucceeded) {
-                                               uf = create_unresolved_field(m->class, m, /* XXX */(instruction *)iptr);
+                               if (result != resolveSucceeded) {
+                                       uf = resolve_create_unresolved_field(m->class, m, iptr);
 
-                                               if (!uf)
-                                                       return false;
+                                       if (uf == NULL)
+                                               return false;
 
-                                               /* store the unresolved_field pointer */
+                                       /* store the unresolved_field pointer */
 
-                                               iptr->sx.s23.s3.uf = uf;
-                                               iptr->flags.bits = INS_FLAG_UNRESOLVED;
-                                       }
-#if defined(ENABLE_VERIFIER)
+                                       iptr->sx.s23.s3.uf = uf;
+                                       iptr->flags.bits |= INS_FLAG_UNRESOLVED;
                                }
-#endif
-                               PINC;
+#if defined(ENABLE_VERIFIER)
                        }
+#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)
+                       OP_PREPARE_ZEROFLAGS(opcode);
+
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
+
+                       if (fmi == NULL)
                                return false;
 
-                       md = mr->parseddesc.md;
+                       md = fmi->parseddesc.md;
 
-                       if (!md->params)
+                       if (md->params == NULL)
                                if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
                                        return false;
 
                        goto invoke_method;
 
+               case JAVA_INVOKESPECIAL:
+                       OP_PREPARE_FLAGS(opcode, INS_FLAG_CHECK);
+
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
+
+                       goto invoke_nonstatic_method;
+
                case JAVA_INVOKEINTERFACE:
-                       i = code_get_u2(p + 1, m);
+                       OP_PREPARE_ZEROFLAGS(opcode);
 
-                       mr = class_getconstant(m->class, i,
-                                       CONSTANT_InterfaceMethodref);
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       fmi = 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);
+                       OP_PREPARE_ZEROFLAGS(opcode);
+
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
 
 invoke_nonstatic_method:
-                       if (!mr)
+                       if (fmi == NULL)
                                return false;
 
-                       md = mr->parseddesc.md;
+                       md = fmi->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;
 
-                       NEW_OP_PREPARE(opcode);
-                       iptr->sx.s23.s3.fmiref = mr;
+                       iptr->sx.s23.s3.fmiref = fmi;
 
                        /* only with -noverify, otherwise the typechecker does this */
 
 #if defined(ENABLE_VERIFIER)
-                       if (!opt_verify) {
+                       if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
 #endif
-                               result = resolve_method_lazy(/* XXX */(instruction *)iptr, NULL, m);
+                               result = resolve_method_lazy(m, fmi, 
+                                                                                        (opcode == JAVA_INVOKESPECIAL));
+
                                if (result == resolveFailed)
                                        return false;
 
-                               if (result != resolveSucceeded) {
-                                       um = create_unresolved_method(m->class, m, /* XXX */(instruction *)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;
+                                               iptr->flags.bits |= INS_FLAG_CHECK;
+                                       }
+                               }
+                               else {
+                                       um = resolve_create_unresolved_method(m->class, m, fmi,
+                                                       (opcode == JAVA_INVOKESTATIC),
+                                                       (opcode == JAVA_INVOKESPECIAL));
 
-                                       if (!um)
+                                       if (um == NULL)
                                                return false;
 
                                        /* store the unresolved_method pointer */
 
                                        iptr->sx.s23.s3.um = um;
-                                       iptr->flags.bits = INS_FLAG_UNRESOLVED;
+                                       iptr->flags.bits |= INS_FLAG_UNRESOLVED;
                                }
 #if defined(ENABLE_VERIFIER)
                        }
@@ -957,24 +1296,27 @@ invoke_method:
                /* instructions taking class arguments ********************************/
 
                case JAVA_NEW:
-                       i = code_get_u2(p + 1, m);
-                       cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
-                       if (!cr)
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       cr = class_getconstant(m->class, i, CONSTANT_Class);
+
+                       if (cr == NULL)
                                return false;
 
                        if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
                                return false;
 
-                       NEW_OP_LOADCONST_CLASSINFO_OR_CLASSREF(c, cr, INS_FLAG_NOCHECK);
+                       INSTRUCTIONS_CHECK(2);
+                       OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
                        bte = builtintable_get_internal(BUILTIN_new);
-                       NEW_OP_BUILTIN_CHECK_EXCEPTION(bte);
+                       OP_BUILTIN_CHECK_EXCEPTION(bte);
                        s_count++;
                        break;
 
                case JAVA_CHECKCAST:
-                       i = code_get_u2(p + 1, m);
-                       cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
-                       if (!cr)
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       cr = class_getconstant(m->class, i, CONSTANT_Class);
+
+                       if (cr == NULL)
                                return false;
 
                        if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
@@ -982,20 +1324,21 @@ invoke_method:
 
                        if (cr->name->text[0] == '[') {
                                /* array type cast-check */
-                               flags = INS_FLAG_ARRAY;
-                               m->isleafmethod = false;
+                               flags = INS_FLAG_CHECK | INS_FLAG_ARRAY;
+                               jd->isleafmethod = false;
                        }
                        else {
                                /* object type cast-check */
-                               flags = 0;
+                               flags = INS_FLAG_CHECK;
                        }
-                       NEW_OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
+                       OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
                        break;
 
                case JAVA_INSTANCEOF:
-                       i = code_get_u2(p + 1,m);
-                       cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
-                       if (!cr)
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       cr = class_getconstant(m->class, i, CONSTANT_Class);
+
+                       if (cr == NULL)
                                return false;
 
                        if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
@@ -1003,14 +1346,15 @@ invoke_method:
 
                        if (cr->name->text[0] == '[') {
                                /* array type cast-check */
-                               NEW_OP_LOADCONST_CLASSINFO_OR_CLASSREF(c, cr, INS_FLAG_NOCHECK);
+                               INSTRUCTIONS_CHECK(2);
+                               OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
                                bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
-                               NEW_OP_BUILTIN_NO_EXCEPTION(bte);
+                               OP_BUILTIN_NO_EXCEPTION(bte);
                                s_count++;
                        }
                        else {
                                /* object type cast-check */
-                               NEW_OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
+                               OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
                        }
                        break;
 
@@ -1019,84 +1363,100 @@ invoke_method:
                case JAVA_MONITORENTER:
 #if defined(ENABLE_THREADS)
                        if (checksync) {
-                               NEW_OP(ICMD_CHECKNULL);
-                               bte = builtintable_get_internal(BUILTIN_monitorenter);
-                               NEW_OP_BUILTIN_NO_EXCEPTION(bte);
+                               bte = builtintable_get_internal(LOCK_monitor_enter);
+                               OP_BUILTIN_CHECK_EXCEPTION(bte);
                        }
                        else
 #endif
-                               {
-                                       NEW_OP(ICMD_CHECKNULL);
-                                       NEW_OP(ICMD_POP);
-                               }
-                       break;
+                       {
+                               OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
+                               OP(ICMD_POP);
+                       }
+                       break;
 
                case JAVA_MONITOREXIT:
 #if defined(ENABLE_THREADS)
                        if (checksync) {
-                               bte = builtintable_get_internal(BUILTIN_monitorexit);
-                               NEW_OP_BUILTIN_NO_EXCEPTION(bte);
+                               bte = builtintable_get_internal(LOCK_monitor_exit);
+                               OP_BUILTIN_CHECK_EXCEPTION(bte);
                        }
                        else
 #endif
-                               {
-                                       NEW_OP(ICMD_POP);
-                               }
+                       {
+                               OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
+                               OP(ICMD_POP);
+                       }
                        break;
 
-               /* arithmetic instructions they may become builtin functions **********/
+               /* arithmetic instructions that may become builtin functions **********/
 
                case JAVA_IDIV:
 #if !SUPPORT_DIVISION
                        bte = builtintable_get_internal(BUILTIN_idiv);
-                       NEW_OP_BUILTIN_ARITHMETIC(opcode, bte);
+                       OP_BUILTIN_ARITHMETIC(opcode, bte);
 #else
+# if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
                        OP(opcode);
+# else
+                       OP_CHECK_EXCEPTION(opcode);
+# endif
 #endif
                        break;
 
                case JAVA_IREM:
 #if !SUPPORT_DIVISION
                        bte = builtintable_get_internal(BUILTIN_irem);
-                       NEW_OP_BUILTIN_ARITHMETIC(opcode, bte);
+                       OP_BUILTIN_ARITHMETIC(opcode, bte);
 #else
+# if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
                        OP(opcode);
+# else
+                       OP_CHECK_EXCEPTION(opcode);
+# endif
 #endif
                        break;
 
                case JAVA_LDIV:
 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
                        bte = builtintable_get_internal(BUILTIN_ldiv);
-                       NEW_OP_BUILTIN_ARITHMETIC(opcode, bte);
+                       OP_BUILTIN_ARITHMETIC(opcode, bte);
 #else
+# if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
                        OP(opcode);
+# else
+                       OP_CHECK_EXCEPTION(opcode);
+# endif
 #endif
                        break;
 
                case JAVA_LREM:
 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
                        bte = builtintable_get_internal(BUILTIN_lrem);
-                       NEW_OP_BUILTIN_ARITHMETIC(opcode, bte);
+                       OP_BUILTIN_ARITHMETIC(opcode, bte);
 #else
+# if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
                        OP(opcode);
+# else
+                       OP_CHECK_EXCEPTION(opcode);
+# endif
 #endif
                        break;
 
                case JAVA_FREM:
 #if defined(__I386__)
-                       NEW_OP(opcode);
+                       OP(opcode);
 #else
                        bte = builtintable_get_internal(BUILTIN_frem);
-                       NEW_OP_BUILTIN_NO_EXCEPTION(bte);
+                       OP_BUILTIN_NO_EXCEPTION(bte);
 #endif
                        break;
 
                case JAVA_DREM:
 #if defined(__I386__)
-                       NEW_OP(opcode);
+                       OP(opcode);
 #else
                        bte = builtintable_get_internal(BUILTIN_drem);
-                       NEW_OP_BUILTIN_NO_EXCEPTION(bte);
+                       OP_BUILTIN_NO_EXCEPTION(bte);
 #endif
                        break;
 
@@ -1104,12 +1464,12 @@ invoke_method:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_f2i);
-                               NEW_OP_BUILTIN_NO_EXCEPTION(bte);
+                               OP_BUILTIN_NO_EXCEPTION(bte);
                        }
                        else
 #endif
                        {
-                               NEW_OP(opcode);
+                               OP(opcode);
                        }
                        break;
 
@@ -1117,12 +1477,12 @@ invoke_method:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_f2l);
-                               NEW_OP_BUILTIN_NO_EXCEPTION(bte);
+                               OP_BUILTIN_NO_EXCEPTION(bte);
                        }
                        else
 #endif
                        {
-                               NEW_OP(opcode);
+                               OP(opcode);
                        }
                        break;
 
@@ -1130,12 +1490,12 @@ invoke_method:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_d2i);
-                               NEW_OP_BUILTIN_NO_EXCEPTION(bte);
+                               OP_BUILTIN_NO_EXCEPTION(bte);
                        }
                        else
 #endif
                        {
-                               NEW_OP(opcode);
+                               OP(opcode);
                        }
                        break;
 
@@ -1143,12 +1503,12 @@ invoke_method:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_d2l);
-                               NEW_OP_BUILTIN_NO_EXCEPTION(bte);
+                               OP_BUILTIN_NO_EXCEPTION(bte);
                        }
                        else
 #endif
                        {
-                               NEW_OP(opcode);
+                               OP(opcode);
                        }
                        break;
 
@@ -1157,8 +1517,7 @@ invoke_method:
                        /* 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 */
@@ -1215,9 +1574,8 @@ 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, ircount);
                        return false;
                        break;
 #endif /* defined(ENABLE_VERIFIER) */
@@ -1226,15 +1584,17 @@ invoke_method:
 
                default:
                        /* straight-forward translation to ICMD */
-                       NEW_OP(opcode);
+                       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;
                }
@@ -1242,1399 +1602,305 @@ 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(ircount <= pd.instructionslength);
+       assert(ircount == (iptr - pd.instructions));
+
+       /*** verifier checks ******************************************************/
+
 #if defined(ENABLE_VERIFIER)
-       if (p != m->jcodelength) {
-               *exceptionptr = new_verifyerror(m,
+       if (bcindex != m->jcodelength) {
+               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) */
 
-       /* adjust block count if target 0 is not first intermediate instruction */
+       /*** setup the methodinfo, allocate stack and basic blocks ****************/
 
-       if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1))
-               b_count++;
+       /* identify basic blocks */
 
-       /* copy local to method variables */
+       /* check if first instruction is a branch target */
 
-       m->instructioncount = ipc;
-       m->basicblockcount = b_count;
-       m->stackcount = s_count + m->basicblockcount * m->maxstack;
-
-       /* allocate stack table */
-
-       m->stack = DMNEW(stackelement, m->stackcount);
-
-       {
-               basicblock *bptr;
-
-               bptr = m->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 */
+       if (pd.basicblockstart[0] == 1) {
+               jd->branchtoentry = true;
+       }
+       else {
+               /* first instruction always starts a basic block */
 
-               if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1)) {
-                       BASICBLOCK_INIT(bptr,m);
+               iptr = pd.instructions;
 
-                       bptr->iinstr = m->instructions;
-                       /* bptr->icount is set when the next block is allocated */
+               iptr->flags.bits |= INS_FLAG_BASICBLOCK;
+       }
 
-                       bptr++;
-                       b_count++;
-                       bptr[-1].next = bptr;
-               }
+       /* Iterate over all bytecode instructions and set missing
+          basic-block starts in IR instructions. */
 
-               /* allocate blocks */
+       for (bcindex = 0; bcindex < m->jcodelength; bcindex++) {
+               /* Does the current bytecode instruction start a basic
+                  block? */
 
-               for (p = 0; p < m->jcodelength; p++) {
-                       if (m->basicblockindex[p] & 1) {
-                               /* Check if this block starts at the beginning of an          */
-                               /* instruction.                                               */
+               if (pd.basicblockstart[bcindex] == 1) {
 #if defined(ENABLE_VERIFIER)
-                               if (!instructionstart[p]) {
-                                       *exceptionptr = new_verifyerror(m,
-                                               "Branch into middle of instruction");
-                                       return false;
-                               }
-#endif
-
-                               /* allocate the block */
-
-                               BASICBLOCK_INIT(bptr,m);
+                       /* Check if this bytecode basic-block start at the
+                          beginning of a bytecode instruction. */
 
-                               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 */
-
-                               m->basicblockindex[p] = b_count;
-
-                               bptr++;
-                               b_count++;
-                               bptr[-1].next = bptr;
+                       if (pd.bytecodestart[bcindex] == 0) {
+                               exceptions_throw_verifyerror(m,
+                                                                                "Branch into middle of instruction");
+                               return false;
                        }
-               }
+#endif
 
-               /* set instruction count of last real block */
+                       /* Get the IR instruction mapped to the bytecode
+                          instruction and set the basic block flag. */
 
-               if (b_count) {
-                       bptr[-1].icount = (m->instructions + m->instructioncount) - bptr[-1].iinstr;
+                       irindex = pd.bytecodemap[bcindex];
+                       iptr    = pd.instructions + irindex;
+
+                       iptr->flags.bits |= INS_FLAG_BASICBLOCK;
                }
+       }
 
-               /* allocate additional block at end */
+       /* IR instruction index to basic-block index mapping */
 
-               BASICBLOCK_INIT(bptr,m);
+       pd.instructionmap = DMNEW(s4, ircount);
+       MZERO(pd.instructionmap, s4, ircount);
 
-               bptr->instack = bptr->outstack = NULL;
-               bptr->indepth = bptr->outdepth = 0;
-               bptr->iinstr = NULL;
-               bptr->icount = 0;
-               bptr->next = NULL;
+       /* Iterate over all IR instructions and count the basic blocks. */
 
-               /* set basicblock pointers in exception table */
+       iptr = pd.instructions;
 
-               if (cd->exceptiontablelength > 0) {
-                       cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
-               }
+       bbcount = 0;
 
-               for (i = 0; i < cd->exceptiontablelength; ++i) {
-                       p = cd->exceptiontable[i].startpc;
-                       cd->exceptiontable[i].start = m->basicblocks + m->basicblockindex[p];
+       for (i = 0; i < ircount; i++, iptr++) {
+               if (INSTRUCTION_STARTS_BASICBLOCK(iptr)) {
+                       /* store the basic-block number in the IR instruction
+                          map */
 
-                       p = cd->exceptiontable[i].endpc;
-                       cd->exceptiontable[i].end = (p == m->jcodelength) ? (m->basicblocks + m->basicblockcount /*+ 1*/) : (m->basicblocks + m->basicblockindex[p]);
+                       pd.instructionmap[i] = bbcount;
 
-                       p = cd->exceptiontable[i].handlerpc;
-                       cd->exceptiontable[i].handler = m->basicblocks + m->basicblockindex[p];
-           }
+                       /* post-increment the basic-block count */
 
-               /* 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];
+                       bbcount++;
+               }
+       }
 
-                       p = m->exceptiontable[i].endpc;
-                       m->exceptiontable[i].end = (p == m->jcodelength) ? (m->basicblocks + m->basicblockcount /*+ 1*/) : (m->basicblocks + m->basicblockindex[p]);
+       /* Allocate basic block array (one more for end ipc). */
 
-                       p = m->exceptiontable[i].handlerpc;
-                       m->exceptiontable[i].handler = m->basicblocks + m->basicblockindex[p];
-           }
-#endif
+       jd->basicblocks = DMNEW(basicblock, bbcount + 1);
+       MZERO(jd->basicblocks, basicblock, bbcount + 1);
 
-       }
+       /* Now iterate again over all IR instructions and initialize the
+          basic block structures and, in the same loop, resolve the
+          branch-target instruction indices to basic blocks. */
 
-       /* everything's ok */
+       iptr = pd.instructions;
+       bptr = jd->basicblocks;
 
-       return true;
+       bbcount = 0;
 
-#if defined(ENABLE_VERIFIER)
+       for (i = 0; i < ircount; i++, iptr++) {
+               /* check for basic block */
 
-throw_unexpected_end_of_bytecode:
-       *exceptionptr = new_verifyerror(m, "Unexpected end of bytecode");
-       return false;
+               if (INSTRUCTION_STARTS_BASICBLOCK(iptr)) {
+                       /* intialize the basic block */
 
-throw_invalid_bytecode_index:
-       *exceptionptr =
-               new_verifyerror(m, "Illegal target of branch instruction");
-       return false;
+                       BASICBLOCK_INIT(bptr, m);
 
-throw_illegal_local_variable_number:
-       *exceptionptr =
-               new_verifyerror(m, "Illegal local variable number");
-       return false;
+                       bptr->iinstr = iptr;
 
-#endif /* ENABLE_VERIFIER */
-}
+                       if (bbcount > 0) {
+                               bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
+                       }
 
+                       /* bptr->icount is set when the next block is allocated */
 
-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 */
-
-       u1 *instructionstart;       /* 1 for pcs which are valid instr. starts    */
+                       bptr->nr = bbcount++;
+                       bptr++;
+                       bptr[-1].next = bptr;
+               }
 
-       constant_classref  *cr;
-       constant_classref  *compr;
-       classinfo          *c;
-       builtintable_entry *bte;
+               /* resolve instruction indices to basic blocks */
 
-       constant_FMIref   *mr;
-       methoddesc        *md;
-       unresolved_method *um;
-       resolve_result_t   result;
+               switch (iptr->opc) {
+               case JAVA_IFEQ:
+               case JAVA_IFLT:
+               case JAVA_IFLE:
+               case JAVA_IFNE:
+               case JAVA_IFGT:
+               case JAVA_IFGE:
+               case JAVA_IFNULL:
+               case JAVA_IFNONNULL:
+               case JAVA_IF_ICMPEQ:
+               case JAVA_IF_ICMPNE:
+               case JAVA_IF_ICMPLT:
+               case JAVA_IF_ICMPGT:
+               case JAVA_IF_ICMPLE:
+               case JAVA_IF_ICMPGE:
+               case JAVA_IF_ACMPEQ:
+               case JAVA_IF_ACMPNE:
+               case JAVA_GOTO:
+                       BYTECODEINDEX_TO_BASICBLOCK(iptr->dst);
+                       break;
 
-       u2 lineindex = 0;
-       u2 currentline = 0;
-       u2 linepcchange = 0;
+               case ICMD_JSR:
+                       BYTECODEINDEX_TO_BASICBLOCK(iptr->sx.s23.s3.jsrtarget);
+                       break;
 
-       /* get required compiler data */
+               case ICMD_TABLESWITCH:
+                       table = iptr->dst.table;
 
-       m  = jd->m;
-       cd = jd->cd;
+                       BYTECODEINDEX_TO_BASICBLOCK(*table);
+                       table++;
 
-       /* 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));
+                       j = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1;
 
-       instructionstart = DMNEW(u1, m->jcodelength + 1);
-       memset(instructionstart, 0, sizeof(u1) * (m->jcodelength + 1));
+                       while (--j >= 0) {
+                               BYTECODEINDEX_TO_BASICBLOCK(*table);
+                               table++;
+                       }
+                       break;
 
-       /* 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);
+               case ICMD_LOOKUPSWITCH:
+                       BYTECODEINDEX_TO_BASICBLOCK(iptr->sx.s23.s3.lookupdefault);
 
-       /* Zero the intermediate instructions array so we don't have any
-        * invalid pointers in it if we cannot finish analyse_stack(). */
+                       lookup = iptr->dst.lookup;
 
-       memset(iptr, 0, sizeof(instruction) * (m->jcodelength + 5));
-       
-       /* compute branch targets of exception table */
+                       j = iptr->sx.s23.s2.lookupcount;
 
-       if (!fillextable(m, 
-                       &(cd->exceptiontable[cd->exceptiontablelength-1]), 
-                       m->exceptiontable, 
-                       m->exceptiontablelength, 
-                       &b_count))
-       {
-               return false;
+                       while (--j >= 0) {
+                               BYTECODEINDEX_TO_BASICBLOCK(lookup->target);
+                               lookup++;
+                       }
+                       break;
+               }
        }
 
-       s_count = 1 + m->exceptiontablelength; /* initialize stack element counter   */
-
-#if defined(ENABLE_THREADS)
-       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
-               m->isleafmethod = false;
-       }                       
-#endif
-
-       /* scan all java instructions */
-       currentline = 0;
-       linepcchange = 0;
+       /* set instruction count of last real block */
 
-       if (m->linenumbercount == 0) {
-               lineindex = 0;
-       } 
-       else {
-               linepcchange = m->linenumbers[0].start_pc;
+       if (bbcount > 0) {
+               bptr[-1].icount = (pd.instructions + ircount) - bptr[-1].iinstr;
        }
 
-       for (p = 0; p < m->jcodelength; p = nextp) {
-         
-               /* mark this position as a valid instruction start */
-               instructionstart[p] = 1;
-               if (linepcchange == p) {
-                       if (m->linenumbercount > lineindex) {
-next_linenumber:
-                               currentline = m->linenumbers[lineindex].line_number;
-                               lineindex++;
-                               if (lineindex < m->linenumbercount) {
-                                       linepcchange = m->linenumbers[lineindex].start_pc;
-                                       if (linepcchange == p)
-                                               goto next_linenumber;
-                               }
-                       }
-               }
-
-               /* fetch next opcode  */
-fetch_opcode:
-               opcode = code_get_u1(p, m);
+       /* allocate additional block at end */
 
-               m->basicblockindex[p] |= (ipc << 1); /*store intermed cnt*/
+       BASICBLOCK_INIT(bptr, m);
+       bptr->nr = bbcount;
 
-               /* some compilers put a JAVA_NOP after a blockend instruction */
+       /* set basicblock pointers in exception table */
 
-               if (blockend && (opcode != JAVA_NOP)) {
-                       /* start new block */
+       if (!parse_resolve_exception_table(jd, &pd))
+               return false;
 
-                       block_insert(p);
-                       blockend = false;
-               }
+       /* store the local map */
 
-               nextp = p + jcommandsize[opcode];   /* compute next instruction start */
+       jd->local_map = local_map;
 
-               CHECK_END_OF_BYTECODE(nextp);
+       /* calculate local variable renaming */
 
-               s_count += stackreq[opcode];            /* compute stack element count    */
-               switch (opcode) {
-               case JAVA_NOP:
-                       break;
+       {
+               s4 nlocals = 0;
+               s4 i;
+               s4 *mapptr;
 
-                       /* pushing constants onto the stack p */
+               mapptr = local_map;
 
-               case JAVA_BIPUSH:
-                       LOADCONST_I(code_get_s1(p+1,m));
-                       break;
+               /* iterate over local_map[0..m->maxlocals*5-1] and allocate a unique */
+               /* variable index for each _used_ (javaindex,type) pair.             */
+               /* (local_map[javaindex*5+type] = cacaoindex)                        */
+               /* Unused (javaindex,type) pairs are marked with UNUSED.             */
 
-               case JAVA_SIPUSH:
-                       LOADCONST_I(code_get_s2(p+1,m));
-                       break;
+               for (i = 0; i < (m->maxlocals * 5); i++, mapptr++) {
+                       if (*mapptr)
+                               *mapptr = nlocals++;
+                       else
+                               *mapptr = UNUSED;
+               }
 
-               case JAVA_LDC1:
-                       i = code_get_u1(p + 1, m);
-                       goto pushconstantitem;
+               jd->localcount = nlocals;
 
-               case JAVA_LDC2:
-               case JAVA_LDC2W:
-                       i = code_get_u2(p + 1, m);
+               /* calculate the (maximum) number of variables needed */
 
-               pushconstantitem:
+               jd->varcount = 
+                         nlocals                                      /* local variables */
+                       + bbcount * m->maxstack                                 /* invars */
+                       + s_count;         /* variables created within blocks (non-invar) */
 
-#if defined(ENABLE_VERIFIER)
-                       if (i >= m->class->cpcount) {
-                               *exceptionptr = new_verifyerror(m,
-                                       "Attempt to access constant outside range");
-                               return false;
-                       }
-#endif
+               /* reserve the first indices for local variables */
 
-                       switch (m->class->cptags[i]) {
-                       case CONSTANT_Integer:
-                               LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
-                               break;
-                       case CONSTANT_Long:
-                               LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
-                               break;
-                       case CONSTANT_Float:
-                               LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
-                               break;
-                       case CONSTANT_Double:
-                               LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
-                               break;
-                       case CONSTANT_String:
-                               LOADCONST_A(literalstring_new((utf *) (m->class->cpinfos[i])));
-                               break;
-                       case CONSTANT_Class:
-                               cr = (constant_classref *) (m->class->cpinfos[i]);
+               jd->vartop = nlocals;
 
-                               if (!resolve_classref(m, cr, resolveLazy, true,
-                                                                         true, &c))
-                                       return false;
+               /* reserve extra variables needed by stack analyse */
 
-                               /* if not resolved, c == NULL */
+               jd->varcount += STACK_EXTRA_VARS;
+               jd->vartop   += STACK_EXTRA_VARS;
 
-                               if (c) {
-                                       iptr->target = (void*) 0x02; /* XXX target used temporarily as flag */
-                                       LOADCONST_A(c);
-                               }
-                               else {
-                                       iptr->target = (void*) 0x03; /* XXX target used temporarily as flag */
-                                       LOADCONST_A(cr);
-                               }
-                               break;
+               /* The verifier needs space for saving invars in some cases and */
+               /* extra variables.                                             */
 
 #if defined(ENABLE_VERIFIER)
-                       default:
-                               *exceptionptr = new_verifyerror(m,
-                                               "Invalid constant type to push");
-                               return false;
+               jd->varcount += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
+               jd->vartop   += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
 #endif
-                       }
-                       break;
-
-               case JAVA_ACONST_NULL:
-                       LOADCONST_A(NULL);
-                       break;
+               /* allocate and initialize the variable array */
 
-               case JAVA_ICONST_M1:
-               case JAVA_ICONST_0:
-               case JAVA_ICONST_1:
-               case JAVA_ICONST_2:
-               case JAVA_ICONST_3:
-               case JAVA_ICONST_4:
-               case JAVA_ICONST_5:
-                       LOADCONST_I(opcode - JAVA_ICONST_0);
-                       break;
+               jd->var = DMNEW(varinfo, jd->varcount);
+               MZERO(jd->var, varinfo, jd->varcount);
 
-               case JAVA_LCONST_0:
-               case JAVA_LCONST_1:
-                       LOADCONST_L(opcode - JAVA_LCONST_0);
-                       break;
+               /* set types of all locals in jd->var */
 
-               case JAVA_FCONST_0:
-               case JAVA_FCONST_1:
-               case JAVA_FCONST_2:
-                       LOADCONST_F(opcode - JAVA_FCONST_0);
-                       break;
+               for (mapptr = local_map, i = 0; i < (m->maxlocals * 5); i++, mapptr++)
+                       if (*mapptr != UNUSED)
+                               VAR(*mapptr)->type = i%5;
+       }
 
-               case JAVA_DCONST_0:
-               case JAVA_DCONST_1:
-                       LOADCONST_D(opcode - JAVA_DCONST_0);
-                       break;
+       /* assign local variables to method variables */
 
-                       /* loading variables onto the stack */
+       jd->instructions     = pd.instructions;
+       jd->instructioncount = ircount;
+       jd->basicblockcount  = bbcount;
+       jd->stackcount       = s_count + bbcount * m->maxstack; /* in-stacks */
 
-               case JAVA_ILOAD:
-               case JAVA_FLOAD:
-               case JAVA_ALOAD:
-                       if (!iswide) {
-                               i = code_get_u1(p + 1,m);
-                       } 
-                       else {
-                               i = code_get_u2(p + 1,m);
-                               nextp = p + 3;
-                               iswide = false;
-                       }
-                       OP1LOAD_ONEWORD(opcode, i);
-                       break;
+       /* allocate stack table */
 
-               case JAVA_LLOAD:
-               case JAVA_DLOAD:
-                       if (!iswide) {
-                               i = code_get_u1(p + 1,m);
-                       } 
-                       else {
-                               i = code_get_u2(p + 1,m);
-                               nextp = p + 3;
-                               iswide = false;
-                       }
-                       OP1LOAD_TWOWORD(opcode, i);
-                       break;
+       jd->stack = DMNEW(stackelement, jd->stackcount);
 
-               case JAVA_ILOAD_0:
-               case JAVA_ILOAD_1:
-               case JAVA_ILOAD_2:
-               case JAVA_ILOAD_3:
-                       OP1LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0);
-                       break;
+       /* everything's ok */
 
-               case JAVA_LLOAD_0:
-               case JAVA_LLOAD_1:
-               case JAVA_LLOAD_2:
-               case JAVA_LLOAD_3:
-                       OP1LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0);
-                       break;
+       return true;
 
-               case JAVA_FLOAD_0:
-               case JAVA_FLOAD_1:
-               case JAVA_FLOAD_2:
-               case JAVA_FLOAD_3:
-                       OP1LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0);
-                       break;
+       /*** goto labels for throwing verifier exceptions *************************/
 
-               case JAVA_DLOAD_0:
-               case JAVA_DLOAD_1:
-               case JAVA_DLOAD_2:
-               case JAVA_DLOAD_3:
-                       OP1LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0);
-                       break;
+#if defined(ENABLE_VERIFIER)
 
-               case JAVA_ALOAD_0:
-               case JAVA_ALOAD_1:
-               case JAVA_ALOAD_2:
-               case JAVA_ALOAD_3:
-                       OP1LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0);
-                       break;
+throw_unexpected_end_of_bytecode:
+       exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
+       return false;
 
-                       /* storing stack values into local variables */
+throw_invalid_bytecode_index:
+       exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
+       return false;
 
-               case JAVA_ISTORE:
-               case JAVA_FSTORE:
-               case JAVA_ASTORE:
-                       if (!iswide) {
-                               i = code_get_u1(p + 1,m);
-                       } 
-                       else {
-                               i = code_get_u2(p + 1,m);
-                               iswide = false;
-                               nextp = p + 3;
-                       }
-                       OP1STORE_ONEWORD(opcode, i);
-                       break;
+throw_illegal_local_variable_number:
+       exceptions_throw_verifyerror(m, "Illegal local variable number");
+       return false;
 
-               case JAVA_LSTORE:
-               case JAVA_DSTORE:
-                       if (!iswide) {
-                               i = code_get_u1(p + 1,m);
-                       } 
-                       else {
-                               i = code_get_u2(p + 1,m);
-                               iswide = false;
-                               nextp = p + 3;
-                       }
-                       OP1STORE_TWOWORD(opcode, i);
-                       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);
-                       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);
-                       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);
-                       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);
-                       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);
-                       break;
-
-               case JAVA_IINC:
-                       {
-                               int v;
-                               
-                               if (!iswide) {
-                                       i = code_get_u1(p + 1,m);
-                                       v = code_get_s1(p + 2,m);
-
-                               } 
-                               else {
-                                       i = code_get_u2(p + 1,m);
-                                       v = code_get_s2(p + 3,m);
-                                       iswide = false;
-                                       nextp = p + 5;
-                               }
-                               INDEX_ONEWORD(i);
-                               OP2I(opcode, i, v);
-                       }
-                       break;
-
-                       /* wider index for loading, storing and incrementing */
-
-               case JAVA_WIDE:
-                       iswide = true;
-                       p++;
-                       goto fetch_opcode;
-
-               /* managing arrays ****************************************************/
-
-               case JAVA_NEWARRAY:
-                       switch (code_get_s1(p + 1, m)) {
-                       case 4:
-                               bte = builtintable_get_internal(BUILTIN_newarray_boolean);
-                               break;
-                       case 5:
-                               bte = builtintable_get_internal(BUILTIN_newarray_char);
-                               break;
-                       case 6:
-                               bte = builtintable_get_internal(BUILTIN_newarray_float);
-                               break;
-                       case 7:
-                               bte = builtintable_get_internal(BUILTIN_newarray_double);
-                               break;
-                       case 8:
-                               bte = builtintable_get_internal(BUILTIN_newarray_byte);
-                               break;
-                       case 9:
-                               bte = builtintable_get_internal(BUILTIN_newarray_short);
-                               break;
-                       case 10:
-                               bte = builtintable_get_internal(BUILTIN_newarray_int);
-                               break;
-                       case 11:
-                               bte = builtintable_get_internal(BUILTIN_newarray_long);
-                               break;
-#if defined(ENABLE_VERIFIER)
-                       default:
-                               *exceptionptr = new_verifyerror(m,
-                                               "Invalid array-type to create");
-                               return false;
-#endif
-                       }
-                       BUILTIN(bte, true, NULL, currentline);
-                       break;
-
-               case JAVA_ANEWARRAY:
-                       i = code_get_u2(p + 1, m);
-                       compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
-                       if (!compr)
-                               return false;
-
-                       if (!(cr = class_get_classref_multiarray_of(1, compr)))
-                               return false;
-
-                       if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
-                               return false;
-
-                       LOADCONST_A_BUILTIN(c, cr);
-                       bte = builtintable_get_internal(BUILTIN_newarray);
-                       BUILTIN(bte, true, NULL, currentline);
-                       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);
-                       }
-                       break;
-
-               case JAVA_IFEQ:
-               case JAVA_IFLT:
-               case JAVA_IFLE:
-               case JAVA_IFNE:
-               case JAVA_IFGT:
-               case JAVA_IFGE:
-               case JAVA_IFNULL:
-               case JAVA_IFNONNULL:
-               case JAVA_IF_ICMPEQ:
-               case JAVA_IF_ICMPNE:
-               case JAVA_IF_ICMPLT:
-               case JAVA_IF_ICMPGT:
-               case JAVA_IF_ICMPLE:
-               case JAVA_IF_ICMPGE:
-               case JAVA_IF_ACMPEQ:
-               case JAVA_IF_ACMPNE:
-               case JAVA_GOTO:
-               case JAVA_JSR:
-                       i = p + code_get_s2(p + 1,m);
-                       CHECK_BYTECODE_INDEX(i);
-                       block_insert(i);
-                       blockend = true;
-                       OP1(opcode, i);
-                       break;
-
-               case JAVA_GOTO_W:
-               case JAVA_JSR_W:
-                       i = p + code_get_s4(p + 1,m);
-                       CHECK_BYTECODE_INDEX(i);
-                       block_insert(i);
-                       blockend = true;
-                       OP1(opcode, i);
-                       break;
-
-               case JAVA_RET:
-                       if (!iswide) {
-                               i = code_get_u1(p + 1,m);
-                       } 
-                       else {
-                               i = code_get_u2(p + 1,m);
-                               nextp = p + 3;
-                               iswide = false;
-                       }
-                       blockend = true;
-                               
-                       OP1LOAD_ONEWORD(opcode, i);
-                       break;
-
-               case JAVA_IRETURN:
-               case JAVA_LRETURN:
-               case JAVA_FRETURN:
-               case JAVA_DRETURN:
-               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;
-                       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;
-                       OP(opcode);
-                       break;
-                               
-
-               /* table jumps ********************************************************/
-
-               case JAVA_LOOKUPSWITCH:
-                       {
-                               s4 num, j;
-                               s4 *tablep;
-#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);
-
-                               /* default target */
-
-                               j =  p + code_get_s4(nextp, m);
-                               *tablep = j;     /* restore for little endian */
-                               tablep++;
-                               nextp += 4;
-                               CHECK_BYTECODE_INDEX(j);
-                               block_insert(j);
-
-                               /* number of pairs */
-
-                               num = code_get_u4(nextp, m);
-                               *tablep = num;
-                               tablep++;
-                               nextp += 4;
-
-                               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++;
-                                       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");
-                                               return false;
-                                       }
-                                       prevvalue = j;
-#endif
-
-                                       /* target */
-
-                                       j = p + code_get_s4(nextp,m);
-                                       *tablep = j; /* restore for little endian */
-                                       tablep++;
-                                       nextp += 4;
-                                       CHECK_BYTECODE_INDEX(j);
-                                       block_insert(j);
-                               }
-
-                               break;
-                       }
-
-
-               case JAVA_TABLESWITCH:
-                       {
-                               s4 num, j;
-                               s4 *tablep;
-
-                               blockend = true;
-                               nextp = ALIGN((p + 1), 4);
-
-                               CHECK_END_OF_BYTECODE(nextp + 12);
-
-                               tablep = (s4 *) (m->jcode + nextp);
-
-                               OP2A(opcode, 0, tablep, currentline);
-
-                               /* default target */
-
-                               j = p + code_get_s4(nextp, m);
-                               *tablep = j;     /* restore for little endian */
-                               tablep++;
-                               nextp += 4;
-                               CHECK_BYTECODE_INDEX(j);
-                               block_insert(j);
-
-                               /* lower bound */
-
-                               j = code_get_s4(nextp, m);
-                               *tablep = j;     /* restore for little endian */
-                               tablep++;
-                               nextp += 4;
-
-                               /* upper bound */
-
-                               num = code_get_s4(nextp, m);
-                               *tablep = num;   /* restore for little endian */
-                               tablep++;
-                               nextp += 4;
-
-                               num -= j;  /* difference of upper - lower */
-
-#if defined(ENABLE_VERIFIER)
-                               if (num < 0) {
-                                       *exceptionptr = new_verifyerror(m,
-                                                       "invalid TABLESWITCH: upper bound < lower bound");
-                                       return false;
-                               }
-#endif
-
-                               CHECK_END_OF_BYTECODE(nextp + 4 * (num + 1));
-
-                               for (i = 0; i <= num; i++) {
-                                       j = p + code_get_s4(nextp,m);
-                                       *tablep = j; /* restore for little endian */
-                                       tablep++;
-                                       nextp += 4;
-                                       CHECK_BYTECODE_INDEX(j);
-                                       block_insert(j);
-                               }
-
-                               break;
-                       }
-
-
-               /* load and store of object fields ************************************/
-
-               case JAVA_AASTORE:
-                       OP(opcode);
-                       m->isleafmethod = false;
-                       break;
-
-               case JAVA_GETSTATIC:
-               case JAVA_PUTSTATIC:
-               case JAVA_GETFIELD:
-               case JAVA_PUTFIELD:
-                       {
-                               constant_FMIref  *fr;
-                               unresolved_field *uf;
-
-                               i = code_get_u2(p + 1, m);
-                               fr = class_getconstant(m->class, i,
-                                                                          CONSTANT_Fieldref);
-                               if (!fr)
-                                       return false;
-
-                               OP2A_NOINC(opcode, fr->parseddesc.fd->type, fr, currentline);
-
-                               /* only with -noverify, otherwise the typechecker does this */
-
-#if defined(ENABLE_VERIFIER)
-                               if (!opt_verify) {
-#endif
-                                       result = resolve_field_lazy(iptr,NULL,m);
-                                       if (result == resolveFailed)
-                                               return false;
-
-                                       if (result != resolveSucceeded) {
-                                               uf = create_unresolved_field(m->class,
-                                                                                                        m, iptr);
-
-                                               if (!uf)
-                                                       return false;
-
-                                               /* store the unresolved_field pointer */
-
-                                               /* XXX this will be changed */
-                                               iptr->val.a = uf;
-                                               iptr->target = (void*) 0x01; /* XXX target temporarily used as flag */
-                                       }
-                                       else {
-                                               iptr->target = NULL;
-                                       }
-#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)
-                               return false;
-
-                       md = mr->parseddesc.md;
-
-                       if (!md->params)
-                               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);
-
-                       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);
-
-invoke_nonstatic_method:
-                       if (!mr)
-                               return false;
-
-                       md = mr->parseddesc.md;
-
-                       if (!md->params)
-                               if (!descriptor_params_from_paramtypes(md, 0))
-                                       return false;
-
-invoke_method:
-                       m->isleafmethod = false;
-
-                       OP2A_NOINC(opcode, 0, mr, currentline);
-
-                       /* only with -noverify, otherwise the typechecker does this */
-
-#if defined(ENABLE_VERIFIER)
-                       if (!opt_verify) {
-#endif
-                               result = resolve_method_lazy(iptr,NULL,m);
-                               if (result == resolveFailed)
-                                       return false;
-
-                               if (result != resolveSucceeded) {
-                                       um = create_unresolved_method(m->class,
-                                                       m, iptr);
-
-                                       if (!um)
-                                               return false;
-
-                                       /* store the unresolved_method pointer */
-
-                                       /* XXX this will be changed */
-                                       iptr->val.a = um;
-                                       iptr->target = (void*) 0x01; /* XXX target temporarily used as flag */
-                               }
-                               else {
-                                       /* the method could be resolved */
-                                       iptr->target = NULL;
-                               }
-#if defined(ENABLE_VERIFIER)
-                       }
-                       else {
-                               iptr->target = NULL;
-                       }
-#endif
-                       PINC;
-                       break;
-
-               /* miscellaneous object operations ************************************/
-
-               case JAVA_NEW:
-                       i = code_get_u2(p + 1, 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;
-
-                       LOADCONST_A_BUILTIN(c, cr);
-                       bte = builtintable_get_internal(BUILTIN_new);
-                       BUILTIN(bte, true, NULL, currentline);
-                       s_count++;
-                       break;
-
-               case JAVA_CHECKCAST:
-                       i = code_get_u2(p + 1, 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 (cr->name->text[0] == '[') {
-                               /* array type cast-check */
-                               OP2AT(opcode, 0, c, cr, currentline);
-                               m->isleafmethod = false;
-
-                       } 
-                       else {
-                               /* object type cast-check */
-                               OP2AT(opcode, 1, c, cr, currentline);
-                       }
-                       break;
-
-               case JAVA_INSTANCEOF:
-                       i = code_get_u2(p + 1,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 (cr->name->text[0] == '[') {
-                               /* array type cast-check */
-                               LOADCONST_A_BUILTIN(c, cr);
-                               bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
-                               BUILTIN(bte, false, NULL, currentline);
-                               s_count++;
-
-                       } 
-                       else {
-                               /* object type cast-check */
-                               OP2AT(opcode, 1, c, cr, currentline);
-                       }
-                       break;
-
-               case JAVA_MONITORENTER:
-#if defined(ENABLE_THREADS)
-                       if (checksync) {
-                               OP(ICMD_CHECKNULL);
-                               bte = builtintable_get_internal(BUILTIN_monitorenter);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } 
-                       else
-#endif
-                               {
-                                       OP(ICMD_CHECKNULL);
-                                       OP(ICMD_POP);
-                               }
-                       break;
-
-               case JAVA_MONITOREXIT:
-#if defined(ENABLE_THREADS)
-                       if (checksync) {
-                               bte = builtintable_get_internal(BUILTIN_monitorexit);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } 
-                       else
-#endif
-                               {
-                                       OP(ICMD_POP);
-                               }
-                       break;
-
-               /* any other basic operation ******************************************/
-
-               case JAVA_IDIV:
-#if !SUPPORT_DIVISION
-                       bte = builtintable_get_internal(BUILTIN_idiv);
-                       OP2A(opcode, bte->md->paramcount, bte, currentline);
-                       m->isleafmethod = false;
-#else
-                       OP(opcode);
-#endif
-                       break;
-
-               case JAVA_IREM:
-#if !SUPPORT_DIVISION
-                       bte = builtintable_get_internal(BUILTIN_irem);
-                       OP2A(opcode, bte->md->paramcount, bte, currentline);
-                       m->isleafmethod = false;
-#else
-                       OP(opcode);
-#endif
-                       break;
-
-               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;
-#else
-                       OP(opcode);
-#endif
-                       break;
-
-               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;
-#else
-                       OP(opcode);
-#endif
-                       break;
-
-               case JAVA_FREM:
-#if defined(__I386__)
-                       OP(opcode);
-#else
-                       bte = builtintable_get_internal(BUILTIN_frem);
-                       BUILTIN(bte, false, NULL, currentline);
-#endif
-                       break;
-
-               case JAVA_DREM:
-#if defined(__I386__)
-                       OP(opcode);
-#else
-                       bte = builtintable_get_internal(BUILTIN_drem);
-                       BUILTIN(bte, false, NULL, currentline);
-#endif
-                       break;
-
-               case JAVA_F2I:
-#if defined(__ALPHA__)
-                       if (!opt_noieee) {
-                               bte = builtintable_get_internal(BUILTIN_f2i);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } 
-                       else
-#endif
-                               {
-                                       OP(opcode);
-                               }
-                       break;
-
-               case JAVA_F2L:
-#if defined(__ALPHA__)
-                       if (!opt_noieee) {
-                               bte = builtintable_get_internal(BUILTIN_f2l);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } 
-                       else 
-#endif
-                               {
-                                       OP(opcode);
-                               }
-                       break;
-
-               case JAVA_D2I:
-#if defined(__ALPHA__)
-                       if (!opt_noieee) {
-                               bte = builtintable_get_internal(BUILTIN_d2i);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } 
-                       else
-#endif
-                               {
-                                       OP(opcode);
-                               }
-                       break;
-
-               case JAVA_D2L:
-#if defined(__ALPHA__)
-                       if (!opt_noieee) {
-                               bte = builtintable_get_internal(BUILTIN_d2l);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } 
-                       else
-#endif
-                               {
-                                       OP(opcode);
-                               }
-                       break;
-
-                       /* 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.");
-                       return false;
-
-               case 186: /* unused opcode */
-               case 203:
-               case 204:
-               case 205:
-               case 206:
-               case 207:
-               case 208:
-               case 209:
-               case 210:
-               case 211:
-               case 212:
-               case 213:
-               case 214:
-               case 215:
-               case 216:
-               case 217:
-               case 218:
-               case 219:
-               case 220:
-               case 221:
-               case 222:
-               case 223:
-               case 224:
-               case 225:
-               case 226:
-               case 227:
-               case 228:
-               case 229:
-               case 230:
-               case 231:
-               case 232:
-               case 233:
-               case 234:
-               case 235:
-               case 236:
-               case 237:
-               case 238:
-               case 239:
-               case 240:
-               case 241:
-               case 242:
-               case 243:
-               case 244:
-               case 245:
-               case 246:
-               case 247:
-               case 248:
-               case 249:
-               case 250:
-               case 251:
-               case 252:
-               case 253:
-               case 254:
-               case 255:
-                       *exceptionptr =
-                               new_verifyerror(m,"Illegal opcode %d at instr %d\n",
-                                                                 opcode, ipc);
-                       return false;
-                       break;
-#endif /* defined(ENABLE_VERIFIER) */
-
-               default:
-                       /* straight-forward translation to ICMD */
-                       OP(opcode);
-                       break;
-                               
-               } /* end switch */
-
-#if defined(ENABLE_VERIFIER)
-               /* If WIDE was used correctly, iswide should have been reset by now. */
-               if (iswide) {
-                       *exceptionptr = new_verifyerror(m,
-                                       "Illegal instruction: WIDE before incompatible opcode");
-                       return false;
-               }
-#endif /* defined(ENABLE_VERIFIER) */
-
-       } /* end for */
-
-#if defined(ENABLE_VERIFIER)
-       if (p != m->jcodelength) {
-               *exceptionptr = new_verifyerror(m,
-                               "Command-sequence crosses code-boundary");
-               return false;
-       }
-
-       if (!blockend) {
-               *exceptionptr = new_verifyerror(m, "Falling off the end of the code");
-               return false;
-       }
-#endif /* defined(ENABLE_VERIFIER) */
-
-       /* adjust block count if target 0 is not first intermediate instruction */
-
-       if (!m->basicblockindex[0] || (m->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;
-
-       /* allocate stack table */
-
-       m->stack = DMNEW(stackelement, m->stackcount);
-
-       {
-               basicblock *bptr;
-
-               bptr = m->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 */
-
-               if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1)) {
-                       BASICBLOCK_INIT(bptr,m);
-
-                       bptr->iinstr = m->instructions;
-                       /* bptr->icount is set when the next block is allocated */
-
-                       bptr++;
-                       b_count++;
-                       bptr[-1].next = bptr;
-               }
-
-               /* allocate blocks */
-
-               for (p = 0; p < m->jcodelength; p++) { 
-                       if (m->basicblockindex[p] & 1) {
-                               /* Check if this block starts at the beginning of an          */
-                               /* instruction.                                               */
-#if defined(ENABLE_VERIFIER)
-                               if (!instructionstart[p]) {
-                                       *exceptionptr = new_verifyerror(m,
-                                               "Branch into middle of instruction");
-                                       return false;
-                               }
-#endif
-
-                               /* allocate the block */
-
-                               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 */
-
-                               m->basicblockindex[p] = b_count;
-
-                               bptr++;
-                               b_count++;
-                               bptr[-1].next = bptr;
-                       }
-               }
-
-               /* set instruction count of last real block */
-
-               if (b_count) {
-                       bptr[-1].icount = (m->instructions + m->instructioncount) - bptr[-1].iinstr;
-               }
-
-               /* 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;
-
-               /* set basicblock pointers in exception table */
-
-               if (cd->exceptiontablelength > 0) {
-                       cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
-               }
-               
-               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]);
-
-                       p = cd->exceptiontable[i].handlerpc;
-                       cd->exceptiontable[i].handler = m->basicblocks + m->basicblockindex[p];
-           }
-
-               /* 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];
-
-                       p = m->exceptiontable[i].endpc;
-                       m->exceptiontable[i].end = (p == m->jcodelength) ? (m->basicblocks + m->basicblockcount /*+ 1*/) : (m->basicblocks + m->basicblockindex[p]);
-
-                       p = m->exceptiontable[i].handlerpc;
-                       m->exceptiontable[i].handler = m->basicblocks + m->basicblockindex[p];
-           }
-#endif
-
-       }
-
-       /* everything's ok */
-
-       return true;
-
-#if defined(ENABLE_VERIFIER)
-
-throw_unexpected_end_of_bytecode:
-       *exceptionptr = new_verifyerror(m, "Unexpected end of bytecode");
-       return false;
-
-throw_invalid_bytecode_index:
-       *exceptionptr =
-               new_verifyerror(m, "Illegal target of branch instruction");
-       return false;
-
-throw_illegal_local_variable_number:
-       *exceptionptr =
-               new_verifyerror(m, "Illegal local variable number");
-       return false;
-               
 #endif /* ENABLE_VERIFIER */
 }