Merged revisions 7797-7917 via svnmerge from
[cacao.git] / src / vm / jit / stack.c
index 8924b8d05ecbc841eeb1b60444f8664015571ba0..b81dfd45e1a62f1a736c595dc7f225b9d6350908 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/stack.c - stack analysis
 
 /* src/vm/jit/stack.c - stack analysis
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-
-   Changes: Edwin Steiner
-            Christian Thalinger
-            Christian Ullrich
-
-   $Id: stack.c 5790 2006-10-16 09:59:52Z edwin $
+   $Id: stack.c 7908 2007-05-15 09:55:17Z christian $
 
 */
 
 
 */
 
@@ -53,9 +45,6 @@
 
 #include "vm/global.h"
 #include "vm/builtin.h"
 
 #include "vm/global.h"
 #include "vm/builtin.h"
-#include "vm/options.h"
-#include "vm/resolve.h"
-#include "vm/statistics.h"
 #include "vm/stringlocal.h"
 #include "vm/types.h"
 
 #include "vm/stringlocal.h"
 #include "vm/types.h"
 
 #include "vm/jit/jit.h"
 #include "vm/jit/stack.h"
 
 #include "vm/jit/jit.h"
 #include "vm/jit/stack.h"
 
+#if 0
 #if defined(ENABLE_SSA)
 # include "vm/jit/optimizing/lsra.h"
 # include "vm/jit/optimizing/ssa.h"
 #elif defined(ENABLE_LSRA)
 # include "vm/jit/allocator/lsra.h"
 #endif
 #if defined(ENABLE_SSA)
 # include "vm/jit/optimizing/lsra.h"
 # include "vm/jit/optimizing/ssa.h"
 #elif defined(ENABLE_LSRA)
 # include "vm/jit/allocator/lsra.h"
 #endif
+#endif
+
+#include "vmcore/options.h"
+#include "vm/resolve.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
 
 /*#define STACK_VERBOSE*/
 
 
 /*#define STACK_VERBOSE*/
 
@@ -125,8 +123,11 @@ struct stackdata_t {
     stackptr new;                 /* next free stackelement                   */
     s4 vartop;                    /* next free variable index                 */
     s4 localcount;                /* number of locals (at the start of var)   */
     stackptr new;                 /* next free stackelement                   */
     s4 vartop;                    /* next free variable index                 */
     s4 localcount;                /* number of locals (at the start of var)   */
-    s4 varcount;                  /* total number of variables allocated      */
+    s4 varcount;                  /* maximum number of variables expected     */
+       s4 varsallocated;             /* total number of variables allocated      */
+       s4 maxlocals;                 /* max. number of Java locals               */
     varinfo *var;                 /* variable array (same as jd->var)         */
     varinfo *var;                 /* variable array (same as jd->var)         */
+       s4 *javalocals;               /* map from Java locals to jd->var indices  */
        methodinfo *m;                /* the method being analysed                */
        jitdata *jd;                  /* current jitdata                          */
        basicblock *last_real_block;  /* the last block before the empty one      */
        methodinfo *m;                /* the method being analysed                */
        jitdata *jd;                  /* current jitdata                          */
        basicblock *last_real_block;  /* the last block before the empty one      */
@@ -323,15 +324,18 @@ struct stackdata_t {
 #if defined(ENABLE_VERIFIER)
 #define COPY_VAL_AND_TYPE_VAR(sv, dv)                                \
     do {                                                             \
 #if defined(ENABLE_VERIFIER)
 #define COPY_VAL_AND_TYPE_VAR(sv, dv)                                \
     do {                                                             \
-        (dv)->type = (sv)->type;                                     \
-        (dv)->vv  = (sv)->vv;                                        \
-        (dv)->SBRSTART = (sv)->SBRSTART;                             \
+        if (((dv)->type = (sv)->type) == TYPE_RET) {                 \
+            (dv)->vv  = (sv)->vv;                                    \
+            (dv)->SBRSTART = (sv)->SBRSTART;                         \
+        }                                                            \
     } while (0)
 #else
 #define COPY_VAL_AND_TYPE_VAR(sv, dv)                                \
     do {                                                             \
         (dv)->type = (sv)->type;                                     \
     } while (0)
 #else
 #define COPY_VAL_AND_TYPE_VAR(sv, dv)                                \
     do {                                                             \
         (dv)->type = (sv)->type;                                     \
-        (dv)->vv  = (sv)->vv;                                        \
+        if (((dv)->type = (sv)->type) == TYPE_RET) {                 \
+            (dv)->vv  = (sv)->vv;                                    \
+        }                                                            \
     } while (0)
 #endif
 
     } while (0)
 #endif
 
@@ -492,7 +496,7 @@ struct stackdata_t {
 
 #define BRANCH_TARGET(bt, tempbptr)                                  \
     do {                                                             \
 
 #define BRANCH_TARGET(bt, tempbptr)                                  \
     do {                                                             \
-        tempbptr = BLOCK_OF((bt).insindex);                          \
+        tempbptr = (bt).block;                                       \
         tempbptr = stack_mark_reached(&sd, tempbptr, curstack,       \
                                       stackdepth);                   \
         if (tempbptr == NULL)                                        \
         tempbptr = stack_mark_reached(&sd, tempbptr, curstack,       \
                                       stackdepth);                   \
         if (tempbptr == NULL)                                        \
@@ -516,6 +520,8 @@ static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
+static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, 
+                                                                        stackptr curstack);
 #endif
 
 
 #endif
 
 
@@ -534,6 +540,10 @@ bool stack_init(void)
 /* stack_grow_variable_array ***************************************************
 
    Grow the variable array so the given number of additional variables fits in.
 /* stack_grow_variable_array ***************************************************
 
    Grow the variable array so the given number of additional variables fits in.
+   The number is added to `varcount`, which is the maximum number of variables
+   we expect to need at this point. The actual number of variables
+   (`varsallocated`) may be larger than that, in order to avoid too many
+   reallocations.
 
    IN:
       sd...........stack analysis data
 
    IN:
       sd...........stack analysis data
@@ -543,20 +553,23 @@ bool stack_init(void)
 
 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
 {
 
 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
 {
-       s4 newcount;
+       s4 newsize;
 
        assert(num >= 0);
 
 
        assert(num >= 0);
 
-       if (num == 0)
-               return;
+       if (sd->varcount + num > sd->varsallocated) {
+               newsize = 2*sd->varsallocated + num;
 
 
-       /* XXX avoid too many reallocations */
-       newcount = sd->varcount + num;
+               sd->var = DMREALLOC(sd->var, varinfo, sd->varsallocated, newsize);
+               MZERO(sd->var + sd->varsallocated, varinfo, (newsize - sd->varsallocated));
+               sd->varsallocated = newsize;
+               sd->jd->var = sd->var;
+       }
+
+       sd->varcount += num;
+       sd->jd->varcount += num;
 
 
-       sd->var = DMREALLOC(sd->var, varinfo, sd->varcount, newcount);
-       sd->varcount = newcount;
-       sd->jd->var = sd->var;
-       sd->jd->varcount = newcount;
+       assert(sd->varcount <= sd->varsallocated);
 }
 
 
 }
 
 
@@ -611,6 +624,7 @@ static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
 
        clone->iinstr = NULL;
        clone->inlocals = NULL;
 
        clone->iinstr = NULL;
        clone->inlocals = NULL;
+       clone->javalocals = NULL;
        clone->invars = NULL;
 
        clone->original = (b->original) ? b->original : b;
        clone->invars = NULL;
 
        clone->original = (b->original) ? b->original : b;
@@ -621,7 +635,7 @@ static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
 
        stack_append_block(sd, clone);
 
 
        stack_append_block(sd, clone);
 
-       /* allocate space for the invars of the clone */
+       /* reserve space for the invars of the clone */
 
        stack_grow_variable_array(sd, b->indepth);
 
 
        stack_grow_variable_array(sd, b->indepth);
 
@@ -633,6 +647,89 @@ static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
 }
 
 
 }
 
 
