* src/mm/boehm-gc/include/private/gcconfig.h: Patch for mips to find
[cacao.git] / src / vm / jit / parse.c
index 031eae696f2af8a8e6aefec7460674390d9a3215..7b1c1ace3c5921576192acead6f21095936974d8 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/parse.c - parser for JavaVM to intermediate code translation
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
-   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-   J. Wenninger, Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Author: Andreas Krall
-
-   Changes: Carolyn Oates
-            Edwin Steiner
-            Joseph Wenninger
-            Christian Thalinger
-
-   $Id: parse.c 5366 2006-09-06 11:01:11Z edwin $
-
 */
 
 
 #include "vm/types.h"
 
 #include "mm/memory.h"
-#include "native/native.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#endif
+#include "native/native.hpp"
+
+#include "threads/lock.hpp"
 
 #include "toolbox/logging.h"
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
+
+#include "vm/jit/builtin.hpp"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/linker.h"
-#include "vm/loader.h"
-#include "vm/resolve.h"
+#include "vm/loader.hpp"
 #include "vm/options.h"
-#include "vm/statistics.h"
-#include "vm/stringlocal.h"
-#include "vm/suck.h"
+#include "vm/resolve.hpp"
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+#include "vm/string.hpp"
+#include "vm/suck.hpp"
+
 #include "vm/jit/asmpart.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
 #include "vm/jit/parse.h"
-#include "vm/jit/patcher.h"
 #include "vm/jit/loop/loop.h"
 
-/*******************************************************************************
+#include "vm/jit/ir/bytecode.h"
 
-       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.
+#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 exceptiontable * new_fillextable(
-                                                                       jitdata *jd,
-                                                                       methodinfo *m, 
-                                                                       exceptiontable *extable, 
-                                                                       exceptiontable *raw_extable, 
-                                                               int exceptiontablelength, 
-                                                                       int *block_count)
+static basicblock *parse_bytecodeindex_to_basicblock(jitdata *jd,
+                                                                                                        parsedata_t *pd,
+                                                                                                        s4 bcindex)
 {
-       int b_count, p, src;
+       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 bool parse_mark_exception_boundaries(jitdata *jd, parsedata_t *pd)
+{
+       s4                   bcindex;
+       s4                   i;
+       s4                   len;
+       raw_exception_entry *rex;
+       methodinfo          *m;
+
+       m = jd->m;
        
-       if (exceptiontablelength == 0) 
-               return extable;
+       len = m->rawexceptiontablelength;
+
+       if (len == 0)
+               return true;
+
+       rex = m->rawexceptiontable;
 
-       b_count = *block_count;
+       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;
-               MARK_BASICBLOCK(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) {
-                       exceptions_throw_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) 
-                       MARK_BASICBLOCK(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;
-               MARK_BASICBLOCK(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:
        exceptions_throw_verifyerror(m,
                                                                 "Illegal bytecode index in exception table");
-       return NULL;
+       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)
@@ -156,29 +368,35 @@ 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                      */
+       methodinfo  *m;                     /* method being parsed                */
        codeinfo    *code;
-       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  */
+       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;
@@ -186,59 +404,50 @@ bool new_parse(jitdata *jd)
        u4                  flags;
        basicblock         *bptr;
 
-#if defined(NEW_VAR)
-       int                *local_map; /* local pointer to renaming structore     */
+       int                *local_map; /* local pointer to renaming map           */
                                       /* is assigned to rd->local_map at the end */
-#endif
+       branch_target_t *table;
+       lookup_target_t *lookup;
+       s4               i;
+       s4               j;
+
        /* get required compiler data */
 
        m    = jd->m;
        code = jd->code;
-       cd   = jd->cd;
 
-#if defined(NEW_VAR)
        /* allocate buffers for local variable renaming */
