* src/vm/jit/parse.c (parse_resolve_exception_table): Do not use
[cacao.git] / src / vm / jit / parse.c
index 3bf7953193dc7b480fc04a50c4dbed8b3fc4d237..e604a943136eafe8babe812a0ee8b4f8c44ef6bc 100644 (file)
@@ -1,9 +1,9 @@
 /* src/vm/jit/parse.c - parser for JavaVM to intermediate code translation
 
-   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
-   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
-   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
-   Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+   J. Wenninger, Institut f. Computersprachen - TU Wien
 
    This file is part of CACAO.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
+   Contact: cacao@cacaojvm.org
 
    Author: Andreas Krall
 
             Joseph Wenninger
             Christian Thalinger
 
-   $Id: parse.c 4169 2006-01-12 22:34:04Z twisti $
+   $Id: parse.c 5790 2006-10-16 09:59:52Z edwin $
 
 */
 
 
+#include "config.h"
+
 #include <assert.h>
 #include <string.h>
 
-#include "config.h"
-
 #include "vm/types.h"
 
 #include "mm/memory.h"
 #include "native/native.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#endif
+
 #include "toolbox/logging.h"
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/options.h"
 #include "vm/statistics.h"
 #include "vm/stringlocal.h"
+#include "vm/suck.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher.h"
-#include "vm/jit/inline/parseRT.h"
-#include "vm/jit/inline/parseXTA.h"
-#include "vm/jit/inline/inline.h"
 #include "vm/jit/loop/loop.h"
-#include "vm/jit/inline/parseRTprint.h"
 
-bool DEBUG = false;
-bool DEBUG2 = false;
-bool DEBUG3 = false;
-bool DEBUG4 = false;  /*opcodes for parse.c*/
+#define INSTRUCTIONS_INCREMENT  5  /* number of additional instructions to    */
+                                   /* allocate if space runs out              */
 
 
-/*INLINING*/
-#define debug_writebranch if (DEBUG2==true) printf("op:: %s i: %d label_index[i]: %d label_index=0x%p\n",opcode_names[opcode], i, label_index[i], (void *)label_index);
-#define debug_writebranch1
+/* parserdata_t ***************************************************************/
 
-/*******************************************************************************
+typedef struct parsedata_t parsedata_t;
 
-       function 'parse' scans the JavaVM code and generates intermediate code
+struct parsedata_t {
+       instruction *instructions;          /* instruction array                  */
+       s4           instructionslength;    /* length of the instruction array    */
+       u1          *instructionstart;
+};
 
-       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.
+
+/* parse_setup *****************************************************************
+
+   Fills the passed parsedata_t structure.
+
+*******************************************************************************/
+
+static void parse_setup(jitdata *jd, parsedata_t *pd)
+{
+       methodinfo *m;
+
+       /* get required compiler data */
+
+       m = jd->m;
+
+       /* Allocate instruction array and block index table (1 additional
+          for end ipc). */
+
+       jd->basicblockindex = DMNEW(s4, m->jcodelength + 1);
+       pd->instructionstart = DMNEW(u1, m->jcodelength + 1);
+
+       MZERO(jd->basicblockindex, s4, m->jcodelength + 1);
+       MZERO(pd->instructionstart, u1, m->jcodelength + 1);
+
+       /* Set the length of the instruction array.  We simply add 5 more
+          instruction, as this seems to be a reasonable value. */
+
+       pd->instructionslength = m->jcodelength + 1;
+
+       /* allocate the instruction array */
+
+       pd->instructions = DMNEW(instruction, pd->instructionslength);
+
+       /* Zero the intermediate instructions array so we don't have any
+          invalid pointers in it if we cannot finish stack_analyse(). */
+
+       MZERO(pd->instructions, instruction, pd->instructionslength);
+}
+
+
+/* parse_realloc_instructions **************************************************
+
+   Reallocate the instructions array so there is room for at least N 
+   additional instructions.
+
+   RETURN VALUE:
+       the new value for iptr
+
+*******************************************************************************/
+
+static instruction *parse_realloc_instructions(parsedata_t *pd, s4 ipc, s4 n)
+{
+       /* increase the size of the instruction array */
+
+       pd->instructionslength += (n + INSTRUCTIONS_INCREMENT);
+
+       /* reallocate the array */
+
+       pd->instructions = DMREALLOC(pd->instructions, instruction, ipc,
+                                                                pd->instructionslength);
+
+       /* return the iptr */
+
+       return pd->instructions + ipc;
+}
+
+
+/* parse_mark_exception_boundaries *********************************************
+
+   Mark exception handlers and the boundaries of the handled regions as
+   basic block boundaries.
+
+   IN:
+       jd...............current jitdata
+
+   RETURN VALUE:
+       >= 0.............the number of new basic blocks marked
+          -1...............an exception has been thrown
 
 *******************************************************************************/
 