+/* stack_create_locals *********************************************************
+   Create the local variables for the start of the given basic block.
+
+   IN:
+      sd...........stack analysis data
+         b............block to create the locals for
+
+*******************************************************************************/
+
+static void stack_create_locals(stackdata_t *sd, basicblock *b)
+{
+       s4       i;
+       s4      *jl;
+       varinfo *dv;
+
+       /* copy the current state of the local variables */
+       /* (one extra local is needed by the verifier)   */
+
+       dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
+       b->inlocals = dv;
+       for (i=0; i<sd->localcount; ++i)
+               *dv++ = sd->var[i];
+
+       /* the current map from java locals to cacao variables */
+
+       jl = DMNEW(s4, sd->maxlocals);
+       b->javalocals = jl;
+       MCOPY(jl, sd->javalocals, s4, sd->maxlocals);
+}
+
+
+/* stack_merge_locals **********************************************************
+   Merge local variables at the beginning of the given basic block.
+
+   IN:
+      sd...........stack analysis data
+         b............the block that is reached
+
+*******************************************************************************/
+
+static void stack_merge_locals(stackdata_t *sd, basicblock *b)
+{
+       s4 i;
+       varinfo *dv;
+       varinfo *sv;
+
+       /* If a javalocal is mapped to different cacao locals along the */
+       /* incoming control-flow edges, it becomes undefined.           */
+
+       for (i=0; i<sd->maxlocals; ++i) {
+               if (b->javalocals[i] != UNUSED && b->javalocals[i] != sd->javalocals[i]) {
+                       b->javalocals[i] = UNUSED;
+                       if (b->flags >= BBFINISHED)
+                               b->flags = BBTYPECHECK_REACHED;
+                       if (b->nr <= sd->bptr->nr)
+                               sd->repeat = true;
+               }
+       }
+
+#if defined(ENABLE_VERIFIER)
+       if (b->inlocals) {
+               for (i=0; i<sd->localcount; ++i) {
+                       dv = b->inlocals + i;
+                       sv = sd->var + i;
+                       if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
+                                       && (sv->SBRSTART != dv->SBRSTART))
+                       {
+#if defined(STACK_VERBOSE)
+                               printf("JSR MISMATCH: setting variable %d to VOID\n", i);
+#endif
+                               dv->type = TYPE_VOID;
+                               if (b->flags >= BBFINISHED)
+                                       b->flags = BBTYPECHECK_REACHED;
+                               sd->repeat = true; /* This is very rare, so just repeat */
+                       }
+               }
+       }
+#endif /* defined(ENABLE_VERIFIER) */
+}
+
+
 /* stack_create_invars *********************************************************
 
    Create the invars for the given basic block. Also make a copy of the locals.
 /* stack_create_invars *********************************************************
 
    Create the invars for the given basic block. Also make a copy of the locals.
@@ -674,13 +771,7 @@ static void stack_create_invars(stackdata_t *sd, basicblock *b,
                COPY_VAL_AND_TYPE_VAR(sv, dv);
        }
 
                COPY_VAL_AND_TYPE_VAR(sv, dv);
        }
 
-       /* copy the current state of the local variables */
-       /* (one extra local is needed by the verifier)   */
-
-       dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
-       b->inlocals = dv;
-       for (i=0; i<sd->localcount; ++i)
-               *dv++ = sd->var[i];
+       stack_create_locals(sd, b);
 }
 
 
 }
 
 
@@ -720,13 +811,7 @@ static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
                }
        }
 
                }
        }
 
-       /* copy the current state of the local variables */
-       /* (one extra local is needed by the verifier)   */
-
-       dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
-       b->inlocals = dv;
-       for (i=0; i<sd->localcount; ++i)
-               *dv++ = sd->var[i];
+       stack_create_locals(sd, b);
 }
 
 
 }
 
 
@@ -832,24 +917,9 @@ static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
                }
 
                if (!separable) {
                }
 
                if (!separable) {
-                       /* XXX mark mixed type variables void */
                        /* XXX cascading collapse? */
                        /* XXX cascading collapse? */
-#if defined(ENABLE_VERIFIER)
-                       if (b->inlocals) {
-                               for (i=0; i<sd->localcount; ++i) {
-                                       dv = b->inlocals + i;
-                                       sv = sd->var + i;
-                                       if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
-                                               && (sv->SBRSTART != dv->SBRSTART))
-                                       {
-                                               dv->type = TYPE_VOID;
-                                               if (b->flags >= BBFINISHED)
-                                                       b->flags = BBTYPECHECK_REACHED;
-                                               sd->repeat = true; /* This is very rare, so just repeat */
-                                       }
-                               }
-                       }
-#endif
+
+                       stack_merge_locals(sd, b);
 
 #if defined(STACK_VERBOSE)
                        printf("------> using L%03d\n", b->nr);
 
 #if defined(STACK_VERBOSE)
                        printf("------> using L%03d\n", b->nr);
@@ -968,24 +1038,9 @@ static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock
                }
 
                if (!separable) {
                }
 
                if (!separable) {
-                       /* XXX mark mixed type variables void */
                        /* XXX cascading collapse? */
                        /* XXX cascading collapse? */
-#if defined(ENABLE_VERIFIER)
-                       if (b->inlocals) {
-                               for (i=0; i<sd->localcount; ++i) {
-                                       dv = b->inlocals + i;
-                                       sv = sd->var + i;
-                                       if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
-                                                       && (sv->SBRSTART != dv->SBRSTART))
-                                       {
-                                               dv->type = TYPE_VOID;
-                                               if (b->flags >= BBFINISHED)
-                                                       b->flags = BBTYPECHECK_REACHED;
-                                               sd->repeat = true; /* This is very rare, so just repeat */
-                                       }
-                               }
-                       }
-#endif
+
+                       stack_merge_locals(sd, b);
 
 #if defined(STACK_VERBOSE)
                        printf("------> using L%03d\n", b->nr);
 
 #if defined(STACK_VERBOSE)
                        printf("------> using L%03d\n", b->nr);