-       local_map = DMNEW(int, cd->maxlocals * 5);
-       for (i = 0; i < cd->maxlocals; i++) {
+
+       local_map = DMNEW(int, m->maxlocals * 5);
+
+       for (i = 0; i < m->maxlocals; i++) {
                local_map[i * 5 + 0] = 0;
                local_map[i * 5 + 1] = 0;
                local_map[i * 5 + 2] = 0;
                local_map[i * 5 + 3] = 0;
                local_map[i * 5 + 4] = 0;
        }
-#endif
 
-       /* allocate instruction array and block index table */
-
-       /* 1 additional for end ipc  */
-       jd->new_basicblockindex = DMNEW(s4, m->jcodelength + 1);
-       memset(jd->new_basicblockindex, 0, sizeof(s4) * (m->jcodelength + 1));
-
-       instructionstart = DMNEW(u1, m->jcodelength + 1);
-       memset(instructionstart, 0, sizeof(u1) * (m->jcodelength + 1));
-
-       /* IMPORTANT: We assume that parsing creates at most one instruction per */
-       /*            byte of original bytecode!                                 */
-
-       iptr = jd->new_instructions = DMNEW(instruction, m->jcodelength);
-
-       /* compute branch targets of exception table */
-
-       if (!new_fillextable(jd, 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))
-               jd->isleafmethod = false;
-#endif
+       s_count = 1 + m->rawexceptiontablelength;
 
        /* setup line number info */
 
@@ -254,117 +463,140 @@ 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 */
 
                /* XXX rewrite this using pointer arithmetic */
 
-               if (linepcchange == p) {
+               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 = SUCK_BE_U1(m->jcode + p);
+               /* fetch next opcode  */        
 
-               /* store intermediate instruction count (bit 0 mark block starts) */
+               opcode = SUCK_BE_U1(m->jcode + bcindex);
 
-               jd->new_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 BC_nop after a blockend
+                  instruction. */
 
-               if (blockend && (opcode != JAVA_NOP)) {
-                       /* start new block */
-
-                       MARK_BASICBLOCK(p);
+               if (blockend && (opcode != BC_nop)) {
+                       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 + bytecode[opcode].length;
 
-               CHECK_END_OF_BYTECODE(nextp);
+               CHECK_END_OF_BYTECODE(nextbc);
 
                /* add stack elements produced by this instruction */
 
-               s_count += stackreq[opcode];
+               s_count += bytecode[opcode].slots;
 
-               /* 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:
+               case BC_nop:
                        break;
 
                /* pushing constants onto the stack ***********************************/
 
-               case JAVA_BIPUSH:
-                       OP_LOADCONST_I(SUCK_BE_S1(m->jcode + p + 1));
+               case BC_bipush:
+                       OP_LOADCONST_I(SUCK_BE_S1(m->jcode + bcindex + 1));
                        break;
 
-               case JAVA_SIPUSH:
-                       OP_LOADCONST_I(SUCK_BE_S2(m->jcode + p + 1));
+               case BC_sipush:
+                       OP_LOADCONST_I(SUCK_BE_S2(m->jcode + bcindex + 1));
                        break;
 
-               case JAVA_LDC1:
-                       i = SUCK_BE_U1(m->jcode + p + 1);
+               case BC_ldc1:
+                       i = SUCK_BE_U1(m->jcode + bcindex + 1);
                        goto pushconstantitem;
 
-               case JAVA_LDC2:
-               case JAVA_LDC2W:
-                       i = SUCK_BE_U2(m->jcode + p + 1);
+               case BC_ldc2:
+               case BC_ldc2w:
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
 
                pushconstantitem:
 
 #if defined(ENABLE_VERIFIER)
-                       if (i >= m->class->cpcount) {
+                       if (i >= m->clazz->cpcount) {
                                exceptions_throw_verifyerror(m,
                                        "Attempt to access constant outside range");
                                return false;
                        }
 #endif
 
-                       switch (m->class->cptags[i]) {
+                       switch (m->clazz->cptags[i]) {
                        case CONSTANT_Integer:
-                               OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_I(((constant_integer *) (m->clazz->cpinfos[i]))->value);
                                break;
                        case CONSTANT_Long:
-                               OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_L(((constant_long *) (m->clazz->cpinfos[i]))->value);
                                break;
                        case CONSTANT_Float:
-                               OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_F(((constant_float *) (m->clazz->cpinfos[i]))->value);
                                break;
                        case CONSTANT_Double:
-                               OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_D(((constant_double *) (m->clazz->cpinfos[i]))->value);
                                break;
                        case CONSTANT_String:
-                               OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
+                               OP_LOADCONST_STRING(literalstring_new((utf *) (m->clazz->cpinfos[i])));
                                break;
                        case CONSTANT_Class:
-                               cr = (constant_classref *) (m->class->cpinfos[i]);
+                               cr = (constant_classref *) (m->clazz->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 */
 
-                               OP_LOADCONST_CLASSINFO_OR_CLASSREF(c, cr, 0 /* no extra flags */);
+                               OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr);
 
                                break;
 
@@ -377,176 +609,236 @@ fetch_opcode:
                        }
                        break;
 
-               case JAVA_ACONST_NULL:
+               case BC_aconst_null:
                        OP_LOADCONST_NULL();
                        break;
 
-               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:
-                       OP_LOADCONST_I(opcode - JAVA_ICONST_0);
+               case BC_iconst_m1:
+               case BC_iconst_0:
+               case BC_iconst_1:
+               case BC_iconst_2:
+               case BC_iconst_3:
+               case BC_iconst_4:
+               case BC_iconst_5:
+                       OP_LOADCONST_I(opcode - BC_iconst_0);
+                       break;
+
+               case BC_lconst_0:
+               case BC_lconst_1:
+                       OP_LOADCONST_L(opcode - BC_lconst_0);
                        break;
 
-               case JAVA_LCONST_0:
-               case JAVA_LCONST_1:
-                       OP_LOADCONST_L(opcode - JAVA_LCONST_0);
+               case BC_fconst_0:
+               case BC_fconst_1:
+               case BC_fconst_2:
+                       OP_LOADCONST_F(opcode - BC_fconst_0);
                        break;
 
-               case JAVA_FCONST_0:
-               case JAVA_FCONST_1:
-               case JAVA_FCONST_2:
-                       OP_LOADCONST_F(opcode - JAVA_FCONST_0);
+               case BC_dconst_0:
+               case BC_dconst_1:
+                       OP_LOADCONST_D(opcode - BC_dconst_0);
                        break;
 
-               case JAVA_DCONST_0:
-               case JAVA_DCONST_1:
-                       OP_LOADCONST_D(opcode - JAVA_DCONST_0);
+               /* stack operations ***************************************************/
+
+               /* We need space for additional instruction so we can
+                  translate these instructions to sequences of ICMD_COPY and
+                  ICMD_MOVE instructions. */
+
+               case BC_dup_x1:
+                       INSTRUCTIONS_CHECK(4);
+                       OP(opcode);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       break;
+
+               case BC_dup_x2:
+                       INSTRUCTIONS_CHECK(6);
+                       OP(opcode);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
+                       break;
+
+               case BC_dup2:
+                       INSTRUCTIONS_CHECK(2);
+                       OP(opcode);
+                       OP(ICMD_NOP);
+                       break;
+
+               case BC_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 BC_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 BC_swap:
+                       INSTRUCTIONS_CHECK(3);
+                       OP(opcode);
+                       OP(ICMD_NOP);
+                       OP(ICMD_NOP);
                        break;
 
                /* local variable access instructions *********************************/
 
-               case JAVA_ILOAD:
-               case JAVA_FLOAD:
-               case JAVA_ALOAD:
+               case BC_iload:
+               case BC_fload:
+               case BC_aload:
                        if (iswide == false) {
-                               i = SUCK_BE_U1(m->jcode + p + 1);
+                               i = SUCK_BE_U1(m->jcode + bcindex + 1);
                        }
                        else {
-                               i = SUCK_BE_U2(m->jcode + p + 1);
-                               nextp = p + 3;
+                               i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                               nextbc = bcindex + 3;
                                iswide = false;
                        }
-                       OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
+                       OP_LOAD_ONEWORD(opcode, i, opcode - BC_iload);
                        break;
 
-               case JAVA_LLOAD:
-               case JAVA_DLOAD:
+               case BC_lload:
+               case BC_dload:
                        if (iswide == false) {
-                               i = SUCK_BE_U1(m->jcode + p + 1);
+                               i = SUCK_BE_U1(m->jcode + bcindex + 1);
                        }
                        else {
-                               i = SUCK_BE_U2(m->jcode + p + 1);
-                               nextp = p + 3;
+                               i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                               nextbc = bcindex + 3;
                                iswide = false;
                        }
-                       OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
+                       OP_LOAD_TWOWORD(opcode, i, opcode - BC_iload);
                        break;
 
-               case JAVA_ILOAD_0:
-               case JAVA_ILOAD_1:
-               case JAVA_ILOAD_2:
-               case JAVA_ILOAD_3:
-                       OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
+               case BC_iload_0:
+               case BC_iload_1:
+               case BC_iload_2:
+               case BC_iload_3:
+                       OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - BC_iload_0, TYPE_INT);
                        break;
 
-               case JAVA_LLOAD_0:
-               case JAVA_LLOAD_1:
-               case JAVA_LLOAD_2:
-               case JAVA_LLOAD_3:
-                       OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
+               case BC_lload_0:
+               case BC_lload_1:
+               case BC_lload_2:
+               case BC_lload_3:
+                       OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - BC_lload_0, TYPE_LNG);
                        break;
 
-               case JAVA_FLOAD_0:
-               case JAVA_FLOAD_1:
-               case JAVA_FLOAD_2:
-               case JAVA_FLOAD_3:
-                       OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
+               case BC_fload_0:
+               case BC_fload_1:
+               case BC_fload_2:
+               case BC_fload_3:
+                       OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - BC_fload_0, TYPE_FLT);
                        break;
 
-               case JAVA_DLOAD_0:
-               case JAVA_DLOAD_1:
-               case JAVA_DLOAD_2:
-               case JAVA_DLOAD_3:
-                       OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
+               case BC_dload_0:
+               case BC_dload_1:
+               case BC_dload_2:
+               case BC_dload_3:
+                       OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - BC_dload_0, TYPE_DBL);
                        break;
 
-               case JAVA_ALOAD_0:
-               case JAVA_ALOAD_1:
-               case JAVA_ALOAD_2:
-               case JAVA_ALOAD_3:
-                       OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
+               case BC_aload_0:
+               case BC_aload_1:
+               case BC_aload_2:
+               case BC_aload_3:
+                       OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - BC_aload_0, TYPE_ADR);
                        break;
 
-               case JAVA_ISTORE:
-               case JAVA_FSTORE:
-               case JAVA_ASTORE:
+               case BC_istore:
+               case BC_fstore:
+               case BC_astore:
                        if (iswide == false) {
-                               i = SUCK_BE_U1(m->jcode + p + 1);
+                               i = SUCK_BE_U1(m->jcode + bcindex + 1);
                        }
                        else {
-                               i = SUCK_BE_U2(m->jcode + p + 1);
+                               i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                               nextbc = bcindex + 3;
                                iswide = false;
-                               nextp = p + 3;
                        }
-                       OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
+                       OP_STORE_ONEWORD(opcode, i, opcode - BC_istore);
                        break;
 
-               case JAVA_LSTORE:
-               case JAVA_DSTORE:
+               case BC_lstore:
+               case BC_dstore:
                        if (iswide == false) {
-                               i = SUCK_BE_U1(m->jcode + p + 1);
+                               i = SUCK_BE_U1(m->jcode + bcindex + 1);
                        }
                        else {
-                               i = SUCK_BE_U2(m->jcode + p + 1);
+                               i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                               nextbc = bcindex + 3;
                                iswide = false;
-                               nextp = p + 3;
                        }
-                       OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
+                       OP_STORE_TWOWORD(opcode, i, opcode - BC_istore);
                        break;
 
-               case JAVA_ISTORE_0:
-               case JAVA_ISTORE_1:
-               case JAVA_ISTORE_2:
-               case JAVA_ISTORE_3:
-                       OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
+               case BC_istore_0:
+               case BC_istore_1:
+               case BC_istore_2:
+               case BC_istore_3:
+                       OP_STORE_ONEWORD(ICMD_ISTORE, opcode - BC_istore_0, TYPE_INT);
                        break;
 
-               case JAVA_LSTORE_0:
-               case JAVA_LSTORE_1:
-               case JAVA_LSTORE_2:
-               case JAVA_LSTORE_3:
-                       OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
+               case BC_lstore_0:
+               case BC_lstore_1:
+               case BC_lstore_2:
+               case BC_lstore_3:
+                       OP_STORE_TWOWORD(ICMD_LSTORE, opcode - BC_lstore_0, TYPE_LNG);
                        break;
 
-               case JAVA_FSTORE_0:
-               case JAVA_FSTORE_1:
-               case JAVA_FSTORE_2:
-               case JAVA_FSTORE_3:
-                       OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
+               case BC_fstore_0:
+               case BC_fstore_1:
+               case BC_fstore_2:
+               case BC_fstore_3:
+                       OP_STORE_ONEWORD(ICMD_FSTORE, opcode - BC_fstore_0, TYPE_FLT);
                        break;
 
-               case JAVA_DSTORE_0:
-               case JAVA_DSTORE_1:
-               case JAVA_DSTORE_2:
-               case JAVA_DSTORE_3:
-                       OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
+               case BC_dstore_0:
+               case BC_dstore_1:
+               case BC_dstore_2:
+               case BC_dstore_3:
+                       OP_STORE_TWOWORD(ICMD_DSTORE, opcode - BC_dstore_0, TYPE_DBL);
                        break;
 
-               case JAVA_ASTORE_0:
-               case JAVA_ASTORE_1:
-               case JAVA_ASTORE_2:
-               case JAVA_ASTORE_3:
-                       OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0, TYPE_ADR);
+               case BC_astore_0:
+               case BC_astore_1:
+               case BC_astore_2:
+               case BC_astore_3:
+                       OP_STORE_ONEWORD(ICMD_ASTORE, opcode - BC_astore_0, TYPE_ADR);
                        break;
 