-static exceptiontable* fillextable(methodinfo *m, 
-               exceptiontable* extable, exceptiontable *raw_extable, 
-                int exceptiontablelength, 
-               int *label_index, int *block_count, 
-               t_inlining_globals *inline_env)
+static int parse_mark_exception_boundaries(jitdata *jd)
 {
-       int b_count, p, src, insertBlock;
+       s4                   b_count;
+       s4                   pc;
+       s4                   i;
+       s4                   len;
+       raw_exception_entry *rex;
+       methodinfo          *m;
+
+       m = jd->m;
        
-       if (exceptiontablelength == 0) 
-               return extable;
-
-       /*if (m->exceptiontablelength > 0) {
-         METHINFOx(m);
-         printf("m->exceptiontablelength=%i\n",m->exceptiontablelength);
-         assert(0);
-         }*/
-
-       b_count = *block_count;
-
-       for (src = exceptiontablelength-1; src >=0; src--) {
-               /* printf("Excepiont table index: %d\n",i); */
-               p = raw_extable[src].startpc;
-               if (label_index != NULL) p = label_index[p];
-               extable->startpc = p;
-               bound_check(p);
-               block_insert(p);
+       len = m->rawexceptiontablelength;
+
+       if (len == 0)
+               return 0;
+
+       b_count = 0;
+       rex = m->rawexceptiontable;
+
+       for (i = 0; i < len; ++i, ++rex) {
+
+               /* the start of the handled region becomes a basic block start */
+
+               pc = rex->startpc;
+               CHECK_BYTECODE_INDEX(pc);
+               MARK_BASICBLOCK(pc);
                
-/*** if (DEBUG==true){printf("---------------------block_inserted:b_count=%i m->basicblockindex[(p=%i)]=%i=%p\n",b_count,p,m->basicblockindex[(p)],m->basicblockindex[(p)]); 
-  fflush(stdout); } ***/   
-               p = raw_extable[src].endpc; /* see JVM Spec 4.7.3 */
-               if (p <= raw_extable[src].startpc) {
-                       *exceptionptr = new_verifyerror(inline_env->method,
+               pc = rex->endpc; /* see JVM Spec 4.7.3 */
+               CHECK_BYTECODE_INDEX_EXCLUSIVE(pc);
+
+               /* check that the range is valid */
+
+#if defined(ENABLE_VERIFIER)
+               if (pc <= rex->startpc) {
+                       exceptions_throw_verifyerror(m,
                                "Invalid exception handler range");
-                       return NULL;
+                       return -1;
                }
+#endif
+               
+               /* 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 >inline_env->method->jcodelength) {
-                       *exceptionptr = new_verifyerror(inline_env->method,
-                               "Invalid exception handler end is after code end");
-                       return NULL;
-               }
+               if (pc < m->jcodelength)
+                       MARK_BASICBLOCK(pc);
 
-               if (p<inline_env->method->jcodelength) insertBlock=1; else insertBlock=0;
-                /*if (label_index !=NULL) printf("%s:translating endpc:%ld to %ld, label_index:%p\n",m->name->text,p,label_index[p],label_index); else
-                       printf("%s:fillextab: endpc:%ld\n",m->name->text,p);*/
-               if (label_index != NULL) p = label_index[p];
-               extable->endpc = p;
-               bound_check1(p);
-               /*if (p < inline_env->method->jcodelength) {
-                       block_insert(p); }*/
-                if (insertBlock) block_insert(p);
-
-               p = raw_extable[src].handlerpc;
-               if (label_index != NULL) p = label_index[p];
-               extable->handlerpc = p;
-               bound_check(p);
-               block_insert(p);
-
-               extable->catchtype  = raw_extable[src].catchtype;
-               extable->next = NULL;
-               extable->down = &extable[1];
-               extable--;
+               /* the start of the handler becomes a basic block start  */
+
+               pc = rex->handlerpc;
+               CHECK_BYTECODE_INDEX(pc);
+               MARK_BASICBLOCK(pc);
        }
 
-       *block_count = b_count;
-       return extable; /*&extable[i];*/  /* return the next free xtable* */
+       /* everything ok */
+
+       return b_count;
+
+#if defined(ENABLE_VERIFIER)
+throw_invalid_bytecode_index:
+       exceptions_throw_verifyerror(m,
+                                                                "Illegal bytecode index in exception table");
+       return -1;
+#endif
 }
 
 
+/* parse_resolve_exception_table ***********************************************
+
+   Enter the exception handlers and their ranges, resolved to basicblock *s,
+   in the jitdata.
+
+   IN:
+       jd...............current jitdata
 
-methodinfo *parse(methodinfo *m, codegendata *cd, t_inlining_globals *inline_env)
+   RETURN VALUE:
+          true.............everything ok
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+static bool parse_resolve_exception_table(jitdata *jd)
 {
-       int  p;                     /* java instruction counter           */
-       int  nextp;                 /* start of next java instruction     */
-       int  opcode;                /* java opcode                        */
-       int  i;                     /* temporary for different uses (ctrs)*/
-       int  ipc = 0;               /* intermediate instruction counter   */
-       int  b_count = 0;           /* basic block counter                */
-       int  s_count = 0;           /* stack element counter              */
-       bool blockend = false;      /* true if basic block end has been reached   */
-       bool iswide = false;        /* true if last instruction was a wide*/
-       instruction *iptr;          /* current ptr into instruction array */
-       int gp;                     /* global java instruction counter    */
-                                   /* inlining info for current method   */
-
-       inlining_methodinfo *inlinfo = inline_env->inlining_rootinfo;
-       inlining_methodinfo *tmpinlinf;
-       int nextgp = -1;            /* start of next method to be inlined */
-       int *label_index = NULL;    /* label redirection table            */
-       int firstlocal = 0;         /* first local variable of method     */
-       exceptiontable* nextex;     /* points next free entry in extable  */
-       u1 *instructionstart;       /* 1 for pcs which are valid instr. starts    */
+       methodinfo          *m;
+       raw_exception_entry *rex;
+       exception_entry     *ex;
+       s4                   i;
+       s4                   len;
+       classinfo           *exclass;
 
-       constant_classref  *cr;
-       constant_classref  *compr;
-       classinfo          *c;
-       builtintable_entry *bte;
+       m = jd->m;
 
-       u2 lineindex = 0;
-       u2 currentline = 0;
-       u2 linepcchange = 0;
-
-       u2 skipBasicBlockChange;
-
-#if defined(USE_INLINING)
-METHINFOt(m,"\nPARSING: ",DEBUG4);
-if ((opt_rt) || (opt_xta)) {
-  FILE *Missed;
-
-  if (opt_rt)  Missed =  rtMissed;  
-  if (opt_xta) Missed = xtaMissed;  
-
-  if (m->methodUsed != USED) {
-    if (opt_verbose) {
-      printf(" rta/xta missed: "); fflush(stdout);
-      METHINFO(m,opt_verbose);
-      }
-    if ( (Missed = fopen("Missed", "a")) == NULL) {
-      printf("CACAO - rt/xtaMissed file: cant open file to write append \n");
-      }
-    else {
-      utf_fprint(Missed,m->class->name); 
-       fprintf(Missed," "); fflush(Missed);
-      utf_fprint(Missed,m->name);
-       fprintf(Missed," "); fflush(Missed);
-      utf_fprint(Missed,m->descriptor); 
-       fprintf(Missed,"\n"); fflush(Missed);
-      fclose(Missed);
-      }
-   } 
-}
-#endif
+       len = m->rawexceptiontablelength;
 
-#if defined(USE_INLINING)
-       if (useinlining) {
-               label_index = inlinfo->label_index;
-               m->maxstack = inline_env->cummaxstack;
-               /*JOWENN m->exceptiontablelength = inline_env->cumextablelength;*/
+       /* common case: no handler entries */
 
-               tmpinlinf = (inlining_methodinfo *) list_first(inlinfo->inlinedmethods);
+       if (len == 0)
+               return true;
 
-               if (tmpinlinf != NULL)
-                       nextgp = tmpinlinf->startgp;
-       }
-#endif
+       /* allocate the exception table */
+
+       jd->exceptiontablelength = len;
+       jd->exceptiontable = DMNEW(exception_entry, len + 1); /* XXX why +1? */
+
+       /* copy and resolve the entries */
+
+       ex = jd->exceptiontable;
+       rex = m->rawexceptiontable;
+
+       for (i = 0; i < len; ++i, ++rex, ++ex) {
+               /* resolve instruction indices to basic blocks */
+
+               ex->start   = BLOCK_OF(rex->startpc);
+               ex->end     = BLOCK_OF(rex->endpc);
+               ex->handler = BLOCK_OF(rex->handlerpc);
+
+               /* lazily resolve the catchtype */
+
+               if (rex->catchtype.any != NULL) {
+                       if (!resolve_classref_or_classinfo(m,
+                                                                                          rex->catchtype,
+                                                                                          resolveLazy, true, false,
+                                                                                          &exclass))
+                               return false;
 
-/**** static analysis has to be called before inlining
-        which has to be called before reg_set
-        which has to be called before parse (or ???)
-        will check if method being parsed was analysed here
-       if (opt_xta && opt_verbose) { 
-               **RT_jit_parse(m);**
-               printf("XTA requested, not available\n");
+                       /* if resolved, enter the result of resolution in the table */
+
+                       if (exclass != NULL)
+                               rex->catchtype.cls = exclass;
                }
-       if (opt_vta && opt_verbose)  
-                   printf("VTA requested, not yet implemented\n");
-       ****/ 
 
-       /* allocate instruction array and block index table */
-       
-       /* 1 additional for end ipc * # cum inline methods*/
-       
-       m->basicblockindex = DMNEW(s4, inline_env->cumjcodelength + inline_env->cummethods);
-       memset(m->basicblockindex, 0, sizeof(s4) * (inline_env->cumjcodelength + inline_env->cummethods));
+               ex->catchtype = rex->catchtype;
+               ex->next = NULL;   /* set by loop analysis */
+               ex->down = ex + 1; /* link to next exception entry */
+       }
 
-       instructionstart = DMNEW(u1, inline_env->cumjcodelength + inline_env->cummethods);
-       memset(instructionstart, 0, sizeof(u1) * (inline_env->cumjcodelength + inline_env->cummethods));
+       /* terminate the ->down linked list */
 
-       /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
-       /* additional MONITOREXITS are reached by branches which are 3 bytes */
-       
-       iptr = m->instructions = DMNEW(instruction, inline_env->cumjcodelength + 5);
+       assert(ex != jd->exceptiontable);
+       ex[-1].down = NULL;
 
-       /* Zero the intermediate instructions array so we don't have any
-        * invalid pointers in it if we cannot finish analyse_stack(). */
+       return true;
+}
 
-       memset(iptr, 0, sizeof(instruction) * (inline_env->cumjcodelength + 5));
-       
-       /* compute branch targets of exception table */
-       /*
-if (m->exceptiontable == NULL) {
-  printf("m->exceptiontable=NULL\n");fflush(stdout);
-  }
-else {
-  printf("m->exceptiontable != NULL\n");fflush(stdout);
-  }
-printf("m->exceptiontablelength=%i, inline_env->method->exceptiontablelength=%i,inline_env->cumextablelength=%i\n",
-m->exceptiontablelength, inline_env->method->exceptiontablelength,inline_env->cumextablelength);
-       */
-       /*
-if (m->exceptiontablelength > 0)
-       m->exceptiontable = DMNEW(exceptiontable, m->exceptiontablelength + 1); 
-       */
-
-       nextex = fillextable(m, 
-         &(cd->exceptiontable[cd->exceptiontablelength-1]), m->exceptiontable, m->exceptiontablelength, 
-          label_index, &b_count, inline_env);
-       if (!nextex)
-               return NULL;
-       s_count = 1 + m->exceptiontablelength; /* initialize stack element counter   */
-
-#if defined(USE_THREADS)
-       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
-               m->isleafmethod = false;
-               inline_env->method->isleafmethod = false;
-       }                       
+
+/*******************************************************************************
+
+       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)
+#define CHECK_END_OF_BYTECODE(neededlength) \
+       do { \
+               if ((neededlength) > m->jcodelength) \
+                       goto throw_unexpected_end_of_bytecode; \
+       } while (0)
+#else /* !ENABLE_VERIFIER */
+#define CHECK_END_OF_BYTECODE(neededlength)
+#endif /* ENABLE_VERIFIER */
+
+bool parse(jitdata *jd)
+{
+       methodinfo  *m;                     /* method being parsed                */
+       codeinfo    *code;
+       parsedata_t  pd;
+       instruction *iptr;                  /* current ptr into instruction array */
+       s4           ipc;                   /* intermediate instruction counter   */
+       s4           p;                     /* java instruction counter           */
+       s4           nextp;                 /* start of next java instruction     */
+       s4           opcode;                /* java opcode                        */
+       s4           i;
+       s4           j;
+       int  b_count;               /* basic block counter                      */
+       int  s_count = 0;           /* stack element counter                    */
+       bool blockend = false;      /* true if basic block end has been reached */
+       bool iswide = false;        /* true if last instruction was a wide      */
+       constant_classref  *cr;
+       constant_classref  *compr;
+       classinfo          *c;
+       builtintable_entry *bte;
+       constant_FMIref    *mr;
+       methoddesc         *md;
+       unresolved_method  *um;
+       resolve_result_t    result;
+       u2                  lineindex = 0;
+       u2                  currentline = 0;
+       u2                  linepcchange = 0;
+       u4                  flags;
+       basicblock         *bptr;
+
+       int                *local_map; /* local pointer to renaming structore     */
+                                      /* is assigned to rd->local_map at the end */
+       /* get required compiler data */
+
+       m    = jd->m;
+       code = jd->code;
+
+       /* allocate buffers for local variable renaming */
+       local_map = DMNEW(int, m->maxlocals * 5);
+       for (i = 0; i < m->maxlocals; i++) {
+               local_map[i * 5 + 0] = 0;
+               local_map[i * 5 + 1] = 0;
+               local_map[i * 5 + 2] = 0;
+               local_map[i * 5 + 3] = 0;
+               local_map[i * 5 + 4] = 0;
+       }
+
+       /* initialize the parse data structures */
+  
+       parse_setup(jd, &pd);
+  
+       /* initialize local variables */
+  
+       iptr = pd.instructions;
+       ipc  = 0;
+  
+       /* mark basic block boundaries for exception table */
+
+       b_count = parse_mark_exception_boundaries(jd);
+       if (b_count < 0)
+               return false;
+
+       /* initialize stack element counter */
+
+       s_count = 1 + m->rawexceptiontablelength;
+
+#if defined(ENABLE_THREADS)
+       if (checksync && (m->flags & ACC_SYNCHRONIZED))
+               jd->isleafmethod = false;
 #endif
 
-       /* scan all java instructions */
+       /* setup line number info */
+
        currentline = 0;
        linepcchange = 0;
 
        if (m->linenumbercount == 0) {
                lineindex = 0;
-               /*printf("linenumber count == 0\n");*/
-       else {
+       }
+       else {
                linepcchange = m->linenumbers[0].start_pc;
        }
 
-       skipBasicBlockChange=0;
-       for (p = 0, gp = 0; p < inline_env->method->jcodelength; gp += (nextp - p), p = nextp) {
-         
-               /* DEBUG */      if (DEBUG==true) printf("----- p:%d gp:%d\n",p,gp);
+       /*** LOOP OVER ALL BYTECODE INSTRUCTIONS **********************************/
 
-               /* mark this position as a valid instruction start */
-               if (!iswide) {
-                       instructionstart[gp] = 1;
-                       /*log_text("new start of instruction");*/
-                        /*printf ("%s, linepcchange %d,p %d\n",inline_env->method->name->text,linepcchange,p);*/
-                       if (linepcchange==p) {
-                               if (inline_env->method->linenumbercount > lineindex) {
-                                       currentline = inline_env->method->linenumbers[lineindex].line_number;
-                                       lineindex++;
-                                       if (lineindex < inline_env->method->linenumbercount)
-                                               linepcchange = inline_env->method->linenumbers[lineindex].start_pc;
-                                       /*printf("Line number changed to: %ld\n",currentline);*/
-                               }
-                       }
-               }
+       for (p = 0; p < m->jcodelength; p = nextp) {
 
-#if defined(USE_INLINING)
-               if ((useinlining) && (gp == nextgp)) {
-                       u1 *tptr;
-                       bool *readonly = NULL;
-                       int argBlockIdx=0;
-
-                       block_insert(gp);               /* JJJJJJJJJJ */
-                       blockend=false;
-                       instructionstart[gp] = 1;
-                       m->basicblockindex[gp] |= (ipc << 1);  /*FIXME: necessary ? */
-
-                       opcode = code_get_u1(p,inline_env->method);
-                       nextp = p += jcommandsize[opcode];
-                       if (nextp > inline_env->method->jcodelength) {
-                               *exceptionptr = new_verifyerror(inline_env->method,
-                                       "Unexpected end of bytecode");
-                               return NULL;
-                       }
-
-                       tmpinlinf = list_first(inlinfo->inlinedmethods);
-                       firstlocal = tmpinlinf->firstlocal;
-                       label_index = tmpinlinf->label_index;
-                       readonly = tmpinlinf->readonly;
-
-                       for (i=0,tptr=tmpinlinf->method->paramtypes;i<tmpinlinf->method->paramcount;i++,tptr++) {
-                               if ( ((*tptr)==TYPE_LNG) ||
-                                 ((*tptr)==TYPE_DBL) )
-                                       argBlockIdx+=2;
-                               else
-                                       argBlockIdx++;
-                       }
+               /* mark this position as a valid instruction start */
 
-                       for (i = 0, tptr = tmpinlinf->method->paramtypes + tmpinlinf->method->paramcount - 1; i < tmpinlinf->method->paramcount; i++, tptr--) {
-                               int op;
+               pd.instructionstart[p] = 1;
 
-                               if ((i == 0) && inlineparamopt) {
-                                       OP1(ICMD_CLEAR_ARGREN, firstlocal);
-                               }
+               /* change the current line number, if necessary */
 
-                               if (!inlineparamopt || !readonly[i]) {
-                                       op = ICMD_ISTORE;
+               /* XXX rewrite this using pointer arithmetic */
 
-                               } else {
-                                       op = ICMD_READONLY_ARG;
+               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;
                                }
-
-                               op += *tptr;
-                               if ( ((*tptr)==TYPE_LNG) ||
-                                 ((*tptr)==TYPE_DBL) )
-                                       argBlockIdx-=2;
-                               else
-                                       argBlockIdx--;
-
-                               OP1(op, firstlocal + argBlockIdx);
-                               /* OP1(op, firstlocal + tmpinlinf->method->paramcount - 1 - i); */
-                               /* printf("inline argument load operation for local: %ld\n",firstlocal + tmpinlinf->method->paramcount - 1 - i); */
-                       }
-                       skipBasicBlockChange=1;
-METHINFOt(inline_env->method,"BEFORE SAVE: ",DEBUG);
-                       inlining_save_compiler_variables();
-METHINFOt(inline_env->method,"AFTER SAVE: ",DEBUG);
-                       inlining_set_compiler_variables(tmpinlinf);
-METHINFOt(inline_env->method,"AFTER SET :: ",DEBUG);
-METHINFOt(m,"\n.......Parsing (inlined): ",DEBUG);
-METHINFO(inline_env->method,DEBUG);
-
-                        OP1(ICMD_INLINE_START,tmpinlinf->level);
-
-                       if (inlinfo->inlinedmethods == NULL) {
-                               gp = -1;
-                       } else {
-                               tmpinlinf = list_first(inlinfo->inlinedmethods);
-                               nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
-                       }
-                       if (inline_env->method->exceptiontablelength > 0) {
-                               nextex = fillextable(m, nextex, 
-                                               inline_env->method->exceptiontable, inline_env->method->exceptiontablelength, 
-                                               label_index, &b_count, inline_env);
-                               if (!nextex)
-                                       return NULL;
                        }
-                       continue;
                }
-#endif /* defined(USE_INLINING) */
 
-               /* fetch next opcode  */
+fetch_opcode:
+               /* fetch next opcode  */        
 
-               opcode = code_get_u1(p, inline_env->method);
-
-        if (DEBUG==true) 
-               {
-                       printf("Parse p=%i<%i<%i<   opcode=<%i> %s\n",
-                          p, gp, inline_env->jcodelength, opcode, opcode_names[opcode]);
-                       if (label_index)
-                               printf("label_index[%d]=%d\n",p,label_index[p]);
-               }
-        /*
-printf("basicblockindex[gp=%i]=%i=%p ipc=%i=%p shifted ipc=%i=%p\n",
-gp,m->basicblockindex[gp],m->basicblockindex[gp],ipc,ipc,(ipc<<1),(ipc<<1));
-fflush(stdout);
-        */
-               if (!skipBasicBlockChange) {
-                       m->basicblockindex[gp] |= (ipc << 1); /*store intermed cnt*/
-               } else skipBasicBlockChange=0;
-               /*
-printf("basicblockindex[gp=%i]=%i=%p \n",
-gp,m->basicblockindex[gp],m->basicblockindex[gp]);
-fflush(stdout);
-               */
+               opcode = SUCK_BE_U1(m->jcode + p);
 
                /* some compilers put a JAVA_NOP after a blockend instruction */
 
-               if ((opcode != JAVA_NOP) && (blockend == true)) {
+               if (blockend && (opcode != JAVA_NOP)) {
                        /* start new block */
 
-                       block_insert(gp);
+                       MARK_BASICBLOCK(p);
                        blockend = false;
                }
 
-               nextp = p + jcommandsize[opcode];   /* compute next instruction start */
+               /* We need a NOP as last instruction in each basic block
+                  for basic block reordering (may be replaced with a GOTO
+                  later). */
 
-               if (nextp > inline_env->method->jcodelength) {
-                       *exceptionptr = new_verifyerror(inline_env->method,
-                                       "Unexpected end of bytecode");
-                       return NULL;
+               if (jd->basicblockindex[p] & 1) {
+                       INSTRUCTIONS_CHECK(1);
+                       OP(ICMD_NOP);
                }
 
-               s_count += stackreq[opcode];            /* compute stack element count    */
-SHOWOPCODE(DEBUG4)
+               /* store intermediate instruction count (bit 0 mark block starts) */
+
+               jd->basicblockindex[p] |= (ipc << 1);
+
+               /* compute next instruction start */
+
+               nextp = p + jcommandsize[opcode];
+
+               CHECK_END_OF_BYTECODE(nextp);
+
+               /* add stack elements produced by this instruction */
+
+               s_count += stackreq[opcode];
+
+               /* We check here for the space of 1 instruction in the
+                  instruction array.  If an opcode is converted to more than
+                  1 instruction, this is checked in the corresponding
+                  case. */
+
+               INSTRUCTIONS_CHECK(1);
+
+               /* translate this bytecode instruction */
                switch (opcode) {
+
                case JAVA_NOP:
                        break;
 
-                       /* pushing constants onto the stack p */
+               /* pushing constants onto the stack ***********************************/
 
                case JAVA_BIPUSH:
-                       LOADCONST_I(code_get_s1(p+1,inline_env->method));
+                       OP_LOADCONST_I(SUCK_BE_S1(m->jcode + p + 1));
                        break;
 
                case JAVA_SIPUSH:
-                       LOADCONST_I(code_get_s2(p+1,inline_env->method));
+                       OP_LOADCONST_I(SUCK_BE_S2(m->jcode + p + 1));
                        break;
 
                case JAVA_LDC1:
-                       i = code_get_u1(p + 1, inline_env->method);
+                       i = SUCK_BE_U1(m->jcode + p + 1);
                        goto pushconstantitem;
 
                case JAVA_LDC2:
                case JAVA_LDC2W:
-                       i = code_get_u2(p + 1, inline_env->method);
+                       i = SUCK_BE_U2(m->jcode + p + 1);
 
                pushconstantitem:
 
-                       if (i >= inline_env->method->class->cpcount) {
-                               *exceptionptr = new_verifyerror(inline_env->method,
+#if defined(ENABLE_VERIFIER)
+                       if (i >= m->class->cpcount) {
+                               exceptions_throw_verifyerror(m,
                                        "Attempt to access constant outside range");
-                               return NULL;
+                               return false;
                        }
+#endif
 
-                       switch (inline_env->method->class->cptags[i]) {
+                       switch (m->class->cptags[i]) {
                        case CONSTANT_Integer:
-                               LOADCONST_I(((constant_integer *) (inline_env->method->class->cpinfos[i]))->value);
+                               OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
                                break;
                        case CONSTANT_Long:
-                               LOADCONST_L(((constant_long *) (inline_env->method->class->cpinfos[i]))->value);
+                               OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
                                break;
                        case CONSTANT_Float:
-                               LOADCONST_F(((constant_float *) (inline_env->method->class->cpinfos[i]))->value);
+                               OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
                                break;
                        case CONSTANT_Double:
-                               LOADCONST_D(((constant_double *) (inline_env->method->class->cpinfos[i]))->value);
+                               OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
                                break;
                        case CONSTANT_String:
-                               LOADCONST_A(literalstring_new((utf *) (inline_env->method->class->cpinfos[i])));
+                               OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
                                break;
                        case CONSTANT_Class:
-                               cr = (constant_classref *) (inline_env->method->class->cpinfos[i]);
+                               cr = (constant_classref *) (m->class->cpinfos[i]);
 
-                               if (!resolve_classref(inline_env->method, cr, resolveLazy, true,
-                                                                         true, &c))
-                                       return NULL;
+                               if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
+                                       return false;
 
                                /* if not resolved, c == NULL */
 
-                               LOADCONST_A_CLASS(c, cr);
+                               OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr);
+
                                break;
+
+#if defined(ENABLE_VERIFIER)
                        default:
-                               *exceptionptr = new_verifyerror(inline_env->method,
+                               exceptions_throw_verifyerror(m,
                                                "Invalid constant type to push");
-                               return NULL;
+                               return false;
+#endif
                        }
                        break;
 
                case JAVA_ACONST_NULL:
-                       LOADCONST_A(NULL);
+                       OP_LOADCONST_NULL();
                        break;
 
                case JAVA_ICONST_M1:
@@ -531,159 +565,243 @@ SHOWOPCODE(DEBUG4)
                case JAVA_ICONST_3:
                case JAVA_ICONST_4:
                case JAVA_ICONST_5:
-                       LOADCONST_I(opcode - JAVA_ICONST_0);
+                       OP_LOADCONST_I(opcode - JAVA_ICONST_0);
                        break;
 
                case JAVA_LCONST_0:
                case JAVA_LCONST_1:
-                       LOADCONST_L(opcode - JAVA_LCONST_0);
+                       OP_LOADCONST_L(opcode - JAVA_LCONST_0);
                        break;
 
                case JAVA_FCONST_0:
                case JAVA_FCONST_1:
                case JAVA_FCONST_2:
-                       LOADCONST_F(opcode - JAVA_FCONST_0);
+                       OP_LOADCONST_F(opcode - JAVA_FCONST_0);
                        break;
 
                case JAVA_DCONST_0:
                case JAVA_DCONST_1:
-                       LOADCONST_D(opcode - JAVA_DCONST_0);
+                       OP_LOADCONST_D(opcode - JAVA_DCONST_0);
                        break;
 
-                       /* loading variables onto the stack */
+               /* 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 *********************************/
 
                case JAVA_ILOAD:
-               case JAVA_LLOAD:
                case JAVA_FLOAD:
-               case JAVA_DLOAD:
                case JAVA_ALOAD:
-                       if (!iswide) {
-                               i = code_get_u1(p + 1,inline_env->method);
-                       } else {
-                               i = code_get_u2(p + 1,inline_env->method);
+                       if (iswide == false) {
+                               i = SUCK_BE_U1(m->jcode + p + 1);
+                       }
+                       else {
+                               i = SUCK_BE_U2(m->jcode + p + 1);
+                               nextp = p + 3;
+                               iswide = false;
+                       }
+                       OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
+                       break;
+
+               case JAVA_LLOAD:
+               case JAVA_DLOAD:
+                       if (iswide == false) {
+                               i = SUCK_BE_U1(m->jcode + p + 1);
+                       }
+                       else {
+                               i = SUCK_BE_U2(m->jcode + p + 1);
                                nextp = p + 3;
                                iswide = false;
                        }
-                       OP1LOAD(opcode, i + firstlocal);
+                       OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
                        break;
 
                case JAVA_ILOAD_0:
                case JAVA_ILOAD_1:
                case JAVA_ILOAD_2:
                case JAVA_ILOAD_3:
-                       OP1LOAD(ICMD_ILOAD, opcode - JAVA_ILOAD_0 + firstlocal);
+                       OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
                        break;
 
                case JAVA_LLOAD_0:
                case JAVA_LLOAD_1:
                case JAVA_LLOAD_2:
                case JAVA_LLOAD_3:
-                       OP1LOAD(ICMD_LLOAD, opcode - JAVA_LLOAD_0 + firstlocal);
+                       OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
                        break;
 
                case JAVA_FLOAD_0:
                case JAVA_FLOAD_1:
                case JAVA_FLOAD_2:
                case JAVA_FLOAD_3:
-                       OP1LOAD(ICMD_FLOAD, opcode - JAVA_FLOAD_0 + firstlocal);
+                       OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
                        break;
 
                case JAVA_DLOAD_0:
                case JAVA_DLOAD_1:
                case JAVA_DLOAD_2:
                case JAVA_DLOAD_3:
-                       OP1LOAD(ICMD_DLOAD, opcode - JAVA_DLOAD_0 + firstlocal);
+                       OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
                        break;
 
                case JAVA_ALOAD_0:
                case JAVA_ALOAD_1:
                case JAVA_ALOAD_2:
                case JAVA_ALOAD_3:
-                       OP1LOAD(ICMD_ALOAD, opcode - JAVA_ALOAD_0 + firstlocal);
+                       OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
                        break;
 
-                       /* storing stack values into local variables */
-
                case JAVA_ISTORE:
-               case JAVA_LSTORE:
                case JAVA_FSTORE:
-               case JAVA_DSTORE:
                case JAVA_ASTORE:
-                       if (!iswide) {
-                               i = code_get_u1(p + 1,inline_env->method);
-                       } else {
-                               i = code_get_u2(p + 1,inline_env->method);
+                       if (iswide == false) {
+                               i = SUCK_BE_U1(m->jcode + p + 1);
+                       }
+                       else {
+                               i = SUCK_BE_U2(m->jcode + p + 1);
+                               iswide = false;
+                               nextp = p + 3;
+                       }
+                       OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
+                       break;
+
+               case JAVA_LSTORE:
+               case JAVA_DSTORE:
+                       if (iswide == false) {
+                               i = SUCK_BE_U1(m->jcode + p + 1);
+                       }
+                       else {
+                               i = SUCK_BE_U2(m->jcode + p + 1);
                                iswide = false;
                                nextp = p + 3;
                        }
-                       OP1STORE(opcode, i + firstlocal);
+                       OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
                        break;
 
                case JAVA_ISTORE_0:
                case JAVA_ISTORE_1:
                case JAVA_ISTORE_2:
                case JAVA_ISTORE_3:
-                       OP1STORE(ICMD_ISTORE, opcode - JAVA_ISTORE_0 + firstlocal);
+                       OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
                        break;
 
                case JAVA_LSTORE_0:
                case JAVA_LSTORE_1:
                case JAVA_LSTORE_2:
                case JAVA_LSTORE_3:
-                       OP1STORE(ICMD_LSTORE, opcode - JAVA_LSTORE_0 + firstlocal);
+                       OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
                        break;
 
                case JAVA_FSTORE_0:
                case JAVA_FSTORE_1:
                case JAVA_FSTORE_2:
                case JAVA_FSTORE_3:
-                       OP1STORE(ICMD_FSTORE, opcode - JAVA_FSTORE_0 + firstlocal);
+                       OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
                        break;
 
                case JAVA_DSTORE_0:
                case JAVA_DSTORE_1:
                case JAVA_DSTORE_2:
                case JAVA_DSTORE_3:
-                       OP1STORE(ICMD_DSTORE, opcode - JAVA_DSTORE_0 + firstlocal);
+                       OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
                        break;
 
                case JAVA_ASTORE_0:
                case JAVA_ASTORE_1:
                case JAVA_ASTORE_2:
                case JAVA_ASTORE_3:
-                       OP1STORE(ICMD_ASTORE, opcode - JAVA_ASTORE_0 + firstlocal);
+                       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,inline_env->method);
-                                       v = code_get_s1(p + 2,inline_env->method);
-
-                               } else {
-                                       i = code_get_u2(p + 1,inline_env->method);
-                                       v = code_get_s2(p + 3,inline_env->method);
+
+                               if (iswide == false) {
+                                       i = SUCK_BE_U1(m->jcode + p + 1);
+                                       v = SUCK_BE_S1(m->jcode + p + 2);
+
+                               }
+                               else {
+                                       i = SUCK_BE_U2(m->jcode + p + 1);
+                                       v = SUCK_BE_S2(m->jcode + p + 3);
                                        iswide = false;
                                        nextp = p + 5;
                                }
-                               INDEX_ONEWORD(i + firstlocal);
-                               OP2I(opcode, i + firstlocal, v);
+                               INDEX_ONEWORD(i);
+                               LOCALTYPE_USED(i, TYPE_INT);
+                               OP_LOCALINDEX_I(opcode, i, v);
                        }
                        break;
 
-                       /* wider index for loading, storing and incrementing */
+               /* wider index for loading, storing and incrementing ******************/
 
                case JAVA_WIDE:
                        iswide = true;
-                       nextp = p + 1;
-                       break;
+                       p++;
+                       goto fetch_opcode;
 
                /* managing arrays ****************************************************/
 
                case JAVA_NEWARRAY:
-                       switch (code_get_s1(p + 1, inline_env->method)) {
+                       switch (SUCK_BE_S1(m->jcode + p + 1)) {
                        case 4:
                                bte = builtintable_get_internal(BUILTIN_newarray_boolean);
                                break;
@@ -708,50 +826,54 @@ SHOWOPCODE(DEBUG4)
                        case 11:
                                bte = builtintable_get_internal(BUILTIN_newarray_long);
                                break;
+#if defined(ENABLE_VERIFIER)
                        default:
-                               *exceptionptr = new_verifyerror(inline_env->method,
-                                               "Invalid array-type to create");
-                               return NULL;
+                               exceptions_throw_verifyerror(m, "Invalid array-type to create");
+                               return false;
+#endif
                        }
-                       BUILTIN(bte, true, NULL, currentline);
+                       OP_BUILTIN_CHECK_EXCEPTION(bte);
                        break;
 
                case JAVA_ANEWARRAY:
-                       i = code_get_u2(p + 1, inline_env->method);
-                       compr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+                       i = SUCK_BE_U2(m->jcode + p + 1);
+                       compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
                        if (!compr)
-                               return NULL;
+                               return false;
 
                        if (!(cr = class_get_classref_multiarray_of(1, compr)))
-                               return NULL;
+                               return false;
 
-                       if (!resolve_classref(inline_env->method, cr, resolveLazy, true, true, &c))
-                               return NULL;
+                       if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
+                               return false;
 
-                       LOADCONST_A_BUILTIN(c, cr);
+                       INSTRUCTIONS_CHECK(2);
+                       OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
                        bte = builtintable_get_internal(BUILTIN_newarray);
-                       BUILTIN(bte, true, NULL, currentline);
+                       OP_BUILTIN_CHECK_EXCEPTION(bte);
                        s_count++;
                        break;
 
                case JAVA_MULTIANEWARRAY:
-                       inline_env->method->isleafmethod = false;
-                       i = code_get_u2(p + 1, inline_env->method);
-                       {
-                               s4 v = code_get_u1(p + 3, inline_env->method);
-
-                               cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
-                               if (!cr)
-                                       return NULL;
-
-                               if (!resolve_classref(inline_env->method, cr, resolveLazy, true, true, &c))
-                                       return NULL;
-
-                               /* if unresolved c == NULL */
-                               OP2AT(opcode, v, c, cr, currentline);
-                       }
+                       jd->isleafmethod = false;
+                       i = SUCK_BE_U2(m->jcode + p + 1);
+                       j = SUCK_BE_U1(m->jcode + p + 3);
+  
+                       cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
+                       if (cr == NULL)
+                               return false;
+  
+                       if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
+                               return false;
+  
+                       /* if unresolved, c == NULL */
+  
+                       iptr->s1.argcount = j;
+                       OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags */);
                        break;
 
+               /* control flow instructions ******************************************/
+
                case JAVA_IFEQ:
                case JAVA_IFLT:
                case JAVA_IFLE:
@@ -769,50 +891,48 @@ SHOWOPCODE(DEBUG4)
                case JAVA_IF_ACMPEQ:
                case JAVA_IF_ACMPNE:
                case JAVA_GOTO:
-               case JAVA_JSR:
-                       i = p + code_get_s2(p + 1,inline_env->method);
-                       if (useinlining) { 
-                               debug_writebranch;
-                               i = label_index[i];
-                       }
-                       /*printf("GOTO: %d\n",i);*/
-                       bound_check(i);
-                       block_insert(i);
+                       i = p + SUCK_BE_S2(m->jcode + p + 1);
+                       CHECK_BYTECODE_INDEX(i);
+                       MARK_BASICBLOCK(i);
                        blockend = true;
-                       OP1(opcode, i);
+                       OP_INSINDEX(opcode, i);
                        break;
 
                case JAVA_GOTO_W:
-               case JAVA_JSR_W:
-                       i = p + code_get_s4(p + 1,inline_env->method);
-                       if (useinlining) { 
-                               debug_writebranch;
-                               i = label_index[i];
-                       }
-                       bound_check(i);
-                       /*printf("B6 JSR_W\t"); fflush(stdout);*/
-                       block_insert(i);
+                       i = p + SUCK_BE_S4(m->jcode + p + 1);
+                       CHECK_BYTECODE_INDEX(i);
+                       MARK_BASICBLOCK(i);
+                       blockend = true;
+                       OP_INSINDEX(opcode, i);
+                       break;
+
+               case JAVA_JSR:
+                       i = p + SUCK_BE_S2(m->jcode + p + 1);
+jsr_tail:
+                       CHECK_BYTECODE_INDEX(i);
+                       MARK_BASICBLOCK(i);
                        blockend = true;
-                       OP1(opcode, i);
+                       OP_PREPARE_ZEROFLAGS(JAVA_JSR);
+                       iptr->sx.s23.s3.jsrtarget.insindex = i;
+                       PINC;
                        break;
 
+               case JAVA_JSR_W:
+                       i = p + SUCK_BE_S4(m->jcode + p + 1);
+                       goto jsr_tail;
+
                case JAVA_RET:
-                       if (!iswide) {
-                               i = code_get_u1(p + 1,inline_env->method);
-                       } else {
-                               i = code_get_u2(p + 1,inline_env->method);
+                       if (iswide == false) {
+                               i = SUCK_BE_U1(m->jcode + p + 1);
+                       }
+                       else {
+                               i = SUCK_BE_U2(m->jcode + p + 1);
                                nextp = p + 3;
                                iswide = false;
                        }
                        blockend = true;
-                               
-                       /*
-                         if (inline_env->isinlinedmethod) {
-                         OP1(ICMD_GOTO, inlinfo->stopgp);
-                         break;
-                         }*/
-
-                       OP1LOAD(opcode, i + firstlocal);
+
+                       OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
                        break;
 
                case JAVA_IRETURN:
@@ -821,119 +941,85 @@ SHOWOPCODE(DEBUG4)
                case JAVA_DRETURN:
                case JAVA_ARETURN:
                case JAVA_RETURN:
-                       if (inline_env->isinlinedmethod) {
-                               /*                                      if (p==m->jcodelength-1) {*/ /* return is at end of inlined method */
-                               /*                                              OP(ICMD_NOP); */
-                               /*                                              break; */
-                               /*                                      } */
-                               if (nextp>inline_env->method->jcodelength-1) {
-                                       /* OP1(ICMD_GOTO, inlinfo->stopgp);
-                                          OP(ICMD_NOP);
-                                          OP(ICMD_NOP);
-                                       */
-                                       blockend=true;
-                                       break;
-                               } /* JJJJJJJ */
-                               blockend = true;
-                               OP1(ICMD_GOTO, inlinfo->stopgp);
-                               break;
-                       }
-
                        blockend = true;
-                       /* zero val.a so no patcher is inserted */
-                       /* the type checker may set this later  */
-                       iptr->val.a = NULL;
+                       /* XXX ARETURN will need a flag in the typechecker */
                        OP(opcode);
                        break;
 
                case JAVA_ATHROW:
                        blockend = true;
-                       /* zero val.a so no patcher is inserted */
-                       /* the type checker may set this later  */
-                       iptr->val.a = NULL;
+                       /* XXX ATHROW will need a flag in the typechecker */
                        OP(opcode);
                        break;
-                               
+
 
                /* table jumps ********************************************************/
 
                case JAVA_LOOKUPSWITCH:
                        {
                                s4 num, j;
-                               s4 *tablep;
-                               s4 prevvalue=0;
-
+                               lookup_target_t *lookup;
+#if defined(ENABLE_VERIFIER)
+                               s4 prevvalue = 0;
+#endif
                                blockend = true;
                                nextp = ALIGN((p + 1), 4);
 
-                               if (nextp + 8 > inline_env->method->jcodelength) {
-                                       *exceptionptr = new_verifyerror(inline_env->method,
-                                                       "Unexpected end of bytecode");
-                                       return NULL;
-                               }
-
-                               if (!useinlining) {
-                                       tablep = (s4 *) (inline_env->method->jcode + nextp);
+                               CHECK_END_OF_BYTECODE(nextp + 8);
 
-                               } else {
-                                       num = code_get_u4(nextp + 4, inline_env->method);
-                                       tablep = DMNEW(s4, num * 2 + 2);
-                               }
-
-                               OP2A(opcode, 0, tablep, currentline);
+                               OP_PREPARE_ZEROFLAGS(opcode);
 
                                /* default target */
 
-                               j =  p + code_get_s4(nextp, inline_env->method);
-                               if (useinlining) 
-                                       j = label_index[j];
-                               *tablep = j;     /* restore for little endian */
-                               tablep++;
+                               j = p + SUCK_BE_S4(m->jcode + nextp);
+                               iptr->sx.s23.s3.lookupdefault.insindex = j;
                                nextp += 4;
-                               bound_check(j);
-                               block_insert(j);
+                               CHECK_BYTECODE_INDEX(j);
+                               MARK_BASICBLOCK(j);
 
                                /* number of pairs */
 
-                               num = code_get_u4(nextp, inline_env->method);
-                               *tablep = num;
-                               tablep++;
+                               num = SUCK_BE_U4(m->jcode + nextp);
+                               iptr->sx.s23.s2.lookupcount = num;
                                nextp += 4;
 
-                               if (nextp + 8 * num > inline_env->method->jcodelength) {
-                                       *exceptionptr = new_verifyerror(inline_env->method,
-                                               "Unexpected end of bytecode");
-                                       return NULL;
-                               }
+                               /* allocate the intermediate code table */
+
+                               lookup = DMNEW(lookup_target_t, num);
+                               iptr->dst.lookup = lookup;
+
+                               /* iterate over the lookup table */
+
+                               CHECK_END_OF_BYTECODE(nextp + 8 * num);
 
                                for (i = 0; i < num; i++) {
                                        /* value */
 
-                                       j = code_get_s4(nextp, inline_env->method);
-                                       *tablep = j; /* restore for little endian */
-                                       tablep++;
+                                       j = SUCK_BE_S4(m->jcode + nextp);
+                                       lookup->value = j;
+
                                        nextp += 4;
 
+#if defined(ENABLE_VERIFIER)
                                        /* check if the lookup table is sorted correctly */
-                                       
+
                                        if (i && (j <= prevvalue)) {
-                                               *exceptionptr = new_verifyerror(m, "Unsorted lookup switch");
-                                               return NULL;
+                                               exceptions_throw_verifyerror(m, "Unsorted lookup switch");
+                                               return false;
                                        }
                                        prevvalue = j;
-
+#endif
                                        /* target */
 
-                                       j = p + code_get_s4(nextp,inline_env->method);
-                                       if (useinlining)
-                                               j = label_index[j];
-                                       *tablep = j; /* restore for little endian */
-                                       tablep++;
+                                       j = p + SUCK_BE_S4(m->jcode + nextp);
+                                       lookup->target.insindex = j;
+                                       lookup++;
                                        nextp += 4;
-                                       bound_check(j);
-                                       block_insert(j);
+                                       CHECK_BYTECODE_INDEX(j);
+                                       MARK_BASICBLOCK(j);
                                }
 
+                               PINC;
                                break;
                        }
 
@@ -941,79 +1027,66 @@ SHOWOPCODE(DEBUG4)
                case JAVA_TABLESWITCH:
                        {
                                s4 num, j;
-                               s4 *tablep;
+                               s4 deftarget;
+                               branch_target_t *table;
 
                                blockend = true;
                                nextp = ALIGN((p + 1), 4);
-                               if (nextp + 12 > inline_env->method->jcodelength) {
-                                       *exceptionptr = new_verifyerror(inline_env->method,
-                                               "Unexpected end of bytecode");
-                                       return NULL;
-                               }
 
-                               if (!useinlining) {
-                                       tablep = (s4 *) (inline_env->method->jcode + nextp);
+                               CHECK_END_OF_BYTECODE(nextp + 12);
 
-                               } else {
-                                       num = code_get_u4(nextp + 8,inline_env->method) - code_get_u4(nextp + 4,inline_env->method);
-                                       tablep = DMNEW(s4, num + 1 + 3);
-                               }
-
-                               OP2A(opcode, 0, tablep, currentline);
+                               OP_PREPARE_ZEROFLAGS(opcode);
 
                                /* default target */
 
-                               j = p + code_get_s4(nextp, inline_env->method);
-                               if (useinlining)
-                                       j = label_index[j];
-                               *tablep = j;     /* restore for little endian */
-                               tablep++;
+                               deftarget = p + SUCK_BE_S4(m->jcode + nextp);
                                nextp += 4;
-                               bound_check(j);
-                               block_insert(j);
+                               CHECK_BYTECODE_INDEX(deftarget);
+                               MARK_BASICBLOCK(deftarget);
 
                                /* lower bound */
 
-                               j = code_get_s4(nextp, inline_env->method);
-                               *tablep = j;     /* restore for little endian */
-                               tablep++;
+                               j = SUCK_BE_S4(m->jcode + nextp);
+                               iptr->sx.s23.s2.tablelow = j;
                                nextp += 4;
 
                                /* upper bound */
 
-                               num = code_get_s4(nextp, inline_env->method);
-                               *tablep = num;   /* restore for little endian */
-                               tablep++;
+                               num = SUCK_BE_S4(m->jcode + nextp);
+                               iptr->sx.s23.s3.tablehigh = num;
                                nextp += 4;
 
-                               num -= j;  /* difference of upper - lower */
+                               /* calculate the number of table entries */
+
+                               num = num - j + 1;
 
-                               if (num < 0) {
-                                       *exceptionptr = new_verifyerror(inline_env->method,
+#if defined(ENABLE_VERIFIER)
+                               if (num < 1) {
+                                       exceptions_throw_verifyerror(m,
                                                        "invalid TABLESWITCH: upper bound < lower bound");
-                                       return NULL;
+                                       return false;
                                }
+#endif
+                               /* create the intermediate code table */
+                               /* the first entry is the default target */
 
-                               if (nextp + 4 * (num + 1) > inline_env->method->jcodelength) {
-                                       *exceptionptr = new_verifyerror(inline_env->method,
-                                               "Unexpected end of bytecode");
-                                       return NULL;
-                               }
+                               table = MNEW(branch_target_t, 1 + num);
+                               iptr->dst.table = table;
+                               (table++)->insindex = deftarget;
 
-                               for (i = 0; i <= num; i++) {
-                                       j = p + code_get_s4(nextp,inline_env->method);
-                                       if (useinlining) {
-                                               /*printf("TABLESWITCH: j before mapping=%ld\n",j);*/
-                                               j = label_index[j];
-                                       }
-                                       *tablep = j; /* restore for little endian */
-                                       tablep++;
+                               /* iterate over the target table */
+
+                               CHECK_END_OF_BYTECODE(nextp + 4 * num);
+
+                               for (i = 0; i < num; i++) {
+                                       j = p + SUCK_BE_S4(m->jcode + nextp);
+                                       (table++)->insindex = j;
                                        nextp += 4;
-                                       bound_check(j);
-                                       block_insert(j);
-                                       /*printf("TABLESWITCH: block_insert(%ld)\n",j);*/
+                                       CHECK_BYTECODE_INDEX(j);
+                                       MARK_BASICBLOCK(j);
                                }
 
+                               PINC;
                                break;
                        }
 
@@ -1022,7 +1095,7 @@ SHOWOPCODE(DEBUG4)
 
                case JAVA_AASTORE:
                        OP(opcode);
-                       inline_env->method->isleafmethod = false;
+                       jd->isleafmethod = false;
                        break;
 
                case JAVA_GETSTATIC:
@@ -1032,36 +1105,38 @@ SHOWOPCODE(DEBUG4)
                        {
                                constant_FMIref  *fr;
                                unresolved_field *uf;
-                               fieldinfo        *fi;
 
-                               i = code_get_u2(p + 1, inline_env->method);
-                               fr = class_getconstant(inline_env->method->class, i,
-                                                                          CONSTANT_Fieldref);
+                               i = SUCK_BE_U2(m->jcode + p + 1);
+                               fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
                                if (!fr)
-                                       return NULL;
+                                       return false;
 
-                               OP2A_NOINC(opcode, fr->parseddesc.fd->type, fr, currentline);
+                               OP_PREPARE_ZEROFLAGS(opcode);
+                               iptr->sx.s23.s3.fmiref = fr;
 
-                               if (!(uf = create_unresolved_field(inline_env->method->class,
-                                                                                                  inline_env->method,
-                                                                                                  iptr)))
-                                       return NULL;
+                               /* only with -noverify, otherwise the typechecker does this */
 
-                               /* store unresolved_field pointer */
+#if defined(ENABLE_VERIFIER)
+                               if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
+#endif
+                                       result = resolve_field_lazy(m, fr);
+                                       if (result == resolveFailed)
+                                               return false;
 
-                               iptr->target = uf;
+                                       if (result != resolveSucceeded) {
+                                               uf = resolve_create_unresolved_field(m->class, m, iptr);
 
-                               /* only with -noverify, otherwise the typechecker does this */
+                                               if (uf == NULL)
+                                                       return false;
 
-                               if (!opt_verify) {
-                                       if (!resolve_field(uf, resolveLazy, &fi))
-                                               return NULL;
+                                               /* store the unresolved_field pointer */
 
-                                       iptr->val.a = fi;
-
-                               } else {
-                                       iptr->val.a = NULL;
+                                               iptr->sx.s23.s3.uf = uf;
+                                               iptr->flags.bits = INS_FLAG_UNRESOLVED;
+                                       }
+#if defined(ENABLE_VERIFIER)
                                }
+#endif
                                PINC;
                        }
                        break;
@@ -1070,244 +1145,186 @@ SHOWOPCODE(DEBUG4)
                /* method invocation **************************************************/
 
                case JAVA_INVOKESTATIC:
-                       i = code_get_u2(p + 1, inline_env->method);
-                       {
-                               constant_FMIref   *mr;
-                               methoddesc        *md;
-                               unresolved_method *um;
-                               methodinfo        *mi;
-
-                               inline_env->method->isleafmethod = false;
-
-                               mr = class_getconstant(inline_env->method->class, i,
-                                                                          CONSTANT_Methodref);
-                               if (!mr)
-                                       return NULL;
+                       i = SUCK_BE_U2(m->jcode + p + 1);
+                       mr = class_getconstant(m->class, i, CONSTANT_Methodref);
 
-                               md = mr->parseddesc.md;
+                       if (mr == NULL)
+                               return false;
 
-                               if (!md->params)
-                                       if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
-                                               return NULL;
+                       md = mr->parseddesc.md;
 
-                               OP2A_NOINC(opcode, 0, mr, currentline);
+                       if (md->params == NULL)
+                               if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
+                                       return false;
 
-                               um = create_unresolved_method(inline_env->method->class,
-                                                                                         inline_env->method, iptr);
+                       goto invoke_method;
 
-                               if (!um)
-                                       return NULL;
-
-                               /* store the unresolved_method pointer */
-
-                               iptr->target = um;
-
-                               /* only with -noverify, otherwise the typechecker does this */
+               case JAVA_INVOKEINTERFACE:
+                       i = SUCK_BE_U2(m->jcode + p + 1);
 
-                               if (!opt_verify) {
-                                       if (!resolve_method(um, resolveLazy, &mi))
-                                               return NULL;
+                       mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
 
-                                       iptr->val.a = mi;
-                               }
-                               else {
-                                       iptr->val.a = NULL;
-                               }
-                               PINC;
-                       }
-                       break;
+                       goto invoke_nonstatic_method;
 
                case JAVA_INVOKESPECIAL:
                case JAVA_INVOKEVIRTUAL:
-                       {
-                               constant_FMIref   *mr;
-                               methoddesc        *md;
-                               unresolved_method *um;
-                               methodinfo        *mi;
+                       i = SUCK_BE_U2(m->jcode + p + 1);
+                       mr = class_getconstant(m->class, i, CONSTANT_Methodref);
 
-                               inline_env->method->isleafmethod = false;
+invoke_nonstatic_method:
+                       if (mr == NULL)
+                               return false;
 
-                               i = code_get_u2(p + 1, inline_env->method);
-                               mr = class_getconstant(inline_env->method->class, i,
-                                                                          CONSTANT_Methodref);
-                               if (!mr)
-                                       return NULL;
+                       md = mr->parseddesc.md;
 
-                               md = mr->parseddesc.md;
+                       if (md->params == NULL)
+                               if (!descriptor_params_from_paramtypes(md, 0))
+                                       return false;
 
-                               if (!md->params)
-                                       if (!descriptor_params_from_paramtypes(md, 0))
-                                               return NULL;
-                               
-                               OP2A_NOINC(opcode, 0, mr, currentline);
+invoke_method:
+                       jd->isleafmethod = false;
 
-                               um = create_unresolved_method(inline_env->method->class,
-                                                                                         inline_env->method, iptr);
+                       OP_PREPARE_ZEROFLAGS(opcode);
+                       iptr->sx.s23.s3.fmiref = mr;
 
-                               if (!um)
-                                       return NULL;
+                       /* only with -noverify, otherwise the typechecker does this */
 
-                               /* store the unresolved_method* */
+#if defined(ENABLE_VERIFIER)
+                       if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
+#endif
+                               result = resolve_method_lazy(m, mr, 
+                                               (opcode == JAVA_INVOKESPECIAL));
+                               if (result == resolveFailed)
+                                       return false;
 
-                               iptr->target = um;
+                               if (result == resolveSucceeded) {
+                                       methodinfo *mi = iptr->sx.s23.s3.fmiref->p.method;
 
-                               /* only with -noverify, otherwise the typechecker does this */
+                                       /* if this call is monomorphic, turn it into an INVOKESPECIAL */
 
-                               if (!opt_verify) {
-                                       if (!resolve_method(um, resolveLazy, &mi))
-                                               return NULL;
+                                       assert(IS_FMIREF_RESOLVED(iptr->sx.s23.s3.fmiref));
 
-                                       iptr->val.a = mi;
+                                       if ((iptr->opc == ICMD_INVOKEVIRTUAL)
+                                               && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
+                                       {
+                                               iptr->opc = ICMD_INVOKESPECIAL;
+                                       }
                                }
                                else {
-                                       iptr->val.a = NULL;
-                               }
-                               PINC;
-                       }
-                       break;
-
-               case JAVA_INVOKEINTERFACE:
-                       i = code_get_u2(p + 1, inline_env->method);
-                       {
-                               constant_FMIref   *mr;
-                               methoddesc        *md;
-                               unresolved_method *um;
-                               methodinfo        *mi;
-                               
-                               inline_env->method->isleafmethod = false;
-
-                               mr = class_getconstant(inline_env->method->class, i,
-                                                                          CONSTANT_InterfaceMethodref);
-                               if (!mr)
-                                       return NULL;
-
-                               md = mr->parseddesc.md;
+                                       um = resolve_create_unresolved_method(m->class, m, mr,
+                                                       (opcode == JAVA_INVOKESTATIC),
+                                                       (opcode == JAVA_INVOKESPECIAL));
 
-                               if (!md->params)
-                                       if (!descriptor_params_from_paramtypes(md, 0))
-                                               return NULL;
+                                       if (!um)
+                                               return false;
 
-                               OP2A_NOINC(opcode, 0, mr, currentline);
+                                       /* store the unresolved_method pointer */
 
-                               um = create_unresolved_method(inline_env->method->class,
-                                                                                         inline_env->method, iptr);
-
-                               if (!um)
-                                       return NULL;
-
-                               /* store the unresolved_method* */
-
-                               iptr->target = um;
-
-                               /* only with -noverify, otherwise the typechecker does this */
-
-                               if (!opt_verify) {
-                                       if (!resolve_method(um, resolveLazy, &mi))
-                                               return NULL;
-
-                                       iptr->val.a = mi;
-                               }
-                               else {
-                                       iptr->val.a = NULL;
+                                       iptr->sx.s23.s3.um = um;
+                                       iptr->flags.bits = INS_FLAG_UNRESOLVED;
                                }
-                               PINC;
+#if defined(ENABLE_VERIFIER)
                        }
+#endif
+                       PINC;
                        break;
 
-               /* miscellaneous object operations ************************************/
+               /* instructions taking class arguments ********************************/
 
                case JAVA_NEW:
-                       i = code_get_u2(p + 1, inline_env->method);
-                       cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+                       i = SUCK_BE_U2(m->jcode + p + 1);
+                       cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
                        if (!cr)
-                               return NULL;
+                               return false;
 
-                       if (!resolve_classref(inline_env->method, cr, resolveLazy, true, true,
-                                                                 &c))
-                               return NULL;
+                       if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
+                               return false;
 
-                       LOADCONST_A_BUILTIN(c, cr);
+                       INSTRUCTIONS_CHECK(2);
+                       OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
                        bte = builtintable_get_internal(BUILTIN_new);
-                       BUILTIN(bte, true, NULL, currentline);
+                       OP_BUILTIN_CHECK_EXCEPTION(bte);
                        s_count++;
                        break;
 
                case JAVA_CHECKCAST:
-                       i = code_get_u2(p + 1, inline_env->method);
-                       cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
-                       if (!cr)
-                               return NULL;
+                       i = SUCK_BE_U2(m->jcode + p + 1);
+                       cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
+                       if (cr == NULL)
+                               return false;
 
-                       if (!resolve_classref(inline_env->method, cr, resolveLazy, true,
-                                                                 true, &c))
-                               return NULL;
+                       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);
-                               inline_env->method->isleafmethod = false;
-
-                       else {
+                               flags = INS_FLAG_ARRAY;
+                               jd->isleafmethod = false;
+                       }
+                       else {
                                /* object type cast-check */
-                               OP2AT(opcode, 1, c, cr, currentline);
+                               flags = 0;
                        }
+                       OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
                        break;
 
                case JAVA_INSTANCEOF:
-                       i = code_get_u2(p + 1,inline_env->method);
-                       cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
-                       if (!cr)
-                               return NULL;
+                       i = SUCK_BE_U2(m->jcode + p + 1);
+                       cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
+                       if (cr == NULL)
+                               return false;
 
-                       if (!resolve_classref(inline_env->method, cr, resolveLazy, true, true, &c))
-                               return NULL;
+                       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);
+                               INSTRUCTIONS_CHECK(2);
+                               OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
                                bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
-                               BUILTIN(bte, false, NULL, currentline);
+                               OP_BUILTIN_NO_EXCEPTION(bte);
                                s_count++;
-
-                       else {
+                       }
+                       else {
                                /* object type cast-check */
-                               OP2AT(opcode, 1, c, cr, currentline);
+                               OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
                        }
                        break;
 
+               /* synchronization instructions ***************************************/
+
                case JAVA_MONITORENTER:
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
                        if (checksync) {
-                               OP(ICMD_CHECKNULL);
-                               bte = builtintable_get_internal(BUILTIN_monitorenter);
-                               BUILTIN(bte, false, NULL, currentline);
-                       else
+                               bte = builtintable_get_internal(LOCK_monitor_enter);
+                               OP_BUILTIN_CHECK_EXCEPTION(bte);
+                       }
+                       else
 #endif
-                               {
-                                       OP(ICMD_CHECKNULL);
-                                       OP(ICMD_POP);
-                               }
+                       {
+                               OP(ICMD_CHECKNULL_POP);
+                       }
                        break;
 
                case JAVA_MONITOREXIT:
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
                        if (checksync) {
-                               bte = builtintable_get_internal(BUILTIN_monitorexit);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } else
+                               bte = builtintable_get_internal(LOCK_monitor_exit);
+                               OP_BUILTIN_CHECK_EXCEPTION(bte);
+                       }
+                       else
 #endif
-                               {
-                                       OP(ICMD_POP);
-                               }
+                       {
+                               OP(ICMD_CHECKNULL_POP);
+                       }
                        break;
 
-               /* any other basic operation ******************************************/
+               /* arithmetic instructions that may become builtin functions **********/
 
                case JAVA_IDIV:
 #if !SUPPORT_DIVISION
                        bte = builtintable_get_internal(BUILTIN_idiv);
-                       OP2A(opcode, bte->md->paramcount, bte, currentline);
-                       inline_env->method->isleafmethod = false;
+                       OP_BUILTIN_ARITHMETIC(opcode, bte);
 #else
                        OP(opcode);
 #endif
@@ -1316,8 +1333,7 @@ SHOWOPCODE(DEBUG4)
                case JAVA_IREM:
 #if !SUPPORT_DIVISION
                        bte = builtintable_get_internal(BUILTIN_irem);
-                       OP2A(opcode, bte->md->paramcount, bte, currentline);
-                       inline_env->method->isleafmethod = false;
+                       OP_BUILTIN_ARITHMETIC(opcode, bte);
 #else
                        OP(opcode);
 #endif
@@ -1326,8 +1342,7 @@ SHOWOPCODE(DEBUG4)
                case JAVA_LDIV:
 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
                        bte = builtintable_get_internal(BUILTIN_ldiv);
-                       OP2A(opcode, bte->md->paramcount, bte, currentline);
-                       inline_env->method->isleafmethod = false;
+                       OP_BUILTIN_ARITHMETIC(opcode, bte);
 #else
                        OP(opcode);
 #endif
@@ -1336,8 +1351,7 @@ SHOWOPCODE(DEBUG4)
                case JAVA_LREM:
 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
                        bte = builtintable_get_internal(BUILTIN_lrem);
-                       OP2A(opcode, bte->md->paramcount, bte, currentline);
-                       inline_env->method->isleafmethod = false;
+                       OP_BUILTIN_ARITHMETIC(opcode, bte);
 #else
                        OP(opcode);
 #endif
@@ -1348,7 +1362,7 @@ SHOWOPCODE(DEBUG4)
                        OP(opcode);
 #else
                        bte = builtintable_get_internal(BUILTIN_frem);
-                       BUILTIN(bte, false, NULL, currentline);
+                       OP_BUILTIN_NO_EXCEPTION(bte);
 #endif
                        break;
 
@@ -1357,7 +1371,7 @@ SHOWOPCODE(DEBUG4)
                        OP(opcode);
 #else
                        bte = builtintable_get_internal(BUILTIN_drem);
-                       BUILTIN(bte, false, NULL, currentline);
+                       OP_BUILTIN_NO_EXCEPTION(bte);
 #endif
                        break;
 
@@ -1365,54 +1379,61 @@ SHOWOPCODE(DEBUG4)
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_f2i);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } else
+                               OP_BUILTIN_NO_EXCEPTION(bte);
+                       }
+                       else
 #endif
-                               {
-                                       OP(opcode);
-                               }
+                       {
+                               OP(opcode);
+                       }
                        break;
 
                case JAVA_F2L:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_f2l);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } else 
+                               OP_BUILTIN_NO_EXCEPTION(bte);
+                       }
+                       else
 #endif
-                               {
-                                       OP(opcode);
-                               }
+                       {
+                               OP(opcode);
+                       }
                        break;
 
                case JAVA_D2I:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_d2i);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } else
+                               OP_BUILTIN_NO_EXCEPTION(bte);
+                       }
+                       else
 #endif
-                               {
-                                       OP(opcode);
-                               }
+                       {
+                               OP(opcode);
+                       }
                        break;
 
                case JAVA_D2L:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_d2l);
-                               BUILTIN(bte, false, NULL, currentline);
-                       } else
+                               OP_BUILTIN_NO_EXCEPTION(bte);
+                       }
+                       else
 #endif
-                               {
-                                       OP(opcode);
-                               }
+                       {
+                               OP(opcode);
+                       }
                        break;
 
+               /* invalid opcodes ****************************************************/
+
+                       /* check for invalid opcodes if the verifier is enabled */
+#if defined(ENABLE_VERIFIER)
                case JAVA_BREAKPOINT:
-                       *exceptionptr =
-                               new_verifyerror(m, "Quick instructions shouldn't appear yet.");
-                       return NULL;
+                       exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
+                       return false;
 
                case 186: /* unused opcode */
                case 203:
@@ -1468,174 +1489,238 @@ SHOWOPCODE(DEBUG4)
                case 253:
                case 254:
                case 255:
-                       *exceptionptr =
-                               new_verifyerror(inline_env->method,"Illegal opcode %d at instr %d\n",
-                                                                 opcode, ipc);
-                       return NULL;
+                       exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
+                                                                                opcode, ipc);
+                       return false;
                        break;
+#endif /* defined(ENABLE_VERIFIER) */
+
+               /* opcodes that don't require translation *****************************/
 
                default:
+                       /* straight-forward translation to ICMD */
                        OP(opcode);
                        break;
-                               
+
                } /* end switch */
 