@@ -1063,11 +1118,15 @@ static stackptr stack_create_instack(stackdata_t *sd)
 
 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth) 
 {
 
 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth) 
 {
+       assert(b != NULL);
+
 #if defined(STACK_VERBOSE)
        printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
 #endif
 #if defined(STACK_VERBOSE)
        printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
 #endif
+
        /* mark targets of backward branches */
        /* mark targets of backward branches */
-       if (b <= sd->bptr)
+
+       if (b->nr <= sd->bptr->nr)
                b->bitflags |= BBFLAG_REPLACEMENT;
 
        if (b->flags < BBREACHED) {
                b->bitflags |= BBFLAG_REPLACEMENT;
 
        if (b->flags < BBREACHED) {
@@ -1109,11 +1168,15 @@ static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr c
 
 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
 {
 
 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
 {
+       assert(b != NULL);
+
 #if defined(STACK_VERBOSE)
        printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
 #endif
 #if defined(STACK_VERBOSE)
        printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
 #endif
+
        /* mark targets of backward branches */
        /* mark targets of backward branches */
-       if (b <= sd->bptr)
+
+       if (b->nr <= sd->bptr->nr)
                b->bitflags |= BBFLAG_REPLACEMENT;
 
        if (b->flags < BBREACHED) {
                b->bitflags |= BBFLAG_REPLACEMENT;
 
        if (b->flags < BBREACHED) {
@@ -1139,9 +1202,10 @@ static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *
 
 /* stack_reach_next_block ******************************************************
 
 
 /* stack_reach_next_block ******************************************************
 
-   Mark the following block reached and propagate the outvars of the current block
-   and the current locals to it. This function specializes the target block, 
-   if necessary, and returns a pointer to the specialized target.
+   Mark the following block reached and propagate the outvars of the
+   current block and the current locals to it.  This function
+   specializes the target block, if necessary, and returns a pointer
+   to the specialized target.
 
    IN:
       sd...........stack analysis data
 
    IN:
       sd...........stack analysis data
@@ -1159,7 +1223,8 @@ static bool stack_reach_next_block(stackdata_t *sd)
 
        tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
        tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
 
        tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
        tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
-       if (!tbptr)
+
+       if (tbptr == NULL)
                return false;
 
        if (tbptr != sd->bptr->next) {
                return false;
 
        if (tbptr != sd->bptr->next) {
@@ -1256,12 +1321,11 @@ bool stack_reanalyse_block(stackdata_t *sd)
        s4 blockvarstart;
        s4 invarshift;
        s4 blockvarshift;
        s4 blockvarstart;
        s4 invarshift;
        s4 blockvarshift;
-       s4 i, j;
+       s4 i, varindex;
        s4 *argp;
        branch_target_t *table;
        lookup_target_t *lookup;
        bool superblockend;
        s4 *argp;
        branch_target_t *table;
        lookup_target_t *lookup;
        bool superblockend;
-       bool maythrow;
        bool cloneinstructions;
        exception_entry *ex;
 
        bool cloneinstructions;
        exception_entry *ex;
 
@@ -1285,10 +1349,12 @@ bool stack_reanalyse_block(stackdata_t *sd)
 
                MCOPY(iptr, orig->iinstr, instruction, len);
                iptr[len].opc = ICMD_NOP;
 
                MCOPY(iptr, orig->iinstr, instruction, len);
                iptr[len].opc = ICMD_NOP;
+               iptr[len].line = 0;
+               iptr[len].flags.bits = 0;
                b->iinstr = iptr;
                b->icount = ++len;
 
                b->iinstr = iptr;
                b->icount = ++len;
 
-               /* allocate space for the clone's block variables */
+               /* reserve space for the clone's block variables */
 
                stack_grow_variable_array(sd, orig->varcount);
 
 
                stack_grow_variable_array(sd, orig->varcount);
 
@@ -1377,6 +1443,8 @@ bool stack_reanalyse_block(stackdata_t *sd)
        if (b->inlocals)
                MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
 
        if (b->inlocals)
                MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
 
+       MCOPY(sd->javalocals, b->javalocals, s4, sd->maxlocals);
+
        /* reach exception handlers for this block */
 
        if (!stack_reach_handlers(sd))
        /* reach exception handlers for this block */
 
        if (!stack_reach_handlers(sd))
@@ -1390,25 +1458,24 @@ bool stack_reanalyse_block(stackdata_t *sd)
                printf("\n");
 #endif
 
                printf("\n");
 #endif
 
-               maythrow = false;
-
                switch (iptr->opc) {
                        case ICMD_RET:
                switch (iptr->opc) {
                        case ICMD_RET:
-                               j = iptr->s1.varindex;
+                               varindex = iptr->s1.varindex;
 
 #if defined(ENABLE_VERIFIER)
 
 #if defined(ENABLE_VERIFIER)
-                               if (sd->var[j].type != TYPE_RET) {
+                               if (sd->var[varindex].type != TYPE_RET) {
                                        exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
                                        return false;
                                }
 #endif
 
                                        exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
                                        return false;
                                }
 #endif
 
-                               iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[j].vv.retaddr);
+                               iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[varindex].vv.retaddr);
                                superblockend = true;
                                break;
 
                        case ICMD_JSR:
                                iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
                                superblockend = true;
                                break;
 
                        case ICMD_JSR:
                                iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
+                               RELOCATE(iptr->dst.varindex);
                                superblockend = true;
                                break;
 
                                superblockend = true;
                                break;
 
@@ -1418,14 +1485,10 @@ bool stack_reanalyse_block(stackdata_t *sd)
 
                        case ICMD_CHECKNULL:
                        case ICMD_PUTSTATICCONST:
 
                        case ICMD_CHECKNULL:
                        case ICMD_PUTSTATICCONST:
-                               maythrow = true;
                                break;
 
                        case ICMD_NOP:
                        case ICMD_IINC:
                                break;
 
                        case ICMD_NOP:
                        case ICMD_IINC:
-                       case ICMD_INLINE_START:
-                       case ICMD_INLINE_END:
-                       case ICMD_INLINE_GOTO:
                                break;
 
                        case ICMD_GOTO:
                                break;
 
                        case ICMD_GOTO:
@@ -1436,7 +1499,6 @@ bool stack_reanalyse_block(stackdata_t *sd)
                                /* pop 0 push 1 const */
 
                        case ICMD_ACONST:
                                /* pop 0 push 1 const */
 
                        case ICMD_ACONST:
-                               maythrow = true;
                        case ICMD_ICONST:
                        case ICMD_LCONST:
                        case ICMD_FCONST:
                        case ICMD_ICONST:
                        case ICMD_LCONST:
                        case ICMD_FCONST:
@@ -1465,7 +1527,6 @@ bool stack_reanalyse_block(stackdata_t *sd)
                                RELOCATE(iptr->sx.s23.s2.varindex);
                                RELOCATE(iptr->s1.varindex);
                                RELOCATE(iptr->dst.varindex);
                                RELOCATE(iptr->sx.s23.s2.varindex);
                                RELOCATE(iptr->s1.varindex);
                                RELOCATE(iptr->dst.varindex);
-                               maythrow = true;
                                break;
 
                                /* pop 3 push 0 */
                                break;
 
                                /* pop 3 push 0 */
@@ -1481,7 +1542,6 @@ bool stack_reanalyse_block(stackdata_t *sd)
                                RELOCATE(iptr->sx.s23.s3.varindex);
                                RELOCATE(iptr->sx.s23.s2.varindex);
                                RELOCATE(iptr->s1.varindex);
                                RELOCATE(iptr->sx.s23.s3.varindex);
                                RELOCATE(iptr->sx.s23.s2.varindex);
                                RELOCATE(iptr->s1.varindex);
-                               maythrow = true;
                                break;
 
                                /* pop 1 push 0 store */
                                break;
 
                                /* pop 1 push 0 store */
@@ -1493,15 +1553,26 @@ bool stack_reanalyse_block(stackdata_t *sd)
                        case ICMD_ASTORE:
                                RELOCATE(iptr->s1.varindex);
 
                        case ICMD_ASTORE:
                                RELOCATE(iptr->s1.varindex);
 
-                               j = iptr->dst.varindex;
-                               COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, j);
+                               varindex = iptr->dst.varindex;
+                               COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, varindex);
+                               i = iptr->sx.s23.s3.javaindex;
+                               if (iptr->flags.bits & INS_FLAG_RETADDR) {
+                                       iptr->sx.s23.s2.retaddrnr =
+                                               JAVALOCAL_FROM_RETADDR(sd->var[varindex].vv.retaddr->nr);
+                                       sd->javalocals[i] = iptr->sx.s23.s2.retaddrnr;
+                               }
+                               else
+                                       sd->javalocals[i] = varindex;
+                               if (iptr->flags.bits & INS_FLAG_KILL_PREV)
+                                       sd->javalocals[i-1] = UNUSED;
+                               if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
+                                       sd->javalocals[i+1] = UNUSED;
                                break;
 
                                /* pop 1 push 0 */
 
                        case ICMD_ARETURN:
                        case ICMD_ATHROW:
                                break;
 
                                /* pop 1 push 0 */
 
                        case ICMD_ARETURN:
                        case ICMD_ATHROW:
-                               maythrow = true;
                        case ICMD_IRETURN:
                        case ICMD_LRETURN:
                        case ICMD_FRETURN:
                        case ICMD_IRETURN:
                        case ICMD_LRETURN:
                        case ICMD_FRETURN:
@@ -1512,7 +1583,6 @@ bool stack_reanalyse_block(stackdata_t *sd)
 
                        case ICMD_PUTSTATIC:
                        case ICMD_PUTFIELDCONST:
 
                        case ICMD_PUTSTATIC:
                        case ICMD_PUTFIELDCONST:
-                               maythrow = true;
                        case ICMD_POP:
                                RELOCATE(iptr->s1.varindex);
                                break;
                        case ICMD_POP:
                                RELOCATE(iptr->s1.varindex);
                                break;
@@ -1583,7 +1653,6 @@ bool stack_reanalyse_block(stackdata_t *sd)
                        case ICMD_MONITORENTER:
                        case ICMD_MONITOREXIT:
                                RELOCATE(iptr->s1.varindex);
                        case ICMD_MONITORENTER:
                        case ICMD_MONITOREXIT:
                                RELOCATE(iptr->s1.varindex);
-                               maythrow = true;
                                break;
 
                                /* pop 2 push 0 branch */
                                break;
 
                                /* pop 2 push 0 branch */
@@ -1644,7 +1713,6 @@ bool stack_reanalyse_block(stackdata_t *sd)
                        case ICMD_BASTORECONST:
                        case ICMD_CASTORECONST:
                        case ICMD_SASTORECONST:
                        case ICMD_BASTORECONST:
                        case ICMD_CASTORECONST:
                        case ICMD_SASTORECONST:
-                               maythrow = true;
                        case ICMD_POP2:
                                RELOCATE(iptr->sx.s23.s2.varindex);
                                RELOCATE(iptr->s1.varindex);
                        case ICMD_POP2:
                                RELOCATE(iptr->sx.s23.s2.varindex);
                                RELOCATE(iptr->s1.varindex);
@@ -1665,7 +1733,6 @@ bool stack_reanalyse_block(stackdata_t *sd)
                        case ICMD_IREM:
                        case ICMD_LDIV:
                        case ICMD_LREM:
                        case ICMD_IREM:
                        case ICMD_LDIV:
                        case ICMD_LREM:
-                               maythrow = true;
                        case ICMD_IADD:
                        case ICMD_ISUB:
                        case ICMD_IMUL:
                        case ICMD_IADD:
                        case ICMD_ISUB:
                        case ICMD_IMUL:
@@ -1711,7 +1778,6 @@ bool stack_reanalyse_block(stackdata_t *sd)
                        case ICMD_INSTANCEOF:
                        case ICMD_NEWARRAY:
                        case ICMD_ANEWARRAY:
                        case ICMD_INSTANCEOF:
                        case ICMD_NEWARRAY:
                        case ICMD_ANEWARRAY:
-                               maythrow = true;
                        case ICMD_GETFIELD:
                        case ICMD_IADDCONST:
                        case ICMD_ISUBCONST:
                        case ICMD_GETFIELD:
                        case ICMD_IADDCONST:
                        case ICMD_ISUBCONST:
@@ -1764,7 +1830,6 @@ bool stack_reanalyse_block(stackdata_t *sd)
 
                        case ICMD_GETSTATIC:
                        case ICMD_NEW:
 
                        case ICMD_GETSTATIC:
                        case ICMD_NEW:
-                               maythrow = true;
                                RELOCATE(iptr->dst.varindex);
                                break;
 
                                RELOCATE(iptr->dst.varindex);
                                break;
 
@@ -1786,7 +1851,6 @@ bool stack_reanalyse_block(stackdata_t *sd)
                                        argp = iptr->sx.s23.s2.args;
                                }
 
                                        argp = iptr->sx.s23.s2.args;
                                }
 
-                               maythrow = true;
                                while (--i >= 0) {
                                        RELOCATE(*argp);
                                        argp++;
                                while (--i >= 0) {
                                        RELOCATE(*argp);
                                        argp++;
@@ -1795,9 +1859,8 @@ bool stack_reanalyse_block(stackdata_t *sd)
                                break;
 
                        default:
                                break;
 
                        default:
-                               *exceptionptr =
-                                       new_internalerror("Unknown ICMD %d during stack re-analysis",
-                                                       iptr->opc);
+                               exceptions_throw_internalerror("Unknown ICMD %d during stack re-analysis",
+                                                                                          iptr->opc);
                                return false;
                } /* switch */
 
                                return false;
                } /* switch */
 
@@ -1851,7 +1914,8 @@ static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp,
        s4 newindex;
        s4 oldindex;
        instruction *iptr;
        s4 newindex;
        s4 oldindex;
        instruction *iptr;
-       int i;
+       s4 depth;
+       s4 i;
 
        oldindex = sp->varnum;
 
 
        oldindex = sp->varnum;
 
@@ -1876,10 +1940,21 @@ static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp,
        if (sp->flags & PASSTHROUGH) {
                iptr = (sp->creator) ? (sp->creator + 1) : sd->bptr->iinstr;
 
        if (sp->flags & PASSTHROUGH) {
                iptr = (sp->creator) ? (sp->creator + 1) : sd->bptr->iinstr;
 
-               /* asser that the limit point to an ICMD, or after the last one */
+               /* assert that the limit points to an ICMD, or after the last one */
+
                assert(ilimit >= sd->bptr->iinstr);
                assert(ilimit <= sd->bptr->iinstr + sd->bptr->icount);
 
                assert(ilimit >= sd->bptr->iinstr);
                assert(ilimit <= sd->bptr->iinstr + sd->bptr->icount);
 
+               /* find the stackdepth under sp plus one */
+               /* Note: This number is usually known when this function is called, */
+               /* but calculating it here is less error-prone and should not be    */
+               /* a performance problem.                                           */
+
+               for (depth = 0; sp != NULL; sp = sp->prev)
+                       depth++;
+
+               /* iterate over all instructions in the range and replace */
+
                for (; iptr < ilimit; ++iptr) {
                        switch (iptr->opc) {
                                case ICMD_INVOKESTATIC:
                for (; iptr < ilimit; ++iptr) {
                        switch (iptr->opc) {
                                case ICMD_INVOKESTATIC:
@@ -1887,11 +1962,10 @@ static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp,
                                case ICMD_INVOKEVIRTUAL:
                                case ICMD_INVOKEINTERFACE:
                                case ICMD_BUILTIN:
                                case ICMD_INVOKEVIRTUAL:
                                case ICMD_INVOKEINTERFACE:
                                case ICMD_BUILTIN:
-
-                                       for (i=0; i<iptr->s1.argcount; ++i)
-                                               if (iptr->sx.s23.s2.args[i] == oldindex) {
-                                                       iptr->sx.s23.s2.args[i] = newindex;
-                                               }
+                                       i = iptr->s1.argcount - depth;
+                                       if (iptr->sx.s23.s2.args[i] == oldindex) {
+                                               iptr->sx.s23.s2.args[i] = newindex;
+                                       }
                                        break;
                                /* IMPORTANT: If any ICMD sets the PASSTHROUGH flag of a */
                                /* stackslot, it must be added in this switch!           */
                                        break;
                                /* IMPORTANT: If any ICMD sets the PASSTHROUGH flag of a */
                                /* stackslot, it must be added in this switch!           */
@@ -1901,6 +1975,42 @@ static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp,
 }
 
 
 }
 
 
+/* stack_init_javalocals *******************************************************
+   Initialize the mapping from Java locals to cacao variables at method entry.
+
+   IN:
+      sd...........stack analysis data
+
+*******************************************************************************/
+
+static void stack_init_javalocals(stackdata_t *sd)
+{
+       s4         *jl;
+       s4          type,i,j;
+       methoddesc *md;
+       jitdata    *jd;
+
+       jd = sd->jd;
+
+       jl = DMNEW(s4, sd->maxlocals);
+       jd->basicblocks[0].javalocals = jl;
+
+       for (i=0; i<sd->maxlocals; ++i)
+               jl[i] = UNUSED;
+
+       md = jd->m->parseddesc;
+       j = 0;
+       for (i=0; i<md->paramcount; ++i) {
+               type = md->paramtypes[i].type;
+               jl[j] = jd->local_map[5*j + type];
+               j++;
+               if (IS_2_WORD_TYPE(type))
+                       j++;
+       }
+}
+
+
 /* stack_analyse ***************************************************************
 
    Analyse_stack uses the intermediate code created by parse.c to
 /* stack_analyse ***************************************************************
 
    Analyse_stack uses the intermediate code created by parse.c to
@@ -1928,19 +2038,15 @@ static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp,
 bool stack_analyse(jitdata *jd)
 {
        methodinfo   *m;              /* method being analyzed                    */
 bool stack_analyse(jitdata *jd)
 {
        methodinfo   *m;              /* method being analyzed                    */
-       codeinfo     *code;
        registerdata *rd;
        stackdata_t   sd;
        registerdata *rd;
        stackdata_t   sd;
-#if defined(ENABLE_SSA)
-       lsradata     *ls;
-#endif
-       int           b_index;        /* basic block index                        */
        int           stackdepth;
        stackptr      curstack;       /* current stack top                        */
        stackptr      copy;
        int           opcode;         /* opcode of current instruction            */
        int           stackdepth;
        stackptr      curstack;       /* current stack top                        */
        stackptr      copy;
        int           opcode;         /* opcode of current instruction            */
-       int           i, j;
+       int           i, varindex;
        int           javaindex;
        int           javaindex;
+       int           type;           /* operand type                             */
        int           len;            /* # of instructions after the current one  */
        bool          superblockend;  /* if true, no fallthrough to next block    */
        bool          deadcode;       /* true if no live code has been reached    */
        int           len;            /* # of instructions after the current one  */
        bool          superblockend;  /* if true, no fallthrough to next block    */
        bool          deadcode;       /* true if no live code has been reached    */
@@ -1974,11 +2080,7 @@ bool stack_analyse(jitdata *jd)
        /* get required compiler data - initialization */
 
        m    = jd->m;
        /* get required compiler data - initialization */
 
        m    = jd->m;
-       code = jd->code;
        rd   = jd->rd;
        rd   = jd->rd;
-#if defined(ENABLE_SSA)
-       ls   = jd->ls;
-#endif
 
        /* initialize the stackdata_t struct */
 
 
        /* initialize the stackdata_t struct */
 
@@ -1988,6 +2090,9 @@ bool stack_analyse(jitdata *jd)
        sd.vartop =  jd->vartop;
        sd.localcount = jd->localcount;
        sd.var = jd->var;
        sd.vartop =  jd->vartop;
        sd.localcount = jd->localcount;
        sd.var = jd->var;
+       sd.varsallocated = sd.varcount;
+       sd.maxlocals = m->maxlocals;
+       sd.javalocals = DMNEW(s4, sd.maxlocals);
        sd.handlers = DMNEW(exception_entry *, jd->exceptiontablelength + 1);
 
        /* prepare the variable for exception handler stacks               */
        sd.handlers = DMNEW(exception_entry *, jd->exceptiontablelength + 1);
 
        /* prepare the variable for exception handler stacks               */
@@ -1998,10 +2103,6 @@ bool stack_analyse(jitdata *jd)
        sd.exstack.varnum = sd.localcount;
        sd.var[sd.exstack.varnum].type = TYPE_ADR;
 
        sd.exstack.varnum = sd.localcount;
        sd.var[sd.exstack.varnum].type = TYPE_ADR;
 
-#if defined(ENABLE_LSRA)
-       m->maxlifetimes = 0;
-#endif
-
 #if defined(ENABLE_STATISTICS)
        iteration_count = 0;
 #endif
 #if defined(ENABLE_STATISTICS)
        iteration_count = 0;
 #endif
@@ -2025,6 +2126,7 @@ bool stack_analyse(jitdata *jd)
 
        /* init jd->interface_map */
 
 
        /* init jd->interface_map */
 
+       jd->maxinterfaces = m->maxstack;
        jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
        for (i = 0; i < m->maxstack * 5; i++)
                jd->interface_map[i].flags = UNUSED;
        jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
        for (i = 0; i < m->maxstack * 5; i++)
                jd->interface_map[i].flags = UNUSED;
@@ -2041,6 +2143,10 @@ bool stack_analyse(jitdata *jd)
        MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo, 
                        jd->localcount + VERIFIER_EXTRA_LOCALS);
 
        MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo, 
                        jd->localcount + VERIFIER_EXTRA_LOCALS);
 
+       /* initialize java local mapping of first block */
+
+       stack_init_javalocals(&sd);
+
        /* stack analysis loop (until fixpoint reached) **************************/
 
        do {
        /* stack analysis loop (until fixpoint reached) **************************/
 
        do {
@@ -2050,11 +2156,12 @@ bool stack_analyse(jitdata *jd)
 
                /* initialize loop over basic blocks */
 
 
                /* initialize loop over basic blocks */
 
-               sd.bptr = jd->basicblocks;
+               sd.bptr       = jd->basicblocks;
                superblockend = true;
                superblockend = true;
-               sd.repeat = false;
-               curstack = NULL; stackdepth = 0;
-               deadcode = true;
+               sd.repeat     = false;
+               curstack      = NULL;
+               stackdepth    = 0;
+               deadcode      = true;
 
                /* iterate over basic blocks *****************************************/
 
 
                /* iterate over basic blocks *****************************************/
 
@@ -2068,15 +2175,20 @@ bool stack_analyse(jitdata *jd)
 
                        if (sd.bptr->flags == BBTYPECHECK_REACHED) {
                                /* re-analyse a block because its input changed */
 
                        if (sd.bptr->flags == BBTYPECHECK_REACHED) {
                                /* re-analyse a block because its input changed */
+
+                               deadcode = false;
+
                                if (!stack_reanalyse_block(&sd))
                                        return false;
                                if (!stack_reanalyse_block(&sd))
                                        return false;
+
                                superblockend = true; /* XXX */
                                continue;
                        }
 
                        if (superblockend && (sd.bptr->flags < BBREACHED)) {
                                superblockend = true; /* XXX */
                                continue;
                        }
 
                        if (superblockend && (sd.bptr->flags < BBREACHED)) {
-                               /* This block has not been reached so far, and we      */
-                               /* don't fall into it, so we'll have to iterate again. */
+                               /* This block has not been reached so far, and we
+                                  don't fall into it, so we'll have to iterate
+                                  again. */
 
                                sd.repeat = true;
                                continue;
 
                                sd.repeat = true;
                                continue;
@@ -2090,8 +2202,9 @@ bool stack_analyse(jitdata *jd)
                        }
 
                        if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
                        }
 
                        if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
-                               /* This block is a clone and the original has not been */
-                               /* analysed, yet. Analyse it on the next iteration.    */
+                               /* This block is a clone and the original has not been
+                                  analysed, yet. Analyse it on the next
+                                  iteration. */
 
                                sd.repeat = true;
                                /* XXX superblockend? */
 
                                sd.repeat = true;
                                /* XXX superblockend? */
@@ -2100,6 +2213,8 @@ bool stack_analyse(jitdata *jd)
 
                        /* This block has to be analysed now. */
 
 
                        /* This block has to be analysed now. */
 
+                       deadcode = false;
+
                        /* XXX The rest of this block is still indented one level too */
                        /* much in order to avoid a giant diff by changing that.      */
 
                        /* XXX The rest of this block is still indented one level too */
                        /* much in order to avoid a giant diff by changing that.      */
 
@@ -2148,13 +2263,13 @@ bool stack_analyse(jitdata *jd)
                                if (sd.bptr->inlocals)
                                        MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
 
                                if (sd.bptr->inlocals)
                                        MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
 
+                               MCOPY(sd.javalocals, sd.bptr->javalocals, s4, sd.maxlocals);
+
                                /* set up local variables for analyzing this block */
 
                                /* set up local variables for analyzing this block */
 
-                               deadcode = false;
                                superblockend = false;
                                len = sd.bptr->icount;
                                iptr = sd.bptr->iinstr;
                                superblockend = false;
                                len = sd.bptr->icount;
                                iptr = sd.bptr->iinstr;
-                               b_index = sd.bptr - jd->basicblocks;
 
                                /* mark the block as analysed */
 
 
                                /* mark the block as analysed */
 
@@ -2184,16 +2299,7 @@ bool stack_analyse(jitdata *jd)
                                while (--len >= 0)  {
 
 #if defined(STACK_VERBOSE)
                                while (--len >= 0)  {
 
 #if defined(STACK_VERBOSE)
-                                       show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
-                                       for( copy = curstack; copy; copy = copy->prev ) {
-                                               printf("%2d(%d", copy->varnum, copy->type);
-                                               if (IS_INOUT(copy))
-                                                       printf("S");
-                                               if (IS_PREALLOC(copy))
-                                                       printf("A");
-                                               printf(") ");
-                                       }
-                                       printf("\n");
+                                       stack_verbose_show_state(&sd, iptr, curstack);
 #endif
 
                                        /* fetch the current opcode */
 #endif
 
                                        /* fetch the current opcode */
@@ -2202,18 +2308,16 @@ bool stack_analyse(jitdata *jd)
 
                                        /* automatically replace some ICMDs with builtins */
 
 
                                        /* automatically replace some ICMDs with builtins */
 
-#if defined(USEBUILTINTABLE)
                                        bte = builtintable_get_automatic(opcode);
 
                                        bte = builtintable_get_automatic(opcode);
 
-                                       if (bte && bte->opcode == opcode) {
-                                               iptr->opc           = ICMD_BUILTIN;
-                                               iptr->flags.bits    = 0;
-                                               iptr->sx.s23.s3.bte = bte;
+                                       if ((bte != NULL) && (bte->opcode == opcode)) {
+                                               iptr->opc            = ICMD_BUILTIN;
+                                               iptr->flags.bits    &= INS_FLAG_ID_MASK;
+                                               iptr->sx.s23.s3.bte  = bte;
                                                /* iptr->line is already set */
                                                /* iptr->line is already set */
-                                               jd->isleafmethod = false;
+                                               jd->isleafmethod     = false;
                                                goto icmd_BUILTIN;
                                        }
                                                goto icmd_BUILTIN;
                                        }
-#endif /* defined(USEBUILTINTABLE) */
 
                                        /* main opcode switch *************************************/
 
 
                                        /* main opcode switch *************************************/
 
@@ -2236,11 +2340,11 @@ icmd_NOP:
                                                break;
 
                                        case ICMD_RET:
                                                break;
 
                                        case ICMD_RET:
-                                               j = iptr->s1.varindex = 
+                                               varindex = iptr->s1.varindex = 
                                                        jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
 
 #if defined(ENABLE_VERIFIER)
                                                        jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
 
 #if defined(ENABLE_VERIFIER)
-                                               if (sd.var[j].type != TYPE_RET) {
+                                               if (sd.var[varindex].type != TYPE_RET) {
                                                        exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
                                                        return false;
                                                }
                                                        exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
                                                        return false;
                                                }
@@ -2248,7 +2352,7 @@ icmd_NOP:
                
                                                CLR_SX;
 
                
                                                CLR_SX;
 
-                                               iptr->dst.block = stack_mark_reached(&sd, sd.var[j].vv.retaddr, curstack, stackdepth);
+                                               iptr->dst.block = stack_mark_reached(&sd, sd.var[varindex].vv.retaddr, curstack, stackdepth);
                                                superblockend = true;
                                                break;
 
                                                superblockend = true;
                                                break;
 
@@ -2257,6 +2361,8 @@ icmd_NOP:
                                                CLR_SX;
                                                OP0_0;
                                                superblockend = true;
                                                CLR_SX;
                                                OP0_0;
                                                superblockend = true;
+                                               sd.jd->returncount++;
+                                               sd.jd->returnblock = sd.bptr;
                                                break;
 
 
                                                break;
 
 
@@ -2589,10 +2695,32 @@ putconst_tail:
                                                                if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
                                                                        iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
                                                                        iptr->flags.bits |= INS_FLAG_UNRESOLVED;
                                                                if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
                                                                        iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
                                                                        iptr->flags.bits |= INS_FLAG_UNRESOLVED;
+                                                                       fmiref = iptr->sx.s23.s3.uf->fieldref;
                                                                }
                                                                else {
                                                                }
                                                                else {
-                                                                       iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
+                                                                       fmiref = iptr[1].sx.s23.s3.fmiref;
+                                                                       iptr->sx.s23.s3.fmiref = fmiref;
+                                                               }
+
+#if defined(ENABLE_VERIFIER)
+                                                               expectedtype = fmiref->parseddesc.fd->type;
+                                                               switch (iptr[0].opc) {
+                                                                       case ICMD_ICONST:
+                                                                               if (expectedtype != TYPE_INT)
+                                                                                       goto throw_stack_type_error;
+                                                                               break;
+                                                                       case ICMD_LCONST:
+                                                                               if (expectedtype != TYPE_LNG)
+                                                                                       goto throw_stack_type_error;
+                                                                               break;
+                                                                       case ICMD_ACONST:
+                                                                               if (expectedtype != TYPE_ADR)
+                                                                                       goto throw_stack_type_error;
+                                                                               break;
+                                                                       default:
+                                                                               assert(0);
                                                                }
                                                                }
+#endif /* defined(ENABLE_VERIFIER) */
                                                                
                                                                switch (iptr[1].opc) {
                                                                        case ICMD_PUTSTATIC:
                                                                
                                                                switch (iptr[1].opc) {
                                                                        case ICMD_PUTSTATIC:
@@ -2866,7 +2994,7 @@ normal_ICONST:
 
                                                                        icmd_lconst_lcmp_tail:
                                                                                /* convert LCONST, LCMP, IFXX to IF_LXX */
 
                                                                        icmd_lconst_lcmp_tail:
                                                                                /* convert LCONST, LCMP, IFXX to IF_LXX */
-                                                                               iptr->dst.insindex = iptr[2].dst.insindex;
+                                                                               iptr->dst.block = iptr[2].dst.block;
                                                                                iptr[1].opc = ICMD_NOP;
                                                                                iptr[2].opc = ICMD_NOP;
 
                                                                                iptr[1].opc = ICMD_NOP;
                                                                                iptr[2].opc = ICMD_NOP;
 
@@ -3033,29 +3161,18 @@ normal_ACONST:
                                        case ICMD_DLOAD:
                                        case ICMD_ALOAD:
                                                COUNT(count_load_instruction);
                                        case ICMD_DLOAD:
                                        case ICMD_ALOAD:
                                                COUNT(count_load_instruction);
-                                               i = opcode - ICMD_ILOAD; /* type */
+                                               type = opcode - ICMD_ILOAD;
 
 
-                                               j = iptr->s1.varindex = 
-                                                       jd->local_map[iptr->s1.varindex * 5 + i];
+                                               varindex = iptr->s1.varindex = 
+                                                       jd->local_map[iptr->s1.varindex * 5 + type];
 
 #if defined(ENABLE_VERIFIER)
 
 #if defined(ENABLE_VERIFIER)
-                                               if (sd.var[j].type == TYPE_RET) {
+                                               if (sd.var[varindex].type == TYPE_RET) {
                                                        exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
                                                        return false;
                                                }
 #endif
                                                        exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
                                                        return false;
                                                }
 #endif
-               
-#if defined(ENABLE_SSA)
-                                               if (ls != NULL) {
-                                                       GET_NEW_VAR(sd, new_index, i);
-                                                       DST(i, new_index);
-                                                       stackdepth++;
-                                               }
-                                               else
-
-#else
-                                               LOAD(i, j);
-#endif
+                                               LOAD(type, varindex);
                                                break;
 
                                                /* pop 2 push 1 */
                                                break;
 
                                                /* pop 2 push 1 */
@@ -3088,13 +3205,6 @@ normal_ACONST:
 
                                        case ICMD_IINC:
                                                STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
 
                                        case ICMD_IINC:
                                                STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
-#if defined(ENABLE_SSA)
-                                               if (ls != NULL) {
-                                                       iptr->s1.varindex = 
-                                                               jd->local_map[iptr->s1.varindex * 5 +TYPE_INT];
-                                               }
-                                               else {
-#endif
                                                last_store_boundary[iptr->s1.varindex] = sd.new;
 
                                                iptr->s1.varindex = 
                                                last_store_boundary[iptr->s1.varindex] = sd.new;
 
                                                iptr->s1.varindex = 
@@ -3112,9 +3222,6 @@ normal_ACONST:
                                                        i--;
                                                        copy = copy->prev;
                                                }
                                                        i--;
                                                        copy = copy->prev;
                                                }
-#if defined(ENABLE_SSA)
-                                               }
-#endif
 
                                                iptr->dst.varindex = iptr->s1.varindex;
                                                break;
 
                                                iptr->dst.varindex = iptr->s1.varindex;
                                                break;
@@ -3128,12 +3235,39 @@ normal_ACONST:
                                        case ICMD_ASTORE:
                                                REQUIRE(1);
 
                                        case ICMD_ASTORE:
                                                REQUIRE(1);
 
-                                               i = opcode - ICMD_ISTORE; /* type */
+                                               type = opcode - ICMD_ISTORE;
                                                javaindex = iptr->dst.varindex;
                                                javaindex = iptr->dst.varindex;
-                                               j = iptr->dst.varindex = 
-                                                       jd->local_map[javaindex * 5 + i];
+                                               varindex = iptr->dst.varindex = 
+                                                       jd->local_map[javaindex * 5 + type];
+
+                                               COPY_VAL_AND_TYPE(sd, curstack->varnum, varindex);
+
+                                               iptr->sx.s23.s3.javaindex = javaindex;
+
+                                               if (curstack->type == TYPE_RET) {
+                                                       iptr->flags.bits |= INS_FLAG_RETADDR;
+                                                       iptr->sx.s23.s2.retaddrnr = 
+                                                               JAVALOCAL_FROM_RETADDR(sd.var[varindex].vv.retaddr->nr);
+                                                       sd.javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
+                                               }
+                                               else
+                                                       sd.javalocals[javaindex] = varindex;
 
 
-                                               COPY_VAL_AND_TYPE(sd, curstack->varnum, j);
+                                               /* invalidate the following javalocal for 2-word types */
+
+                                               if (IS_2_WORD_TYPE(type)) {
+                                                       sd.javalocals[javaindex+1] = UNUSED;
+                                                       iptr->flags.bits |= INS_FLAG_KILL_NEXT;
+                                               }
+
+                                               /* invalidate 2-word types if second half was overwritten */
+
+                                               if (javaindex > 0 && (i = sd.javalocals[javaindex-1]) >= 0) {
+                                                       if (IS_2_WORD_TYPE(sd.var[i].type)) {
+                                                               sd.javalocals[javaindex-1] = UNUSED;
+                                                               iptr->flags.bits |= INS_FLAG_KILL_PREV;
+                                                       }
+                                               }
 
 #if defined(ENABLE_STATISTICS)
                                                if (opt_stat) {
 
 #if defined(ENABLE_STATISTICS)
                                                if (opt_stat) {
@@ -3151,16 +3285,13 @@ normal_ACONST:
                                                }
 #endif
 
                                                }
 #endif
 
-#if defined(ENABLE_SSA)
-                                               if (ls != NULL) {
-#endif
                                                /* check for conflicts as described in Figure 5.2 */
 
                                                copy = curstack->prev;
                                                i = stackdepth - 2;
                                                while (copy) {
                                                        if ((copy->varkind == LOCALVAR) &&
                                                /* check for conflicts as described in Figure 5.2 */
 
                                                copy = curstack->prev;
                                                i = stackdepth - 2;
                                                while (copy) {
                                                        if ((copy->varkind == LOCALVAR) &&
-                                                               (copy->varnum == j))
+                                                               (copy->varnum == varindex))
                                                        {
                                                                copy->varkind = TEMPVAR;
                                                                assert(IS_LOCALVAR(copy));
                                                        {
                                                                copy->varkind = TEMPVAR;
                                                                assert(IS_LOCALVAR(copy));
@@ -3188,11 +3319,11 @@ normal_ACONST:
                                                if (curstack < coalescing_boundary)
                                                        goto assume_conflict;
 
                                                if (curstack < coalescing_boundary)
                                                        goto assume_conflict;
 
-                                               /* there is no DEF LOCALVAR(j) while curstack is live */
+                                               /* there is no DEF LOCALVAR(varindex) while curstack is live */
 
                                                copy = sd.new; /* most recent stackslot created + 1 */
                                                while (--copy > curstack) {
 
                                                copy = sd.new; /* most recent stackslot created + 1 */
                                                while (--copy > curstack) {
-                                                       if (copy->varkind == LOCALVAR && copy->varnum == j)
+                                                       if (copy->varkind == LOCALVAR && copy->varnum == varindex)
                                                                goto assume_conflict;
                                                }
 
                                                                goto assume_conflict;
                                                }
 
@@ -3208,14 +3339,14 @@ normal_ACONST:
                                                assert(!(curstack->flags & PASSTHROUGH));
                                                RELEASE_INDEX(sd, curstack);
                                                curstack->varkind = LOCALVAR;
                                                assert(!(curstack->flags & PASSTHROUGH));
                                                RELEASE_INDEX(sd, curstack);
                                                curstack->varkind = LOCALVAR;
-                                               curstack->varnum = j;
-                                               curstack->creator->dst.varindex = j;
+                                               curstack->varnum = varindex;
+                                               curstack->creator->dst.varindex = varindex;
                                                goto store_tail;
 
                                                /* revert the coalescing, if it has been done earlier */
 assume_conflict:
                                                if ((curstack->varkind == LOCALVAR)
                                                goto store_tail;
 
                                                /* revert the coalescing, if it has been done earlier */
 assume_conflict:
                                                if ((curstack->varkind == LOCALVAR)
-                                                       && (curstack->varnum == j))
+                                                       && (curstack->varnum == varindex))
                                                {
                                                        assert(IS_LOCALVAR(curstack));
                                                        SET_TEMPVAR(curstack);
                                                {
                                                        assert(IS_LOCALVAR(curstack));
                                                        SET_TEMPVAR(curstack);
@@ -3224,14 +3355,11 @@ assume_conflict:
                                                /* remember the stack boundary at this store */
 store_tail:
                                                last_store_boundary[javaindex] = sd.new;
                                                /* remember the stack boundary at this store */
 store_tail:
                                                last_store_boundary[javaindex] = sd.new;
-#if defined(ENABLE_SSA)
-                                               } /* if (ls != NULL) */
-#endif
 
                                                if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
 
                                                if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
-                                                       STORE(TYPE_RET, j);
+                                                       STORE(TYPE_RET, varindex);
                                                else
                                                else
-                                                       STORE(opcode - ICMD_ISTORE, j);
+                                                       STORE(opcode - ICMD_ISTORE, varindex);
                                                break;
 
                                        /* pop 3 push 0 */
                                                break;
 
                                        /* pop 3 push 0 */
@@ -3319,6 +3447,8 @@ store_tail:
                                                COUNT(count_pcmd_return);
                                                OP1_0(opcode - ICMD_IRETURN);
                                                superblockend = true;
                                                COUNT(count_pcmd_return);
                                                OP1_0(opcode - ICMD_IRETURN);
                                                superblockend = true;
+                                               sd.jd->returncount++;
+                                               sd.jd->returnblock = sd.bptr;
                                                break;
 
                                        case ICMD_ATHROW:
                                                break;
 
                                        case ICMD_ATHROW:
@@ -3868,7 +3998,7 @@ icmd_DUP_X2:
                                                case ICMD_IFEQ:
                                                        iptr->opc = ICMD_IF_LCMPEQ;
                                                icmd_lcmp_if_tail:
                                                case ICMD_IFEQ:
                                                        iptr->opc = ICMD_IF_LCMPEQ;
                                                icmd_lcmp_if_tail:
-                                                       iptr->dst.insindex = iptr[1].dst.insindex;
+                                                       iptr->dst.block = iptr[1].dst.block;
                                                        iptr[1].opc = ICMD_NOP;
 
                                                        OP2_BRANCH(TYPE_LNG, TYPE_LNG);
                                                        iptr[1].opc = ICMD_NOP;
 
                                                        OP2_BRANCH(TYPE_LNG, TYPE_LNG);
@@ -3911,7 +4041,7 @@ normal_LCMP:
                                                case ICMD_IFEQ:
                                                        iptr->opc = ICMD_IF_FCMPEQ;
                                                icmd_if_fcmpl_tail:
                                                case ICMD_IFEQ:
                                                        iptr->opc = ICMD_IF_FCMPEQ;
                                                icmd_if_fcmpl_tail:
-                                                       iptr->dst.insindex = iptr[1].dst.insindex;
+                                                       iptr->dst.block = iptr[1].dst.block;
                                                        iptr[1].opc = ICMD_NOP;
 
                                                        OP2_BRANCH(TYPE_FLT, TYPE_FLT);
                                                        iptr[1].opc = ICMD_NOP;
 
                                                        OP2_BRANCH(TYPE_FLT, TYPE_FLT);
@@ -3952,7 +4082,7 @@ normal_FCMPL:
                                                case ICMD_IFEQ:
                                                        iptr->opc = ICMD_IF_FCMPEQ;
                                                icmd_if_fcmpg_tail:
                                                case ICMD_IFEQ:
                                                        iptr->opc = ICMD_IF_FCMPEQ;
                                                icmd_if_fcmpg_tail:
-                                                       iptr->dst.insindex = iptr[1].dst.insindex;
+                                                       iptr->dst.block = iptr[1].dst.block;
                                                        iptr[1].opc = ICMD_NOP;
 
                                                        OP2_BRANCH(TYPE_FLT, TYPE_FLT);
                                                        iptr[1].opc = ICMD_NOP;
 
                                                        OP2_BRANCH(TYPE_FLT, TYPE_FLT);
@@ -3993,7 +4123,7 @@ normal_FCMPG:
                                                case ICMD_IFEQ:
                                                        iptr->opc = ICMD_IF_DCMPEQ;
                                                icmd_if_dcmpl_tail:
                                                case ICMD_IFEQ:
                                                        iptr->opc = ICMD_IF_DCMPEQ;
                                                icmd_if_dcmpl_tail:
-                                                       iptr->dst.insindex = iptr[1].dst.insindex;
+                                                       iptr->dst.block = iptr[1].dst.block;
                                                        iptr[1].opc = ICMD_NOP;
 
                                                        OP2_BRANCH(TYPE_DBL, TYPE_DBL);
                                                        iptr[1].opc = ICMD_NOP;
 
                                                        OP2_BRANCH(TYPE_DBL, TYPE_DBL);
@@ -4034,7 +4164,7 @@ normal_DCMPL:
                                                case ICMD_IFEQ:
                                                        iptr->opc = ICMD_IF_DCMPEQ;
                                                icmd_if_dcmpg_tail:
                                                case ICMD_IFEQ:
                                                        iptr->opc = ICMD_IF_DCMPEQ;
                                                icmd_if_dcmpg_tail:
-                                                       iptr->dst.insindex = iptr[1].dst.insindex;
+                                                       iptr->dst.block = iptr[1].dst.block;
                                                        iptr[1].opc = ICMD_NOP;
 
                                                        OP2_BRANCH(TYPE_DBL, TYPE_DBL);
                                                        iptr[1].opc = ICMD_NOP;
 
                                                        OP2_BRANCH(TYPE_DBL, TYPE_DBL);
@@ -4212,7 +4342,7 @@ normal_DCMPG:
                                        case ICMD_JSR:
                                                OP0_1(TYPE_RET);
 
                                        case ICMD_JSR:
                                                OP0_1(TYPE_RET);
 
-                                               tbptr = BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex);
+                                               tbptr = iptr->sx.s23.s3.jsrtarget.block;
                                                tbptr->type = BBTYPE_SBR;
 
                                                assert(sd.bptr->next);  /* XXX exception */
                                                tbptr->type = BBTYPE_SBR;
 
                                                assert(sd.bptr->next);  /* XXX exception */
@@ -4222,7 +4352,7 @@ normal_DCMPG:
 #endif
 
                                                tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
 #endif
 
                                                tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
-                                               if (!tbptr)
+                                               if (tbptr == NULL)
                                                        return false;
 
                                                iptr->sx.s23.s3.jsrtarget.block = tbptr;
                                                        return false;
 
                                                iptr->sx.s23.s3.jsrtarget.block = tbptr;
@@ -4314,20 +4444,20 @@ icmd_BUILTIN:
                                                                                assert(0); /* XXX is this assert ok? */
 #else
                                                                                sd.var[copy->varnum].vv.regoff = 
                                                                                assert(0); /* XXX is this assert ok? */
 #else
                                                                                sd.var[copy->varnum].vv.regoff = 
-                                                                       rd->argfltregs[md->params[i].regoff];
+                                                                                       md->params[i].regoff;
 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
                                                                        }
                                                                        else {
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                                                                if (IS_2_WORD_TYPE(copy->type))
                                                                                        sd.var[copy->varnum].vv.regoff = 
 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
                                                                        }
                                                                        else {
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                                                                if (IS_2_WORD_TYPE(copy->type))
                                                                                        sd.var[copy->varnum].vv.regoff = 
-                       PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
-                                          rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
+                       PACK_REGS(GET_LOW_REG(md->params[i].regoff),
+                                         GET_HIGH_REG(md->params[i].regoff));
 
                                                                                else
 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
                                                                                        sd.var[copy->varnum].vv.regoff = 
 
                                                                                else
 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
                                                                                        sd.var[copy->varnum].vv.regoff = 
-                                                                       rd->argintregs[md->params[i].regoff];
+                                                                                               md->params[i].regoff;
                                                                        }
                                                                }
                                                        }
                                                                        }
                                                                }
                                                        }
@@ -4365,12 +4495,6 @@ icmd_BUILTIN:
                                                }
                                                break;
 
                                                }
                                                break;
 
-                                       case ICMD_INLINE_START:
-                                       case ICMD_INLINE_END:
-                                               CLR_S1;
-                                               CLR_DST;
-                                               break;
-
                                        case ICMD_MULTIANEWARRAY:
                                                coalescing_boundary = sd.new;
                                                if (rd->argintreguse < MIN(3, INT_ARG_CNT))
                                        case ICMD_MULTIANEWARRAY:
                                                coalescing_boundary = sd.new;
                                                if (rd->argintreguse < MIN(3, INT_ARG_CNT))
@@ -4449,8 +4573,8 @@ icmd_BUILTIN:
                                                break;
 
                                        default:
                                                break;
 
                                        default:
-                                               *exceptionptr =
-                                                       new_internalerror("Unknown ICMD %d", opcode);
+                                               exceptions_throw_internalerror("Unknown ICMD %d during stack analysis",
+                                                                                                          opcode);
                                                return false;
                                        } /* switch */
 
                                                return false;
                                        } /* switch */
 
@@ -4458,6 +4582,12 @@ icmd_BUILTIN:
                                        iptr++;
                                } /* while instructions */
 
                                        iptr++;
                                } /* while instructions */
 
+                               /* show state after last instruction */
+
+#if defined(STACK_VERBOSE)
+                               stack_verbose_show_state(&sd, NULL, curstack);
+#endif
+
                                /* stack slots at basic block end become interfaces */
 
                                sd.bptr->outdepth = stackdepth;
                                /* stack slots at basic block end become interfaces */
 
                                sd.bptr->outdepth = stackdepth;
@@ -4466,7 +4596,6 @@ icmd_BUILTIN:
                                i = stackdepth - 1;
                                for (copy = curstack; copy; i--, copy = copy->prev) {
                                        varinfo *v;
                                i = stackdepth - 1;
                                for (copy = curstack; copy; i--, copy = copy->prev) {
                                        varinfo *v;
-                                       s4 t;
 
                                        /* with the new vars rd->interfaces will be removed */
                                        /* and all in and outvars have to be STACKVARS!     */
 
                                        /* with the new vars rd->interfaces will be removed */
                                        /* and all in and outvars have to be STACKVARS!     */
@@ -4474,20 +4603,22 @@ icmd_BUILTIN:
                                        /* create an unresolvable conflict */
 
                                        SET_TEMPVAR(copy);
                                        /* create an unresolvable conflict */
 
                                        SET_TEMPVAR(copy);
-                                       t = copy->type;
-                                       if (t == TYPE_RET)
-                                               t = TYPE_ADR;
+                                       type = copy->type;
 
                                        v = sd.var + copy->varnum;
                                        v->flags |= INOUT;
 
 
                                        v = sd.var + copy->varnum;
                                        v->flags |= INOUT;
 
-                                       if (jd->interface_map[i*5 + t].flags == UNUSED) {
-                                               /* no interface var until now for this depth and */
-                                               /* type */
-                                               jd->interface_map[i*5 + t].flags = v->flags;
-                                       }
-                                       else {
-                                               jd->interface_map[i*5 + t].flags |= v->flags;
+                                       /* do not allocate variables for returnAddresses */
+
+                                       if (type != TYPE_RET) {
+                                               if (jd->interface_map[i*5 + type].flags == UNUSED) {
+                                                       /* no interface var until now for this depth and */
+                                                       /* type */
+                                                       jd->interface_map[i*5 + type].flags = v->flags;
+                                               }
+                                               else {
+                                                       jd->interface_map[i*5 + type].flags |= v->flags;
+                                               }
                                        }
 
                                        sd.bptr->outvars[i] = copy->varnum;
                                        }
 
                                        sd.bptr->outvars[i] = copy->varnum;
@@ -4497,19 +4628,18 @@ icmd_BUILTIN:
 
                                for (i=0; i<sd.bptr->indepth; ++i) {
                                        varinfo *v = sd.var + sd.bptr->invars[i];
 
                                for (i=0; i<sd.bptr->indepth; ++i) {
                                        varinfo *v = sd.var + sd.bptr->invars[i];
-                                       s4 t;
 
 
-                                       t = v->type;
-                                       if (t == TYPE_RET)
-                                               t = TYPE_ADR;
+                                       type = v->type;
 
 
-                                       if (jd->interface_map[i*5 + t].flags == UNUSED) {
-                                               /* no interface var until now for this depth and */
-                                               /* type */
-                                               jd->interface_map[i*5 + t].flags = v->flags;
-                                       }
-                                       else {
-                                               jd->interface_map[i*5 + t].flags |= v->flags;
+                                       if (type != TYPE_RET) {
+                                               if (jd->interface_map[i*5 + type].flags == UNUSED) {
+                                                       /* no interface var until now for this depth and */
+                                                       /* type */
+                                                       jd->interface_map[i*5 + type].flags = v->flags;
+                                               }
+                                               else {
+                                                       jd->interface_map[i*5 + type].flags |= v->flags;
+                                               }
                                        }
                                }
 
                                        }
                                }
 
@@ -4531,11 +4661,30 @@ icmd_BUILTIN:
 
        } while (sd.repeat && !deadcode);
 
 
        } while (sd.repeat && !deadcode);
 
-       /* XXX reset TYPE_RET to TYPE_ADR */
+    /* reset locals of TYPE_RET|VOID to TYPE_ADR */
+
+    /* A local variable may be used as both a returnAddress and a reference */
+    /* type variable, as we do not split variables between these types when */
+    /* renaming locals. While returnAddresses have been eliminated now, we  */
+    /* must assume that the variable is still used as TYPE_ADR.             */
+    /* The only way that a local can be TYPE_VOID at this point, is that it */
+    /* was a TYPE_RET variable for which incompatible returnAddresses were  */
+    /* merged. Thus we must treat TYPE_VOID in the same way as TYPE_RET     */
+    /* here.                                                                */
+    /* XXX: It would be nice to remove otherwise unused returnAddress       */
+    /*      variables from the local variable array, so they are not        */
+    /*      allocated by simplereg. (For LSRA this is not needed).          */
+
+       for (i=0; i<sd.localcount; ++i) {
+               if (sd.var[i].type == TYPE_RET || sd.var[i].type == TYPE_VOID)
+                       sd.var[i].type = TYPE_ADR;
+       }
+
+       /* mark temporaries of TYPE_RET as PREALLOC to avoid allocation */
 
 
-       for (i=0; i<sd.vartop; ++i) {
+       for (i=sd.localcount; i<sd.vartop; ++i) {
                if (sd.var[i].type == TYPE_RET)
                if (sd.var[i].type == TYPE_RET)
-                       sd.var[i].type = TYPE_ADR;
+                       sd.var[i].flags |= PREALLOC;
        }
 
        /* XXX hack to fix up the ranges of the cloned single-block handlers */
        }
 
        /* XXX hack to fix up the ranges of the cloned single-block handlers */
@@ -4548,6 +4697,10 @@ icmd_BUILTIN:
                }
        }
 
                }
        }
 