-               case JAVA_IINC:
+               case BC_iinc:
                        {
                                int v;
 
                                if (iswide == false) {
-                                       i = SUCK_BE_U1(m->jcode + p + 1);
-                                       v = SUCK_BE_S1(m->jcode + p + 2);
-
+                                       i = SUCK_BE_U1(m->jcode + bcindex + 1);
+                                       v = SUCK_BE_S1(m->jcode + bcindex + 2);
                                }
                                else {
-                                       i = SUCK_BE_U2(m->jcode + p + 1);
-                                       v = SUCK_BE_S2(m->jcode + p + 3);
+                                       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);
                                LOCALTYPE_USED(i, TYPE_INT);
@@ -556,15 +848,15 @@ fetch_opcode:
 
                /* wider index for loading, storing and incrementing ******************/
 
-               case JAVA_WIDE:
+               case BC_wide:
+                       bcindex++;
                        iswide = true;
-                       p++;
                        goto fetch_opcode;
 
                /* managing arrays ****************************************************/
 
-               case JAVA_NEWARRAY:
-                       switch (SUCK_BE_S1(m->jcode + p + 1)) {
+               case BC_newarray:
+                       switch (SUCK_BE_S1(m->jcode + bcindex + 1)) {
                        case 4:
                                bte = builtintable_get_internal(BUILTIN_newarray_boolean);
                                break;
@@ -598,10 +890,10 @@ fetch_opcode:
                        OP_BUILTIN_CHECK_EXCEPTION(bte);
                        break;
 
-               case JAVA_ANEWARRAY:
-                       i = SUCK_BE_U2(m->jcode + p + 1);
-                       compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
-                       if (!compr)
+               case BC_anewarray:
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       compr = (constant_classref *) class_getconstant(m->clazz, i, CONSTANT_Class);
+                       if (compr == NULL)
                                return false;
 
                        if (!(cr = class_get_classref_multiarray_of(1, compr)))
@@ -610,88 +902,87 @@ fetch_opcode:
                        if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
                                return false;
 
-                       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);
                        OP_BUILTIN_CHECK_EXCEPTION(bte);
                        s_count++;
                        break;
 
-               case JAVA_MULTIANEWARRAY:
-                       jd->isleafmethod = false;
-                       i = SUCK_BE_U2(m->jcode + p + 1);
-                       {
-                               s4 v = SUCK_BE_U1(m->jcode + p + 3);
-
-                               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;
-                               OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags */);
-                       }
+               case BC_multianewarray:
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       j = SUCK_BE_U1(m->jcode + bcindex + 3);
+  
+                       cr = (constant_classref *) class_getconstant(m->clazz, 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);
+                       code_unflag_leafmethod(code);
                        break;
 
                /* control flow instructions ******************************************/
 
-               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:
-                       i = p + SUCK_BE_S2(m->jcode + p + 1);
+               case BC_ifeq:
+               case BC_iflt:
+               case BC_ifle:
+               case BC_ifne:
+               case BC_ifgt:
+               case BC_ifge:
+               case BC_ifnull:
+               case BC_ifnonnull:
+               case BC_if_icmpeq:
+               case BC_if_icmpne:
+               case BC_if_icmplt:
+               case BC_if_icmpgt:
+               case BC_if_icmple:
+               case BC_if_icmpge:
+               case BC_if_acmpeq:
+               case BC_if_acmpne:
+               case BC_goto:
+                       i = bcindex + SUCK_BE_S2(m->jcode + bcindex + 1);
                        CHECK_BYTECODE_INDEX(i);
-                       MARK_BASICBLOCK(i);
+                       MARK_BASICBLOCK(&pd, i);
                        blockend = true;
                        OP_INSINDEX(opcode, i);
                        break;
 
-               case JAVA_GOTO_W:
-                       i = p + SUCK_BE_S4(m->jcode + p + 1);
+               case BC_goto_w:
+                       i = bcindex + SUCK_BE_S4(m->jcode + bcindex + 1);
                        CHECK_BYTECODE_INDEX(i);
-                       MARK_BASICBLOCK(i);
+                       MARK_BASICBLOCK(&pd, i);
                        blockend = true;
-                       OP_INSINDEX(opcode, i);
+                       OP_INSINDEX(ICMD_GOTO, i);
                        break;
 
-               case JAVA_JSR:
-                       i = p + SUCK_BE_S2(m->jcode + p + 1);
+               case BC_jsr:
+                       i = bcindex + SUCK_BE_S2(m->jcode + bcindex + 1);
 jsr_tail:
                        CHECK_BYTECODE_INDEX(i);
-                       MARK_BASICBLOCK(i);
+                       MARK_BASICBLOCK(&pd, i);
                        blockend = true;
-                       OP_PREPARE_ZEROFLAGS(JAVA_JSR);
+                       OP_PREPARE_ZEROFLAGS(BC_jsr);
                        iptr->sx.s23.s3.jsrtarget.insindex = i;
                        PINC;
                        break;
 
-               case JAVA_JSR_W:
-                       i = p + SUCK_BE_S4(m->jcode + p + 1);
+               case BC_jsr_w:
+                       i = bcindex + SUCK_BE_S4(m->jcode + bcindex + 1);
                        goto jsr_tail;
 
-               case JAVA_RET:
+               case BC_ret:
                        if (iswide == false) {
-                               i = SUCK_BE_U1(m->jcode + p + 1);
+                               i = SUCK_BE_U1(m->jcode + bcindex + 1);
                        }
                        else {
-                               i = SUCK_BE_U2(m->jcode + p + 1);
-                               nextp = p + 3;
+                               i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                               nextbc = bcindex + 3;
                                iswide = false;
                        }
                        blockend = true;
@@ -699,18 +990,18 @@ jsr_tail:
                        OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
                        break;
 
-               case JAVA_IRETURN:
-               case JAVA_LRETURN:
-               case JAVA_FRETURN:
-               case JAVA_DRETURN:
-               case JAVA_ARETURN:
-               case JAVA_RETURN:
+               case BC_ireturn:
+               case BC_lreturn:
+               case BC_freturn:
+               case BC_dreturn:
+               case BC_areturn:
+               case BC_return:
                        blockend = true;
                        /* XXX ARETURN will need a flag in the typechecker */
                        OP(opcode);
                        break;
 
-               case JAVA_ATHROW:
+               case BC_athrow:
                        blockend = true;
                        /* XXX ATHROW will need a flag in the typechecker */
                        OP(opcode);
@@ -719,7 +1010,7 @@ jsr_tail:
 
                /* table jumps ********************************************************/
 
-               case JAVA_LOOKUPSWITCH:
+               case BC_lookupswitch:
                        {
                                s4 num, j;
                                lookup_target_t *lookup;
@@ -727,25 +1018,25 @@ jsr_tail:
                                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);
 
                                OP_PREPARE_ZEROFLAGS(opcode);
 
                                /* default target */
 
-                               j = p + SUCK_BE_S4(m->jcode + nextp);
+                               j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
                                iptr->sx.s23.s3.lookupdefault.insindex = j;
-                               nextp += 4;
+                               nextbc += 4;
                                CHECK_BYTECODE_INDEX(j);
-                               MARK_BASICBLOCK(j);
+                               MARK_BASICBLOCK(&pd, j);
 
                                /* number of pairs */
 
-                               num = SUCK_BE_U4(m->jcode + nextp);
+                               num = SUCK_BE_U4(m->jcode + nextbc);
                                iptr->sx.s23.s2.lookupcount = num;
-                               nextp += 4;
+                               nextbc += 4;
 
                                /* allocate the intermediate code table */
 
@@ -754,15 +1045,15 @@ jsr_tail:
 
                                /* 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 = SUCK_BE_S4(m->jcode + nextp);
+                                       j = SUCK_BE_S4(m->jcode + nextbc);
                                        lookup->value = j;
 
-                                       nextp += 4;
+                                       nextbc += 4;
 
 #if defined(ENABLE_VERIFIER)
                                        /* check if the lookup table is sorted correctly */
@@ -775,50 +1066,49 @@ jsr_tail:
 #endif
                                        /* target */
 
-                                       j = p + SUCK_BE_S4(m->jcode + nextp);
+                                       j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
                                        lookup->target.insindex = j;
                                        lookup++;
-                                       nextp += 4;
+                                       nextbc += 4;
                                        CHECK_BYTECODE_INDEX(j);
-                                       MARK_BASICBLOCK(j);
+                                       MARK_BASICBLOCK(&pd, j);
                                }
 
                                PINC;
                                break;
                        }
 