+               /* verifier checks ****************************************************/
+
+#if defined(ENABLE_VERIFIER)
                /* If WIDE was used correctly, iswide should have been reset by now. */
-               if (iswide && opcode != JAVA_WIDE) {
-                       *exceptionptr = new_verifyerror(inline_env->method,
+               if (iswide) {
+                       exceptions_throw_verifyerror(m,
                                        "Illegal instruction: WIDE before incompatible opcode");
-                       return NULL;
-               }
-
-#if defined(USE_INLINING)
-               /* if (inline_env->isinlinedmethod && p == inline_env->method->jcodelength - 1) { */ /* end of an inlined method */
-               if (inline_env->isinlinedmethod && (nextp >= inline_env->method->jcodelength) ) { /* end of an inlined method */
-                       /*                printf("setting gp from %d to %d\n",gp, inlinfo->stopgp); */
-                       gp = inlinfo->stopgp; 
-                       inlining_restore_compiler_variables();
-                       OP(ICMD_INLINE_END);
-/*label_index = inlinfo->label_index;*/
-
-METHINFOt(inline_env->method,"AFTER RESTORE : ",DEBUG);
-                       list_remove(inlinfo->inlinedmethods, list_first(inlinfo->inlinedmethods));
-                       if (inlinfo->inlinedmethods == NULL) { /* JJJJ */
-                               nextgp = -1;
-                       } else {
-                               tmpinlinf = list_first(inlinfo->inlinedmethods);
-                               nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
-                       }
-                       /*                printf("nextpgp: %d\n", nextgp); */
-                       label_index=inlinfo->label_index;
-                       firstlocal = inlinfo->firstlocal;
+                       return false;
                }
-#endif /* defined(USE_INLINING) */
+#endif /* defined(ENABLE_VERIFIER) */
 
        } /* end for */
 
+       if (JITDATA_HAS_FLAG_REORDER(jd)) {
+               /* add a NOP to the last basic block */
 
+               INSTRUCTIONS_CHECK(1);
+               OP(ICMD_NOP);
+       }
+
+       /*** END OF LOOP **********************************************************/
+
+       /* assert that we did not write more ICMDs than allocated */
+
+       assert(ipc <= pd.instructionslength);
+       assert(ipc == (iptr - pd.instructions));
+
+       /*** verifier checks ******************************************************/
+
+#if defined(ENABLE_VERIFIER)
        if (p != m->jcodelength) {
-               printf("p (%d) != m->jcodelength (%d)\n",p,m->jcodelength);
-               *exceptionptr = new_verifyerror(inline_env->method,
+               exceptions_throw_verifyerror(m,
                                "Command-sequence crosses code-boundary");
-               return NULL;
+               return false;
        }
 
        if (!blockend) {
-               *exceptionptr = new_verifyerror(m, "Falling off the end of the code");
-               return NULL;
+               exceptions_throw_verifyerror(m, "Falling off the end of the code");
+               return false;
        }
+#endif /* defined(ENABLE_VERIFIER) */
+
+       /*** setup the methodinfo, allocate stack and basic blocks ****************/
 
        /* adjust block count if target 0 is not first intermediate instruction */
 
-       if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1))
+       if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1))
                b_count++;
 
        /* copy local to method variables */
 