+       /* store number of created variables */
+
+       jd->vartop = sd.vartop;
+
        /* gather statistics *****************************************************/
 
 #if defined(ENABLE_STATISTICS)
        /* gather statistics *****************************************************/
 
 #if defined(ENABLE_STATISTICS)
@@ -4652,14 +4805,52 @@ throw_stack_category_error:
 }
 
 
 }
 
 
+/* stack_javalocals_store ******************************************************
+   Model the effect of a ?STORE instruction upon the given javalocals array.
+  
+   IN:
+       iptr.............the ?STORE instruction
+          javalocals.......the javalocals array to modify
+  
+*******************************************************************************/
+
+void stack_javalocals_store(instruction *iptr, s4 *javalocals)
+{
+       s4 varindex;     /* index into the jd->var array */
+       s4 javaindex;    /* java local index             */
+
+       varindex = iptr->dst.varindex;
+       javaindex = iptr->sx.s23.s3.javaindex;
+
+       if (javaindex != UNUSED) {
+               assert(javaindex >= 0);
+               if (iptr->flags.bits & INS_FLAG_RETADDR)
+                       javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
+               else
+                       javalocals[javaindex] = varindex;
+
+               if (iptr->flags.bits & INS_FLAG_KILL_PREV)
+                       javalocals[javaindex-1] = UNUSED;
+
+               if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
+                       javalocals[javaindex+1] = UNUSED;
+       }
+}
+
+
 /* functions for verbose stack analysis output ********************************/
 
 #if defined(STACK_VERBOSE)
 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
 {
        printf("%c", show_jit_type_letters[v->type]);
 /* functions for verbose stack analysis output ********************************/
 
 #if defined(STACK_VERBOSE)
 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
 {
        printf("%c", show_jit_type_letters[v->type]);
-       if (v->type == TYPE_RET)
+       if (v->type == TYPE_RET) {
                printf("{L%03d}", v->vv.retaddr->nr);
                printf("{L%03d}", v->vv.retaddr->nr);
+#if defined(ENABLE_VERIFIER)
+               printf("{start=L%03d}", ((basicblock *)v->SBRSTART)->nr);
+#endif
+       }
 }
 
 
 }
 
 