-
-               case JAVA_TABLESWITCH:
+               case BC_tableswitch:
                        {
                                s4 num, j;
                                s4 deftarget;
                                branch_target_t *table;
 
                                blockend = true;
-                               nextp = ALIGN((p + 1), 4);
+                               nextbc = MEMORY_ALIGN((bcindex + 1), 4);
 
-                               CHECK_END_OF_BYTECODE(nextp + 12);
+                               CHECK_END_OF_BYTECODE(nextbc + 12);
 
                                OP_PREPARE_ZEROFLAGS(opcode);
 
                                /* default target */
 
-                               deftarget = p + SUCK_BE_S4(m->jcode + nextp);
-                               nextp += 4;
+                               deftarget = bcindex + SUCK_BE_S4(m->jcode + nextbc);
+                               nextbc += 4;
                                CHECK_BYTECODE_INDEX(deftarget);
-                               MARK_BASICBLOCK(deftarget);
+                               MARK_BASICBLOCK(&pd, deftarget);
 
                                /* lower bound */
 
-                               j = SUCK_BE_S4(m->jcode + nextp);
+                               j = SUCK_BE_S4(m->jcode + nextbc);
                                iptr->sx.s23.s2.tablelow = j;
-                               nextp += 4;
+                               nextbc += 4;
 
                                /* upper bound */
 
-                               num = SUCK_BE_S4(m->jcode + nextp);
+                               num = SUCK_BE_S4(m->jcode + nextbc);
                                iptr->sx.s23.s3.tablehigh = num;
-                               nextp += 4;
+                               nextbc += 4;
 
                                /* calculate the number of table entries */
 
@@ -834,20 +1124,20 @@ jsr_tail:
                                /* 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 + SUCK_BE_S4(m->jcode + nextp);
+                                       j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
                                        (table++)->insindex = j;
-                                       nextp += 4;
+                                       nextbc += 4;
                                        CHECK_BYTECODE_INDEX(j);
-                                       MARK_BASICBLOCK(j);
+                                       MARK_BASICBLOCK(&pd, j);
                                }
 
                                PINC;
@@ -857,119 +1147,146 @@ jsr_tail:
 
                /* load and store of object fields ************************************/
 
-               case JAVA_AASTORE:
+               case BC_aastore:
                        OP(opcode);
-                       jd->isleafmethod = false;
+                       code_unflag_leafmethod(code);
                        break;
 
-               case JAVA_GETSTATIC:
-               case JAVA_PUTSTATIC:
-               case JAVA_GETFIELD:
-               case JAVA_PUTFIELD:
-                       {
-                               constant_FMIref  *fr;
-                               unresolved_field *uf;
+               case BC_getstatic:
+               case BC_putstatic:
+               case BC_getfield:
+               case BC_putfield:
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       fmi = class_getconstant(m->clazz, i, CONSTANT_Fieldref);
 
-                               i = SUCK_BE_U2(m->jcode + p + 1);
-                               fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
-                               if (!fr)
-                                       return false;
+                       if (fmi == NULL)
+                               return false;
 
-                               OP_PREPARE_ZEROFLAGS(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 (!JITDATA_HAS_FLAG_VERIFY(jd)) {
+                       if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
 #endif
-                                       result = new_resolve_field_lazy(iptr, m);
-                                       if (result == resolveFailed)
-                                               return false;
+                               result = resolve_field_lazy(m, fmi);
 
-                                       if (result != resolveSucceeded) {
-                                               uf = new_create_unresolved_field(m->class, m, iptr);
+                               if (result == resolveFailed)
+                                       return false;
 
-                                               if (uf == NULL)
-                                                       return false;
+                               if (result != resolveSucceeded) {
+                                       uf = resolve_create_unresolved_field(m->clazz, m, iptr);
 
-                                               /* store the unresolved_field pointer */
+                                       if (uf == NULL)
+                                               return false;
 
-                                               iptr->sx.s23.s3.uf = uf;
-                                               iptr->flags.bits = INS_FLAG_UNRESOLVED;
-                                       }
-#if defined(ENABLE_VERIFIER)
+                                       /* store the unresolved_field pointer */
+
+                                       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 = SUCK_BE_U2(m->jcode + p + 1);
-                       mr = class_getconstant(m->class, i, CONSTANT_Methodref);
-                       if (!mr)
+               case BC_invokestatic:
+                       OP_PREPARE_ZEROFLAGS(opcode);
+
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       fmi = class_getconstant(m->clazz, 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_INVOKEINTERFACE:
-                       i = SUCK_BE_U2(m->jcode + p + 1);
+               case BC_invokespecial:
+                       OP_PREPARE_FLAGS(opcode, INS_FLAG_CHECK);
 
-                       mr = class_getconstant(m->class, i,
-                                       CONSTANT_InterfaceMethodref);
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       fmi = class_getconstant(m->clazz, i, CONSTANT_Methodref);
 
                        goto invoke_nonstatic_method;
 
-               case JAVA_INVOKESPECIAL:
-               case JAVA_INVOKEVIRTUAL:
-                       i = SUCK_BE_U2(m->jcode + p + 1);
-                       mr = class_getconstant(m->class, i, CONSTANT_Methodref);
+               case BC_invokeinterface:
+                       OP_PREPARE_ZEROFLAGS(opcode);
+
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       fmi = class_getconstant(m->clazz, i, CONSTANT_InterfaceMethodref);
+
+                       goto invoke_nonstatic_method;
+
+               case BC_invokevirtual:
+                       OP_PREPARE_ZEROFLAGS(opcode);
+
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       fmi = class_getconstant(m->clazz, 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:
-                       jd->isleafmethod = false;
+                       code_unflag_leafmethod(code);
 
-                       OP_PREPARE_ZEROFLAGS(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 (!JITDATA_HAS_FLAG_VERIFY(jd)) {
 #endif
-                               result = new_resolve_method_lazy(iptr, m);
+                               result = resolve_method_lazy(m, fmi, 
+                                                                                        (opcode == BC_invokespecial));
+
                                if (result == resolveFailed)
                                        return false;
 
-                               if (result != resolveSucceeded) {
-                                       um = new_create_unresolved_method(m->class, m, iptr);
+                               if (result == resolveSucceeded) {
+                                       methodinfo *mi = iptr->sx.s23.s3.fmiref->p.method;
 
-                                       if (!um)
+                                       /* 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->clazz, m, fmi,
+                                                       (opcode == BC_invokestatic),
+                                                       (opcode == BC_invokespecial));
+
+                                       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)
                        }
@@ -979,25 +1296,28 @@ invoke_method:
 
                /* instructions taking class arguments ********************************/
 
-               case JAVA_NEW:
-                       i = SUCK_BE_U2(m->jcode + p + 1);
-                       cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
-                       if (!cr)
+               case BC_new:
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       cr = class_getconstant(m->clazz, i, CONSTANT_Class);
+
+                       if (cr == NULL)
                                return false;
 
                        if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
                                return false;
 
-                       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);
                        OP_BUILTIN_CHECK_EXCEPTION(bte);
                        s_count++;
                        break;
 
-               case JAVA_CHECKCAST:
-                       i = SUCK_BE_U2(m->jcode + p + 1);
-                       cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
-                       if (!cr)
+               case BC_checkcast:
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       cr = class_getconstant(m->clazz, i, CONSTANT_Class);
+
+                       if (cr == NULL)
                                return false;
 
                        if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
@@ -1005,20 +1325,21 @@ invoke_method:
 
                        if (cr->name->text[0] == '[') {
                                /* array type cast-check */
-                               flags = INS_FLAG_ARRAY;
-                               jd->isleafmethod = false;
+                               flags = INS_FLAG_CHECK | INS_FLAG_ARRAY;
+                               code_unflag_leafmethod(code);
                        }
                        else {
                                /* object type cast-check */
-                               flags = 0;
+                               flags = INS_FLAG_CHECK;
                        }
                        OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
                        break;
 
-               case JAVA_INSTANCEOF:
-                       i = SUCK_BE_U2(m->jcode + p + 1);
-                       cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
-                       if (!cr)
+               case BC_instanceof:
+                       i = SUCK_BE_U2(m->jcode + bcindex + 1);
+                       cr = class_getconstant(m->clazz, i, CONSTANT_Class);
+
+                       if (cr == NULL)
                                return false;
 
                        if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
@@ -1026,7 +1347,8 @@ invoke_method:
 
                        if (cr->name->text[0] == '[') {
                                /* array type cast-check */
-                               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);
                                OP_BUILTIN_NO_EXCEPTION(bte);
                                s_count++;
@@ -1039,7 +1361,7 @@ invoke_method:
 
                /* synchronization instructions ***************************************/
 
-               case JAVA_MONITORENTER:
+               case BC_monitorenter:
 #if defined(ENABLE_THREADS)
                        if (checksync) {
                                bte = builtintable_get_internal(LOCK_monitor_enter);
@@ -1048,11 +1370,12 @@ invoke_method:
                        else
 #endif
                        {
-                               OP(ICMD_CHECKNULL_POP);
+                               OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
+                               OP(ICMD_POP);
                        }
                        break;
 
-               case JAVA_MONITOREXIT:
+               case BC_monitorexit:
 #if defined(ENABLE_THREADS)
                        if (checksync) {
                                bte = builtintable_get_internal(LOCK_monitor_exit);
@@ -1061,49 +1384,66 @@ invoke_method:
                        else
 #endif
                        {
-                               OP(ICMD_CHECKNULL_POP);
+                               OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
+                               OP(ICMD_POP);
                        }
                        break;
 
                /* arithmetic instructions that may become builtin functions **********/
 
-               case JAVA_IDIV:
+               case BC_idiv:
 #if !SUPPORT_DIVISION
                        bte = builtintable_get_internal(BUILTIN_idiv);
                        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:
+               case BC_irem:
 #if !SUPPORT_DIVISION
                        bte = builtintable_get_internal(BUILTIN_irem);
                        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:
+               case BC_ldiv:
 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
                        bte = builtintable_get_internal(BUILTIN_ldiv);
                        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:
+               case BC_lrem:
 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
                        bte = builtintable_get_internal(BUILTIN_lrem);
                        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:
+               case BC_frem:
 #if defined(__I386__)
                        OP(opcode);
 #else
@@ -1112,7 +1452,7 @@ invoke_method:
 #endif
                        break;
 
-               case JAVA_DREM:
+               case BC_drem:
 #if defined(__I386__)
                        OP(opcode);
 #else
@@ -1121,67 +1461,55 @@ invoke_method:
 #endif
                        break;
 
-               case JAVA_F2I:
+               case BC_f2i:
 #if defined(__ALPHA__)
-                       if (!opt_noieee) {
-                               bte = builtintable_get_internal(BUILTIN_f2i);
-                               OP_BUILTIN_NO_EXCEPTION(bte);
-                       }
-                       else
+                       bte = builtintable_get_internal(BUILTIN_f2i);
+                       OP_BUILTIN_NO_EXCEPTION(bte);
+#else
+                       OP(opcode);
 #endif
-                       {
-                               OP(opcode);
-                       }
                        break;
 
-               case JAVA_F2L:
+               case BC_f2l:
 #if defined(__ALPHA__)
-                       if (!opt_noieee) {
-                               bte = builtintable_get_internal(BUILTIN_f2l);
-                               OP_BUILTIN_NO_EXCEPTION(bte);
-                       }
-                       else
+                       bte = builtintable_get_internal(BUILTIN_f2l);
+                       OP_BUILTIN_NO_EXCEPTION(bte);
+#else
+                       OP(opcode);
 #endif
-                       {
-                               OP(opcode);
-                       }
                        break;
 
-               case JAVA_D2I:
+               case BC_d2i:
 #if defined(__ALPHA__)
-                       if (!opt_noieee) {
-                               bte = builtintable_get_internal(BUILTIN_d2i);
-                               OP_BUILTIN_NO_EXCEPTION(bte);
-                       }
-                       else
+                       bte = builtintable_get_internal(BUILTIN_d2i);
+                       OP_BUILTIN_NO_EXCEPTION(bte);
+#else
+                       OP(opcode);
 #endif
-                       {
-                               OP(opcode);
-                       }
                        break;
 
-               case JAVA_D2L:
+               case BC_d2l:
 #if defined(__ALPHA__)
-                       if (!opt_noieee) {
-                               bte = builtintable_get_internal(BUILTIN_d2l);
-                               OP_BUILTIN_NO_EXCEPTION(bte);
-                       }
-                       else
+                       bte = builtintable_get_internal(BUILTIN_d2l);
+                       OP_BUILTIN_NO_EXCEPTION(bte);
+#else
+                       OP(opcode);
 #endif
-                       {
-                               OP(opcode);
-                       }
                        break;
 
+
                /* invalid opcodes ****************************************************/
 
                        /* check for invalid opcodes if the verifier is enabled */
 #if defined(ENABLE_VERIFIER)
-               case JAVA_BREAKPOINT:
+               case BC_breakpoint:
                        exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
                        return false;
 
-               case 186: /* unused opcode */
+
+               /* Unused opcodes ************************************************** */
+
+               case 186:
                case 203:
                case 204:
                case 205:
@@ -1236,7 +1564,7 @@ invoke_method:
                case 254:
                case 255:
                        exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
-                                                                                opcode, ipc);
+                                                                                opcode, ircount);
                        return false;
                        break;
 #endif /* defined(ENABLE_VERIFIER) */
@@ -1244,7 +1572,7 @@ invoke_method:
                /* opcodes that don't require translation *****************************/
 
                default:
-                       /* straight-forward translation to ICMD */
+                       /* Straight-forward translation to HIR. */
                        OP(opcode);
                        break;
 
@@ -1263,17 +1591,24 @@ invoke_method:
 
        } /* end for */
 
+       if (JITDATA_HAS_FLAG_REORDER(jd)) {
+               /* add a NOP to the last basic block */
+
+               INSTRUCTIONS_CHECK(1);
+               OP(ICMD_NOP);
+       }
+
        /*** END OF LOOP **********************************************************/
 
        /* assert that we did not write more ICMDs than allocated */
 
-       assert(ipc == (iptr - jd->new_instructions));
-       assert(ipc <= m->jcodelength);
+       assert(ircount <= pd.instructionslength);
+       assert(ircount == (iptr - pd.instructions));
 
        /*** verifier checks ******************************************************/
 
 #if defined(ENABLE_VERIFIER)
-       if (p != m->jcodelength) {
+       if (bcindex != m->jcodelength) {
                exceptions_throw_verifyerror(m,
                                "Command-sequence crosses code-boundary");
                return false;
@@ -1287,147 +1622,266 @@ invoke_method:
 
        /*** setup the methodinfo, allocate stack and basic blocks ****************/
 
-       /* adjust block count if target 0 is not first intermediate instruction */
+       /* identify basic blocks */
 
-       if (!jd->new_basicblockindex[0] || (jd->new_basicblockindex[0] > 1))
-               b_count++;
+       /* check if first instruction is a branch target */
 
-       /* copy local to method variables */
+       if (pd.basicblockstart[0] == 1) {
+               jd->branchtoentry = true;
+       }
+       else {
+               /* first instruction always starts a basic block */
 
-       jd->new_instructioncount = ipc;
-       jd->new_basicblockcount = b_count;
-       jd->new_stackcount = s_count + jd->new_basicblockcount * m->maxstack; /* in-stacks */
+               iptr = pd.instructions;
 
-#if defined(NEW_VAR)
-       jd->local_map = local_map;
+               iptr->flags.bits |= INS_FLAG_BASICBLOCK;
+       }
+
+       /* Iterate over all bytecode instructions and set missing
+          basic-block starts in IR instructions. */
+
+       for (bcindex = 0; bcindex < m->jcodelength; bcindex++) {
+               /* Does the current bytecode instruction start a basic
+                  block? */
+
+               if (pd.basicblockstart[bcindex] == 1) {
+#if defined(ENABLE_VERIFIER)
+                       /* Check if this bytecode basic-block start at the
+                          beginning of a bytecode instruction. */
+
+                       if (pd.bytecodestart[bcindex] == 0) {
+                               exceptions_throw_verifyerror(m,
+                                                                                "Branch into middle of instruction");
+                               return false;
+                       }
 #endif
 
-       /* allocate stack table */
+                       /* Get the IR instruction mapped to the bytecode
+                          instruction and set the basic block flag. */
+
+                       irindex = pd.bytecodemap[bcindex];
+                       iptr    = pd.instructions + irindex;
 
-       jd->new_stack = DMNEW(stackelement, jd->new_stackcount);
+                       iptr->flags.bits |= INS_FLAG_BASICBLOCK;
+               }
+       }
 
-       /* build basic block list */
+       /* IR instruction index to basic-block index mapping */
 
-       bptr = jd->new_basicblocks = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
+       pd.instructionmap = DMNEW(s4, ircount);
+       MZERO(pd.instructionmap, s4, ircount);
 
-       /* zero out all basic block structures */
+       /* Iterate over all IR instructions and count the basic blocks. */
 
-       MZERO(bptr, basicblock, b_count + 1);
+       iptr = pd.instructions;
 
-       b_count = 0;
-       jd->new_c_debug_nr = 0;
+       bbcount = 0;
 
-       /* additional block if target 0 is not first intermediate instruction */
+       for (i = 0; i < ircount; i++, iptr++) {
+               if (INSTRUCTION_STARTS_BASICBLOCK(iptr)) {
+                       /* store the basic-block number in the IR instruction
+                          map */
 
-       if (!jd->new_basicblockindex[0] || (jd->new_basicblockindex[0] > 1)) {
-               BASICBLOCK_INIT(bptr, m);
+                       pd.instructionmap[i] = bbcount;
 
-               bptr->iinstr = jd->new_instructions;
-               /* bptr->icount is set when the next block is allocated */
+                       /* post-increment the basic-block count */
 
-               bptr++;
-               b_count++;
-               bptr[-1].next = bptr;
+                       bbcount++;
+               }
        }
 
-       /* allocate blocks */
+       /* Allocate basic block array (one more for end ipc). */
 
-       for (p = 0; p < m->jcodelength; p++) {
-               if (jd->new_basicblockindex[p] & 1) {
-                       /* Check if this block starts at the beginning of an          */
-                       /* instruction.                                               */
-#if defined(ENABLE_VERIFIER)
-                       if (!instructionstart[p]) {
-                               exceptions_throw_verifyerror(m,
-                                               "Branch into middle of instruction");
-                               return false;
-                       }
-#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. */
+
+       iptr = pd.instructions;
+       bptr = jd->basicblocks;
 
-                       /* allocate the block */
+       bbcount = 0;
+
+       for (i = 0; i < ircount; i++, iptr++) {
+               /* check for basic block */
+
+               if (INSTRUCTION_STARTS_BASICBLOCK(iptr)) {
+                       /* intialize the basic block */
 
                        BASICBLOCK_INIT(bptr, m);
 
-                       bptr->iinstr = jd->new_instructions + (jd->new_basicblockindex[p] >> 1);
-                       if (b_count) {
+                       bptr->iinstr = iptr;
+
+                       if (bbcount > 0) {
                                bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
                        }
-                       /* bptr->icount is set when the next block is allocated */
 
-                       jd->new_basicblockindex[p] = b_count;
+                       /* bptr->icount is set when the next block is allocated */
 
+                       bptr->nr = bbcount++;
                        bptr++;
-                       b_count++;
                        bptr[-1].next = bptr;
                }
-       }
 
-       /* set instruction count of last real block */
+               /* resolve instruction indices to basic blocks */
+
+               switch (iptr->opc) {
+               case ICMD_IFEQ:
+               case ICMD_IFLT:
+               case ICMD_IFLE:
+               case ICMD_IFNE:
+               case ICMD_IFGT:
+               case ICMD_IFGE:
+               case ICMD_IFNULL:
+               case ICMD_IFNONNULL:
+               case ICMD_IF_ICMPEQ:
+               case ICMD_IF_ICMPNE:
+               case ICMD_IF_ICMPLT:
+               case ICMD_IF_ICMPGT:
+               case ICMD_IF_ICMPLE:
+               case ICMD_IF_ICMPGE:
+               case ICMD_IF_ACMPEQ:
+               case ICMD_IF_ACMPNE:
+               case ICMD_GOTO:
+                       BYTECODEINDEX_TO_BASICBLOCK(iptr->dst);
+                       break;
 
-       if (b_count) {
-               bptr[-1].icount = (jd->new_instructions + jd->new_instructioncount) - bptr[-1].iinstr;
-       }
+               case ICMD_JSR:
+                       BYTECODEINDEX_TO_BASICBLOCK(iptr->sx.s23.s3.jsrtarget);
+                       break;
 
-       /* allocate additional block at end */
+               case ICMD_TABLESWITCH:
+                       table = iptr->dst.table;
 
-       BASICBLOCK_INIT(bptr,m);
+                       BYTECODEINDEX_TO_BASICBLOCK(*table);
+                       table++;
 
-       /* set basicblock pointers in exception table */
+                       j = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1;
 
-       if (cd->exceptiontablelength > 0) {
-               cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
-       }
+                       while (--j >= 0) {
+                               BYTECODEINDEX_TO_BASICBLOCK(*table);
+                               table++;
+                       }
+                       break;
 
-       for (i = 0; i < cd->exceptiontablelength; ++i) {
-               p = cd->exceptiontable[i].startpc;
-               cd->exceptiontable[i].start = jd->new_basicblocks + jd->new_basicblockindex[p];
+               case ICMD_LOOKUPSWITCH:
+                       BYTECODEINDEX_TO_BASICBLOCK(iptr->sx.s23.s3.lookupdefault);
 
-               p = cd->exceptiontable[i].endpc;
-               cd->exceptiontable[i].end = (p == m->jcodelength) ? (jd->new_basicblocks + jd->new_basicblockcount /*+ 1*/) : (jd->new_basicblocks + jd->new_basicblockindex[p]);
+                       lookup = iptr->dst.lookup;
 
-               p = cd->exceptiontable[i].handlerpc;
-               cd->exceptiontable[i].handler = jd->new_basicblocks + jd->new_basicblockindex[p];
-       }
+                       j = iptr->sx.s23.s2.lookupcount;
 
-       /* 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 = jd->new_basicblocks + jd->new_basicblockindex[p];
+                       while (--j >= 0) {
+                               BYTECODEINDEX_TO_BASICBLOCK(lookup->target);
+                               lookup++;
+                       }
+                       break;
+               }
+       }
 
-               p = m->exceptiontable[i].endpc;
-               m->exceptiontable[i].end = (p == m->jcodelength) ? (jd->new_basicblocks + jd->new_basicblockcount /*+ 1*/) : (jd->new_basicblocks + jd->new_basicblockindex[p]);
+       /* set instruction count of last real block */
 
-               p = m->exceptiontable[i].handlerpc;
-               m->exceptiontable[i].handler = jd->new_basicblocks + jd->new_basicblockindex[p];
+       if (bbcount > 0) {
+               bptr[-1].icount = (pd.instructions + ircount) - bptr[-1].iinstr;
        }
-#endif
 
-#if defined(NEW_VAR)
+       /* allocate additional block at end */
+
+       BASICBLOCK_INIT(bptr, m);
+       bptr->nr = bbcount;
+
+       /* set basicblock pointers in exception table */
+
+       if (!parse_resolve_exception_table(jd, &pd))
+               return false;
+
+       /* store the local map */
+
+       jd->local_map = local_map;
+
        /* calculate local variable renaming */
 
        {
                s4 nlocals = 0;
                s4 i;
-
+               s4 t;
+               s4 varindex;
                s4 *mapptr;
+               s4 *reversemap;
 
                mapptr = local_map;
 
-               /* iterate over local_map[0..m->maxlocals*5] and set all existing  */
-               /* index,type pairs (localmap[index*5+type]==1) to an unique value */
-               /* -> == new local var index */
-               for(i = 0; i < (m->maxlocals * 5); i++, mapptr++) {
+               /* 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.             */
+
+               for (i = 0; i < (m->maxlocals * 5); i++, mapptr++) {
                        if (*mapptr)
                                *mapptr = nlocals++;
                        else
-                               *mapptr = LOCAL_UNUSED;
+                               *mapptr = UNUSED;
                }
 
                jd->localcount = nlocals;
 
-       }
+               /* calculate the (maximum) number of variables needed */
+
+               jd->varcount = 
+                         nlocals                                      /* local variables */
+                       + bbcount * m->maxstack                                 /* invars */
+                       + s_count;         /* variables created within blocks (non-invar) */
+
+               /* reserve the first indices for local variables */
+
+               jd->vartop = nlocals;
+
+               /* reserve extra variables needed by stack analyse */
+
+               jd->varcount += STACK_EXTRA_VARS;
+               jd->vartop   += STACK_EXTRA_VARS;
+
+               /* The verifier needs space for saving invars in some cases and */
+               /* extra variables.                                             */
+
+#if defined(ENABLE_VERIFIER)
+               jd->varcount += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
+               jd->vartop   += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
 #endif
+               /* allocate and initialize the variable array */
+
+               jd->var = DMNEW(varinfo, jd->varcount);
+               MZERO(jd->var, varinfo, jd->varcount);
+
+               /* set types of all locals in jd->var */
+               /* and fill the reverselocalmap       */
+
+               reversemap = DMNEW(s4, nlocals);
+
+               for (i = 0; i < m->maxlocals; i++)
+                       for (t=0; t<5; t++) {
+                               varindex = local_map[5*i + t];
+                               if (varindex != UNUSED) {
+                                       VAR(varindex)->type = t;
+                                       reversemap[varindex] = i;
+                               }
+                       }
+
+               jd->reverselocalmap = reversemap;
+       }
+
+       /* assign local variables to method variables */
+
+       jd->instructions     = pd.instructions;
+       jd->instructioncount = ircount;
+       jd->basicblockcount  = bbcount;
+       jd->stackcount       = s_count + bbcount * m->maxstack; /* in-stacks */
+
+       /* allocate stack table */
+
+       jd->stack = DMNEW(stackelement_t, jd->stackcount);
 
        /* everything's ok */