-       m->instructioncount = ipc;
-       m->basicblockcount = b_count;
-       m->stackcount = s_count + m->basicblockcount * m->maxstack;
+       jd->instructions = pd.instructions;
+       jd->instructioncount = ipc;
+       jd->basicblockcount = b_count;
+       jd->stackcount = s_count + jd->basicblockcount * m->maxstack; /* in-stacks */
 
        /* allocate stack table */
 
-       m->stack = DMNEW(stackelement, m->stackcount);
+       jd->stack = DMNEW(stackelement, jd->stackcount);
 
-       {
-               basicblock *bptr;
+       /* build basic block list */
 
-               bptr = m->basicblocks = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
+       bptr = jd->basicblocks = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
 
-               b_count = 0;
-               m->c_debug_nr = 0;
-       
-               /* additional block if target 0 is not first intermediate instruction */
-
-               if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1)) {
-                       bptr->iinstr = m->instructions;
-                       bptr->mpc = -1;
-                       bptr->flags = -1;
-                       bptr->type = BBTYPE_STD;
-                       bptr->branchrefs = NULL;
-                       bptr->pre_count = 0;
-                       bptr->debug_nr = m->c_debug_nr++;
-                       bptr++;
-                       b_count++;
-                       (bptr - 1)->next = bptr;
-               }
+       /* zero out all basic block structures */
+
+       MZERO(bptr, basicblock, b_count + 1);
 