@@ -4684,7 +4875,9 @@ static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
        }
        else
                putchar('-');
        }
        else
                putchar('-');
-       printf("] inlocals [");
+       printf("] javalocals ");
+       show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
+       printf(" inlocals [");
        if (bptr->inlocals) {
                for (i=0; i<sd->localcount; ++i) {
                        if (i)
        if (bptr->inlocals) {
                for (i=0; i<sd->localcount; ++i) {
                        if (i)
@@ -4725,7 +4918,7 @@ static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
        int i;
 
        printf("======================================== STACK %sANALYSE BLOCK ", 
        int i;
 
        printf("======================================== STACK %sANALYSE BLOCK ", 
-                       (reanalyse) ? "RE-" : "");
+                       (reanalyse) ? ((sd->bptr->iinstr == NULL) ? "CLONE-" : "RE-") : "");
        stack_verbose_show_block(sd, sd->bptr);
        printf("\n");
 
        stack_verbose_show_block(sd, sd->bptr);
        printf("\n");
 
@@ -4746,6 +4939,47 @@ static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
        stack_verbose_show_block(sd, sd->bptr);
        printf("\n");
 }
        stack_verbose_show_block(sd, sd->bptr);
        printf("\n");
 }
+
+static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, stackptr curstack)
+{
+       stackptr sp;
+       s4       i;
+       s4       depth;
+       varinfo *v;
+       stackptr *stack;
+
+       printf("    javalocals ");
+       show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
+       printf(" stack [");
+
+       for(i = 0, sp = curstack; sp; sp = sp->prev)
+               i++;
+       depth = i;
+
+       stack = MNEW(stackptr, depth);
+       for(sp = curstack; sp; sp = sp->prev)
+               stack[--i] = sp;
+
+       for(i=0; i<depth; ++i) {
+               if (i)
+                       putchar(' ');
+               sp = stack[i];
+               v = &(sd->var[sp->varnum]);
+
+               if (v->flags & INOUT)
+                       putchar('I');
+               if (v->flags & PREALLOC)
+                       putchar('A');
+               printf("%d:%c", sp->varnum, show_jit_type_letters[sp->type]);
+               if (v->type == TYPE_RET) {
+                       printf("(L%03d)", v->vv.retaddr->nr);
+               }
+       }
+       printf("] ... ");
+       if (iptr)
+               show_icmd(sd->jd, iptr, false, SHOW_PARSE); 
+       printf("\n");
+}
 #endif
 
 
 #endif