-               /* allocate blocks */
+       b_count = 0;
 
-               for (p = 0; p < inline_env->cumjcodelength; p++) { 
-               /* for (p = 0; p < m->jcodelength; p++) { */
-                       if (m->basicblockindex[p] & 1) {
-                               /* Check if this block starts at the beginning of an          */
-                               /* instruction.                                               */
+       /* additional block if target 0 is not first intermediate instruction */
 
-                               if (!instructionstart[p]) {
-                                       *exceptionptr = new_verifyerror(inline_env->method,
+       if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1)) {
+               BASICBLOCK_INIT(bptr, m);
+
+               bptr->iinstr = jd->instructions;
+               /* bptr->icount is set when the next block is allocated */
+
+               bptr->nr = b_count++;
+               bptr++;
+               bptr[-1].next = bptr;
+       }
+
+       /* allocate blocks */
+
+       for (p = 0; p < m->jcodelength; p++) {
+               if (jd->basicblockindex[p] & 1) {
+#if defined(ENABLE_VERIFIER)
+                       /* Check if this block starts at the beginning of an
+                          instruction. */
+
+                       if (!pd.instructionstart[p]) {
+                               exceptions_throw_verifyerror(m,
                                                "Branch into middle of instruction");
-                                       return NULL;
-                               }
+                               return false;
+                       }
+#endif
 
-                               /* allocate the block */
-                               bptr->iinstr = m->instructions + (m->basicblockindex[p] >> 1);
-                               bptr->debug_nr = m->c_debug_nr++;
-                               if (b_count != 0)
-                                       (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
-                               bptr->mpc = -1;
-                               bptr->flags = -1;
-                               bptr->lflags = 0;
-                               bptr->type = BBTYPE_STD;
-                               bptr->branchrefs = NULL;
-                               m->basicblockindex[p] = b_count;
-                               bptr->pre_count = 0;
-                               bptr++;
-                               b_count++;
-                               (bptr - 1)->next = bptr;
+                       /* allocate the block */
+
+                       BASICBLOCK_INIT(bptr, m);
+
+                       bptr->iinstr = jd->instructions + (jd->basicblockindex[p] >> 1);
+                       if (b_count) {
+                               bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
                        }
-               }
+                       /* bptr->icount is set when the next block is allocated */
 
-               /* allocate additional block at end */
-
-               bptr->instack = bptr->outstack = NULL;
-               bptr->indepth = bptr->outdepth = 0;
-               bptr->iinstr = NULL;
-               (bptr - 1)->icount = (m->instructions + m->instructioncount) - (bptr - 1)->iinstr;
-               bptr->icount = 0;
-               bptr->mpc = -1;
-               bptr->flags = -1;
-               bptr->lflags = 0;
-               bptr->type = BBTYPE_STD;
-               bptr->branchrefs = NULL;
-               bptr->pre_count = 0;
-               bptr->debug_nr = m->c_debug_nr++;
-               (bptr - 1)->next = bptr;
-               bptr->next = NULL;
-
-               if (cd->exceptiontablelength > 0) {
-                       cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
+                       jd->basicblockindex[p] = b_count;
+
+                       bptr->nr = b_count++;
+                       bptr++;
+                       bptr[-1].next = bptr;
                }
-               
-               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 == inline_env->method->jcodelength) ? (m->basicblocks + m->basicblockcount /*+ 1*/) : (m->basicblocks + m->basicblockindex[p]);
+       /* set instruction count of last real block */
 
-                       p = cd->exceptiontable[i].handlerpc;
-                       cd->exceptiontable[i].handler = m->basicblocks + m->basicblockindex[p];
-           }
+       if (b_count) {
+               bptr[-1].icount = (jd->instructions + jd->instructioncount) - bptr[-1].iinstr;
        }
 
-#if defined(USE_INLINING)      
-       if (useinlining)
-               inlining_cleanup(inline_env);
+       /* allocate additional block at end */
+
+       BASICBLOCK_INIT(bptr,m);
+       bptr->nr = b_count;
+       jd->basicblockindex[m->jcodelength] = b_count;
+
+       /* set basicblock pointers in exception table */
+
+       if (!parse_resolve_exception_table(jd))
+               return false;
+
+       /* store the local map */
+
+       jd->local_map = local_map;
+
+       /* calculate local variable renaming */
+
+       {
+               s4 nlocals = 0;
+               s4 i;
+
+               s4 *mapptr;
+
+               mapptr = local_map;
+
+               /* iterate over local_map[0..m->maxlocals*5] and set all existing  */
+               /* index,type pairs (local_map[index*5+type]==1) to an unique value */
+               /* -> == new local var index */
+               for(i = 0; i < (m->maxlocals * 5); i++, mapptr++) {
+                       if (*mapptr)
+                               *mapptr = nlocals++;
+                       else
+                               *mapptr = UNUSED;
+               }
+
+               jd->localcount = nlocals;
+
+               /* calculate the (maximum) number of variables needed */
+
+               jd->varcount = 
+                         nlocals                                      /* local variables */
+                       + jd->basicblockcount * 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)
+               if (JITDATA_HAS_FLAG_VERIFY(jd)) {
+                       jd->varcount += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
+                       jd->vartop   += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
+               }
 #endif
+               /* allocate and initialize the variable array */
+
+               jd->var = DMNEW(varinfo, jd->varcount);
+               MZERO(jd->var, varinfo, jd->varcount);
+
+               /* set types of all locals in jd->var */
+
+               for(mapptr = local_map, i = 0; i < (m->maxlocals * 5); i++, mapptr++)
+                       if (*mapptr != UNUSED)
+                               VAR(*mapptr)->type = i%5;
+       }
+
+       /* everything's ok */
+
+       return true;
+
+       /*** goto labels for throwing verifier exceptions *************************/
+
+#if defined(ENABLE_VERIFIER)
+
+throw_unexpected_end_of_bytecode:
+       exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
+       return false;
+
+throw_invalid_bytecode_index:
+       exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
+       return false;
 
-       /* just return methodinfo* to signal everything was ok */
+throw_illegal_local_variable_number:
+       exceptions_throw_verifyerror(m, "Illegal local variable number");
+       return false;
 
-       return m;
+#endif /* ENABLE_VERIFIER */
 }
 
 
@@ -1650,4 +1735,5 @@ METHINFOt(inline_env->method,"AFTER RESTORE : ",DEBUG);
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */