* Removed all Id tags.
[cacao.git] / src / vm / jit / arm / codegen.c
index 28ffc5b45985283919e8b79ca5cbbb3e9627390c..6719286f4109e1005963f4c9081d956eef16dcc4 100644 (file)
@@ -22,8 +22,6 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: codegen.c 7754 2007-04-17 23:18:15Z twisti $
-
 */
 
 
 
 #include "mm/memory.h"
 
+#include "native/localref.h"
 #include "native/native.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#endif
+#include "threads/lock-common.h"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
@@ -60,7 +57,7 @@
 #include "vm/jit/md.h"
 #include "vm/jit/methodheader.h"
 #include "vm/jit/parse.h"
-#include "vm/jit/patcher.h"
+#include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
 
 #if defined(ENABLE_LSRA)
@@ -90,8 +87,6 @@ bool codegen_emit(jitdata *jd)
        basicblock     *bptr;
        instruction    *iptr;
        exception_entry *ex;
-       s4              fieldtype;
-       s4              varindex;
 
        s4              spilledregs_num;
        s4              savedregs_num;
@@ -102,6 +97,10 @@ bool codegen_emit(jitdata *jd)
        unresolved_method  *um;
        builtintable_entry *bte;
        methoddesc         *md;
+       fieldinfo          *fi;
+       unresolved_field   *uf;
+       int                 fieldtype;
+       int                 varindex;
 
        /* get required compiler data */
 
@@ -122,7 +121,8 @@ bool codegen_emit(jitdata *jd)
 
        savedregs_num = (jd->isleafmethod) ? 0 : 1;       /* space to save the LR */
        savedregs_num += (INT_SAV_CNT - rd->savintreguse);
-       savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
+       /*savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);*/
+       assert((FLT_SAV_CNT - rd->savfltreguse) == 0);
 
        spilledregs_num = rd->memuse;
 
@@ -131,19 +131,19 @@ bool codegen_emit(jitdata *jd)
                spilledregs_num++;
 #endif
 
-       cd->stackframesize = spilledregs_num + savedregs_num;
+       cd->stackframesize = spilledregs_num * 8 + savedregs_num * 4;
 
        /* XXX QUICK FIX: We shouldn't align the stack in Java code, but
           only in native stubs. */
        /* align stack to 8-byte */
 
-       cd->stackframesize = (cd->stackframesize + 1) & ~1;
+       cd->stackframesize = (cd->stackframesize + 4) & ~4;
 
        /* SECTION: Method Header */
        /* create method header */
 
        (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
-       (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
+       (void) dseg_add_unique_s4(cd, cd->stackframesize);     /* FrameSize       */
 
 #if defined(ENABLE_THREADS)
        /* IsSync contains the offset relative to the stack pointer for the
@@ -153,7 +153,7 @@ bool codegen_emit(jitdata *jd)
        */
 
        if (checksync && (m->flags & ACC_SYNCHRONIZED))
-               (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4);/* IsSync         */
+               (void) dseg_add_unique_s4(cd, rd->memuse * 8 + 4);/* IsSync         */
        else
 #endif
                (void) dseg_add_unique_s4(cd, 0);                  /* IsSync          */
@@ -195,8 +195,8 @@ bool codegen_emit(jitdata *jd)
 
        /* create additional stack frame for spilled variables (if necessary) */
 
-       if ((cd->stackframesize - savedregs_num) > 0)
-               M_SUB_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize - savedregs_num);
+       if ((cd->stackframesize / 4 - savedregs_num) > 0)
+               M_SUB_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize / 4 - savedregs_num);
 
        /* take arguments out of register or stack frame */
 
@@ -216,44 +216,28 @@ bool codegen_emit(jitdata *jd)
 
                /* ATTENTION: we use interger registers for all arguments (even float) */
 #if !defined(ENABLE_SOFTFLOAT)
-               if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
+               if (IS_INT_LNG_TYPE(t)) {
 #endif
-                       if (!md->params[i].inmemory) {           /* register arguments    */
-                               if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
-                                       if (GET_LOW_REG(var->vv.regoff) == REG_SPLIT || GET_HIGH_REG(var->vv.regoff) == REG_SPLIT) {
-                                               /* TODO: remove this!!! */
-                                               dolog("SPLIT in local var: %x>%x (%s.%s)", s1, var->vv.regoff, m->class->name->text, m->name->text);
-                                               assert(s1 == var->vv.regoff);
-                                       }
-                                       s3 = var->vv.regoff;
-                                       SPLIT_OPEN(t, s1, REG_ITMP1);
-                                       SPLIT_LOAD(t, s1, cd->stackframesize);
-                                       SPLIT_OPEN(t, s3, REG_ITMP1);
-
+                       if (!md->params[i].inmemory) {
+                               if (!(var->flags & INMEMORY)) {
                                        if (IS_2_WORD_TYPE(t))
-                                               M_LNGMOVE(s1, s3);
+                                               M_LNGMOVE(s1, var->vv.regoff);
                                        else
-                                               M_INTMOVE(s1, s3);
-
-                                       SPLIT_STORE_AND_CLOSE(t, s3, cd->stackframesize);
+                                               M_INTMOVE(s1, var->vv.regoff);
                                }
-                               else {                               /* reg arg -> spilled    */
-                                       SPLIT_OPEN(t, s1, REG_ITMP1);
-                                       SPLIT_LOAD(t, s1, cd->stackframesize);
-
+                               else {
                                        if (IS_2_WORD_TYPE(t))
-                                               M_LST(s1, REG_SP, var->vv.regoff * 4);
+                                               M_LST(s1, REG_SP, var->vv.regoff);
                                        else
-                                               M_IST(s1, REG_SP, var->vv.regoff * 4);
-                                       /* no SPLIT_CLOSE here because arg is fully spilled now */
+                                               M_IST(s1, REG_SP, var->vv.regoff);
                                }
                        }
                        else {                                   /* stack arguments       */
                                if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
                                        if (IS_2_WORD_TYPE(t))
-                                               M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
+                                               M_LLD(var->vv.regoff, REG_SP, cd->stackframesize + s1);
                                        else
-                                               M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
+                                               M_ILD(var->vv.regoff, REG_SP, cd->stackframesize + s1);
                                }
                                else {                               /* stack arg -> spilled  */
                                        /* Reuse Memory Position on Caller Stack */
@@ -261,32 +245,27 @@ bool codegen_emit(jitdata *jd)
                                }
                        }
 #if !defined(ENABLE_SOFTFLOAT)
-               } else {                                     /* floating args         */
-                       if (!md->params[i].inmemory) {           /* register arguments    */
-                               if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
-                                       SPLIT_OPEN(t, s1, REG_ITMP1);
-                                       SPLIT_LOAD(t, s1, cd->stackframesize);
+               }
+               else {
+                       if (!md->params[i].inmemory) {
+                               if (!(var->flags & INMEMORY)) {
                                        M_CAST_INT_TO_FLT_TYPED(t, s1, var->vv.regoff);
                                }
-                               else {                               /* reg arg -> spilled    */
-                                       SPLIT_OPEN(t, s1, REG_ITMP1);
-                                       SPLIT_LOAD(t, s1, cd->stackframesize);
-
+                               else {
                                        if (IS_2_WORD_TYPE(t))
-                                               M_LST(s1, REG_SP, var->vv.regoff * 4);
+                                               M_LST(s1, REG_SP, var->vv.regoff);
                                        else
-                                               M_IST(s1, REG_SP, var->vv.regoff * 4);
-                                       /* no SPLIT_CLOSE here because arg is fully spilled now */
+                                               M_IST(s1, REG_SP, var->vv.regoff);
                                }
                        }
-                       else {                                   /* stack arguments       */
-                               if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
+                       else {
+                               if (!(var->flags & INMEMORY)) {
                                        if (IS_2_WORD_TYPE(t))
-                                               M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
+                                               M_DLD(var->vv.regoff, REG_SP, cd->stackframesize + s1);
                                        else
-                                               M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
+                                               M_FLD(var->vv.regoff, REG_SP, cd->stackframesize + s1);
                                }
-                               else {                               /* stack arg -> spilled  */
+                               else {
                                        /* Reuse Memory Position on Caller Stack */
                                        var->vv.regoff = cd->stackframesize + s1;
                                }
@@ -301,12 +280,12 @@ bool codegen_emit(jitdata *jd)
        if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
                /* stack offset for monitor argument */
 
-               s1 = rd->memuse;
+               s1 = rd->memuse * 8;
 
 # if !defined(NDEBUG)
                if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
                        M_STMFD(BITMASK_ARGS, REG_SP);
-                       s1 += 4;
+                       s1 += 4 * 4;
                }
 # endif
 
@@ -320,7 +299,7 @@ bool codegen_emit(jitdata *jd)
                        emit_nullpointer_check_force(cd, iptr, REG_A0);
                }
 
-               M_STR(REG_A0, REG_SP, s1 * 4);
+               M_STR(REG_A0, REG_SP, s1);
                disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
                M_DSEG_BRANCH(disp);
                s1 = (s4) (cd->mcodeptr - cd->mcodebase);
@@ -342,6 +321,9 @@ bool codegen_emit(jitdata *jd)
 
        /* end of header generation */
 
+       /* create replacement points */
+       REPLACEMENT_POINTS_INIT(cd, jd);
+
        /* SECTION: ICMD Code Generation */
        /* for all basic blocks */
 
@@ -358,6 +340,9 @@ bool codegen_emit(jitdata *jd)
 
                codegen_resolve_branchrefs(cd, bptr);
 
+               /* handle replacement points */
+               REPLACEMENT_POINT_BLOCK_START(cd, bptr);
+
                /* copy interface registers to their destination */
 
                len = bptr->indepth;
@@ -430,9 +415,8 @@ bool codegen_emit(jitdata *jd)
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                disp = dseg_add_unique_address(cd, NULL);
 
-                               codegen_addpatchref(cd, PATCHER_aconst,
-                                                   iptr->sx.val.c.ref,
-                                                                       disp);
+                               patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
+                                                   iptr->sx.val.c.ref, disp);
 
                                if (opt_showdisassemble)
                                        M_NOP;
@@ -1158,7 +1142,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        /* implicit null-pointer check */
-                       M_ILD_INTERN(d, s1, OFFSET(java_arrayheader, size));
+                       M_ILD_INTERN(d, s1, OFFSET(java_array_t, size));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1170,7 +1154,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ADD(REG_ITMP1, s1, s2); /* REG_ITMP1 = s1 + 1 * s2 */
-                       M_LDRSB(d, REG_ITMP1, OFFSET(java_bytearray, data[0]));
+                       M_LDRSB(d, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1182,7 +1166,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ADD(REG_ITMP1, s1, REG_LSL(s2, 1)); /* REG_ITMP1 = s1 + 2 * s2 */
-                       M_LDRH(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
+                       M_LDRH(d, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1194,7 +1178,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ADD(REG_ITMP1, s1, REG_LSL(s2, 1)); /* REG_ITMP1 = s1 + 2 * s2 */
-                       M_LDRSH(d, REG_ITMP1, OFFSET(java_shortarray, data[0]));
+                       M_LDRSH(d, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1206,7 +1190,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */
-                       M_ILD_INTERN(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
+                       M_ILD_INTERN(d, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1218,7 +1202,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ADD(REG_ITMP3, s1, REG_LSL(s2, 3)); /* REG_ITMP3 = s1 + 8 * s2 */
-                       M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
+                       M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1231,10 +1215,10 @@ bool codegen_emit(jitdata *jd)
                        M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */
 #if !defined(ENABLE_SOFTFLOAT)
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
-                       M_FLD_INTERN(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
+                       M_FLD_INTERN(d, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
 #else
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
-                       M_ILD_INTERN(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
+                       M_ILD_INTERN(d, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
 #endif
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1248,10 +1232,10 @@ bool codegen_emit(jitdata *jd)
                        M_ADD(REG_ITMP3, s1, REG_LSL(s2, 3)); /* REG_ITMP3 = s1 + 8 * s2 */
 #if !defined(ENABLE_SOFTFLOAT)
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
-                       M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
+                       M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
 #else
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
-                       M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
+                       M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
 #endif
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1264,7 +1248,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */
-                       M_LDR_INTERN(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
+                       M_LDR_INTERN(d, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1276,7 +1260,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
                        M_ADD(REG_ITMP1, s1, s2); /* REG_ITMP1 = s1 + 1 * s2 */
-                       M_STRB(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
+                       M_STRB(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
                        break;
 
                case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1287,7 +1271,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
                        M_ADD(REG_ITMP1, s1, REG_LSL(s2, 1)); /* REG_ITMP1 = s1 + 2 * s2 */
-                       M_STRH(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
+                       M_STRH(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
                        break;
 
                case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1298,7 +1282,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
                        M_ADD(REG_ITMP1, s1, REG_LSL(s2, 1)); /* REG_ITMP1 = s1 + 2 * s2 */
-                       M_STRH(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
+                       M_STRH(s3, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
                        break;
 
                case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1309,7 +1293,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
                        M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */
-                       M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
+                       M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
                        break;
 
                case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1320,7 +1304,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ADD(REG_ITMP3, s1, REG_LSL(s2, 3)); /* REG_ITMP3 = s1 + 8 * s2 */
                        s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
-                       M_LST_INTERN(s3, REG_ITMP3, OFFSET(java_longarray, data[0]));
+                       M_LST_INTERN(s3, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
                        break;
 
                case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1332,10 +1316,10 @@ bool codegen_emit(jitdata *jd)
                        M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */
 #if !defined(ENABLE_SOFTFLOAT)
                        s3 = emit_load_s3(jd, iptr, REG_FTMP1);
-                       M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
+                       M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
 #else
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
+                       M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
 #endif
                        break;
 
@@ -1348,10 +1332,10 @@ bool codegen_emit(jitdata *jd)
                        M_ADD(REG_ITMP1, s1, REG_LSL(s2, 3)); /* REG_ITMP1 = s1 + 8 * s2 */
 #if !defined(ENABLE_SOFTFLOAT)
                        s3 = emit_load_s3(jd, iptr, REG_FTMP1);
-                       M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
+                       M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
 #else
                        s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
-                       M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
+                       M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
 #endif
                        break;
 
@@ -1384,36 +1368,33 @@ bool codegen_emit(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
                        M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */
-                       M_STR_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
+                       M_STR_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
                        break;
 
                case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               unresolved_field *uf = iptr->sx.s23.s3.uf;
-
+                               uf        = iptr->sx.s23.s3.uf;
                                fieldtype = uf->fieldref->parseddesc.fd->type;
+                               disp      = dseg_add_unique_address(cd, NULL);
 
-                               disp = dseg_add_unique_address(cd, NULL);
-
-                               codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
+                               patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
 
                                if (opt_showdisassemble)
                                        M_NOP;
                        }
                        else {
-                               fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
-
+                               fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
+                               disp      = dseg_add_address(cd, fi->value);
 
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
-                                       codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class,
+                                                           fi->class, 0);
 
                                        if (opt_showdisassemble)
                                                M_NOP;
                                }
-
-                               disp = dseg_add_address(cd, &(fi->value));
                        }
 
                        M_DSEG_LOAD(REG_ITMP3, disp);
@@ -1452,30 +1433,27 @@ bool codegen_emit(jitdata *jd)
                case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               unresolved_field *uf = iptr->sx.s23.s3.uf;
-
+                               uf        = iptr->sx.s23.s3.uf;
                                fieldtype = uf->fieldref->parseddesc.fd->type;
+                               disp      = dseg_add_unique_address(cd, NULL);
 
-                               disp = dseg_add_unique_address(cd, NULL);
-
-                               codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
+                               patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
 
                                if (opt_showdisassemble)
                                        M_NOP;
                        }
                        else {
-                               fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
-
+                               fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
+                               disp      = dseg_add_address(cd, fi->value);
 
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
-                                       codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class,
+                                                           fi->class, 0);
 
                                        if (opt_showdisassemble)
                                                M_NOP;
                                }
-
-                               disp = dseg_add_address(cd, &(fi->value));
                        }
 
                        M_DSEG_LOAD(REG_ITMP3, disp);
@@ -1517,13 +1495,12 @@ bool codegen_emit(jitdata *jd)
 
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               unresolved_field *uf = iptr->sx.s23.s3.uf;
-
+                               uf        = iptr->sx.s23.s3.uf;
                                fieldtype = uf->fieldref->parseddesc.fd->type;
+                               disp      = 0;
                        }
                        else {
-                               fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
-
+                               fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
                                disp      = fi->offset;
                        }
@@ -1535,14 +1512,13 @@ bool codegen_emit(jitdata *jd)
 #endif
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               unresolved_field *uf = iptr->sx.s23.s3.uf;
+                               /* XXX REMOVE ME */
+                               uf = iptr->sx.s23.s3.uf;
 
-                               codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
+                               patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
 
                                if (opt_showdisassemble)
                                        M_NOP;
-
-                               disp = 0;
                        }
 
                        switch (fieldtype) {
@@ -1583,13 +1559,12 @@ bool codegen_emit(jitdata *jd)
                        emit_nullpointer_check(cd, iptr, s1);
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               unresolved_field *uf = iptr->sx.s23.s3.uf;
-
+                               uf        = iptr->sx.s23.s3.uf;
                                fieldtype = uf->fieldref->parseddesc.fd->type;
+                               disp      = 0;
                        }
                        else {
-                               fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
-
+                               fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
                                disp      = fi->offset;
                        }
@@ -1625,14 +1600,13 @@ bool codegen_emit(jitdata *jd)
                        }
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               unresolved_field *uf = iptr->sx.s23.s3.uf;
+                               /* XXX REMOVE ME */
+                               uf = iptr->sx.s23.s3.uf;
 
-                               codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
+                               patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
 
                                if (opt_showdisassemble)
                                        M_NOP;
-
-                               disp = 0;
                        }
 
                        switch (fieldtype) {
@@ -1670,7 +1644,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        M_INTMOVE(s1, REG_ITMP1_XPTR);
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               codegen_addpatchref(cd, PATCHER_athrow_areturn,
+                               patcher_add_patch_ref(jd, PATCHER_resolve_class,
                                                                        iptr->sx.s23.s2.uc, 0);
 
                                if (opt_showdisassemble)
@@ -2092,6 +2066,7 @@ bool codegen_emit(jitdata *jd)
                case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
 
 #if !defined(ENABLE_SOFTFLOAT)
+                       REPLACEMENT_POINT_RETURN(cd, iptr);
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        M_CAST_FLT_TO_INT_TYPED(VAROP(iptr->s1)->type, s1, REG_RESULT);
                        goto ICMD_RETURN_do;
@@ -2099,6 +2074,7 @@ bool codegen_emit(jitdata *jd)
 
                case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
 
+                       REPLACEMENT_POINT_RETURN(cd, iptr);
                        s1 = emit_load_s1(jd, iptr, REG_RESULT);
                        M_INTMOVE(s1, REG_RESULT);
                        goto ICMD_RETURN_do;
@@ -2106,6 +2082,7 @@ bool codegen_emit(jitdata *jd)
                case ICMD_DRETURN:      /* ..., retvalue ==> ...                      */
 
 #if !defined(ENABLE_SOFTFLOAT)
+                       REPLACEMENT_POINT_RETURN(cd, iptr);
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        M_CAST_FLT_TO_INT_TYPED(VAROP(iptr->s1)->type, s1, REG_RESULT_PACKED);
                        goto ICMD_RETURN_do;
@@ -2113,16 +2090,18 @@ bool codegen_emit(jitdata *jd)
 
                case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
 
+                       REPLACEMENT_POINT_RETURN(cd, iptr);
                        s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
                        M_LNGMOVE(s1, REG_RESULT_PACKED);
                        goto ICMD_RETURN_do;
 
                case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
 
+                       REPLACEMENT_POINT_RETURN(cd, iptr);
                        s1 = emit_load_s1(jd, iptr, REG_RESULT);
                        M_INTMOVE(s1, REG_RESULT);
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               codegen_addpatchref(cd, PATCHER_athrow_areturn,
+                               patcher_add_patch_ref(jd, PATCHER_resolve_class,
                                                                        iptr->sx.s23.s2.uc, 0);
 
                                if (opt_showdisassemble)
@@ -2131,6 +2110,8 @@ bool codegen_emit(jitdata *jd)
                        goto ICMD_RETURN_do;
 
                case ICMD_RETURN:       /* ...  ==> ...                               */
+
+                       REPLACEMENT_POINT_RETURN(cd, iptr);
                        ICMD_RETURN_do:
 
 #if !defined(NDEBUG)
@@ -2144,7 +2125,7 @@ bool codegen_emit(jitdata *jd)
                        if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
                                /* stack offset for monitor argument */
 
-                               s1 = rd->memuse;
+                               s1 = rd->memuse * 8;
 
                                /* we need to save the proper return value */
 
@@ -2155,11 +2136,11 @@ bool codegen_emit(jitdata *jd)
                                case ICMD_FRETURN: /* XXX TWISTI: is that correct? */
                                case ICMD_DRETURN:
                                        M_STMFD(BITMASK_RESULT, REG_SP);
-                                       s1 += 2;
+                                       s1 += 2 * 4;
                                        break;
                                }
 
-                               M_LDR(REG_A0, REG_SP, s1 * 4);
+                               M_LDR(REG_A0, REG_SP, s1);
                                disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
                                M_DSEG_BRANCH(disp);
 
@@ -2181,8 +2162,8 @@ bool codegen_emit(jitdata *jd)
 
                        /* deallocate stackframe for spilled variables */
 
-                       if ((cd->stackframesize - savedregs_num) > 0)
-                               M_ADD_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize - savedregs_num);
+                       if ((cd->stackframesize / 4 - savedregs_num) > 0)
+                               M_ADD_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize / 4 - savedregs_num);
 
                        /* restore callee saved registers + do return */
 
@@ -2211,6 +2192,8 @@ bool codegen_emit(jitdata *jd)
                case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
                case ICMD_INVOKEINTERFACE:
 
+                       REPLACEMENT_POINT_INVOKE(cd, iptr);
+
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                lm = NULL;
                                um = iptr->sx.s23.s3.um;
@@ -2241,24 +2224,21 @@ bool codegen_emit(jitdata *jd)
                                if (IS_INT_LNG_TYPE(var->type)) {
 #endif /* !defined(ENABLE_SOFTFLOAT) */
                                        if (!md->params[s3].inmemory) {
-                                               SPLIT_OPEN(var->type, s1, REG_ITMP2);
                                                s1 = emit_load(jd, iptr, var, d);
 
                                                if (IS_2_WORD_TYPE(var->type))
                                                        M_LNGMOVE(s1, d);
                                                else
                                                        M_INTMOVE(s1, d);
-
-                                               SPLIT_STORE_AND_CLOSE(var->type, d, 0);
                                        }
                                        else {
                                                if (IS_2_WORD_TYPE(var->type)) {
                                                        s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
-                                                       M_LST(s1, REG_SP, d * 4);
+                                                       M_LST(s1, REG_SP, d);
                                                }
                                                else {
                                                        s1 = emit_load(jd, iptr, var, REG_ITMP1);
-                                                       M_IST(s1, REG_SP, d * 4);
+                                                       M_IST(s1, REG_SP, d);
                                                }
                                        }
 #if !defined(ENABLE_SOFTFLOAT)
@@ -2266,16 +2246,14 @@ bool codegen_emit(jitdata *jd)
                                else {
                                        if (!md->params[s3].inmemory) {
                                                s1 = emit_load(jd, iptr, var, REG_FTMP1);
-                                               SPLIT_OPEN(var->type, d, REG_ITMP1);
                                                M_CAST_FLT_TO_INT_TYPED(var->type, s1, d);
-                                               SPLIT_STORE_AND_CLOSE(var->type, d, 0);
                                        }
                                        else {
                                                s1 = emit_load(jd, iptr, var, REG_FTMP1);
                                                if (IS_2_WORD_TYPE(var->type))
-                                                       M_DST(s1, REG_SP, d * 4);
+                                                       M_DST(s1, REG_SP, d);
                                                else
-                                                       M_FST(s1, REG_SP, d * 4);
+                                                       M_FST(s1, REG_SP, d);
                                        }
                                }
 #endif /* !defined(ENABLE_SOFTFLOAT) */
@@ -2305,7 +2283,7 @@ bool codegen_emit(jitdata *jd)
                                if (lm == NULL) {
                                        disp = dseg_add_unique_address(cd, NULL);
 
-                                       codegen_addpatchref(cd, PATCHER_invokestatic_special,
+                                       patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
                                                                                um, disp);
 
                                        if (opt_showdisassemble)
@@ -2326,7 +2304,7 @@ bool codegen_emit(jitdata *jd)
 
                        case ICMD_INVOKEVIRTUAL:
                                if (lm == NULL) {
-                                       codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
+                                       patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
 
                                        if (opt_showdisassemble)
                                                M_NOP;
@@ -2339,7 +2317,7 @@ bool codegen_emit(jitdata *jd)
 
                                /* implicit null-pointer check */
                                M_LDR_INTERN(REG_METHODPTR, REG_A0,
-                                                        OFFSET(java_objectheader, vftbl));
+                                                        OFFSET(java_object_t, vftbl));
                                M_LDR_INTERN(REG_PV, REG_METHODPTR, s1);
 
                                /* generate the actual call */
@@ -2352,7 +2330,7 @@ bool codegen_emit(jitdata *jd)
 
                        case ICMD_INVOKEINTERFACE:
                                if (lm == NULL) {
-                                       codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
+                                       patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
 
                                        if (opt_showdisassemble)
                                                M_NOP;
@@ -2368,7 +2346,7 @@ bool codegen_emit(jitdata *jd)
 
                                /* implicit null-pointer check */
                                M_LDR_INTERN(REG_METHODPTR, REG_A0,
-                                                        OFFSET(java_objectheader, vftbl));
+                                                        OFFSET(java_object_t, vftbl));
                                M_LDR_INTERN(REG_METHODPTR, REG_METHODPTR, s1);
                                M_LDR_INTERN(REG_PV, REG_METHODPTR, s2);
 
@@ -2381,6 +2359,9 @@ bool codegen_emit(jitdata *jd)
                                break;
                        }
 
+                       /* store size of call code in replacement point */
+                       REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
+
                        /* store return value */
 
                        d = md->returntype.type;
@@ -2431,7 +2412,6 @@ bool codegen_emit(jitdata *jd)
                        break;
 
                case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
-                                     /* val.a: (classinfo*) superclass               */
 
                        if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
                                /* object type cast-check */
@@ -2448,9 +2428,9 @@ bool codegen_emit(jitdata *jd)
                                superindex = super->index;
                        }
 
-#if defined(ENABLE_THREADS)
-                       codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+                               if ((super == NULL) || !(super->flags & ACC_INTERFACE))
+                                       CODEGEN_CRITICAL_SECTION_NEW;
+
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
 
                        /* if class is not resolved, check which code to call */
@@ -2460,7 +2440,7 @@ bool codegen_emit(jitdata *jd)
                                emit_label_beq(cd, BRANCH_LABEL_1);
 
                                disp = dseg_add_unique_s4(cd, 0); /* super->flags */
-                               codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
+                               patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
                                                    iptr->sx.s23.s3.c.ref, disp);
 
                                if (opt_showdisassemble)
@@ -2476,10 +2456,12 @@ bool codegen_emit(jitdata *jd)
                        /* interface checkcast code */
 
                        if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
+                               if ((super == NULL) || !IS_IMM(superindex)) {
+                                       disp = dseg_add_unique_s4(cd, superindex);
+                               }
                                if (super == NULL) {
-                                       codegen_addpatchref(cd,
-                                                           PATCHER_checkcast_instanceof_interface,
-                                                           iptr->sx.s23.s3.c.ref, 0);
+                                       patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_index,
+                                                           iptr->sx.s23.s3.c.ref, disp);
 
                                        if (opt_showdisassemble)
                                                M_NOP;
@@ -2489,14 +2471,42 @@ bool codegen_emit(jitdata *jd)
                                        emit_label_beq(cd, BRANCH_LABEL_3);
                                }
 
-                               M_LDR_INTERN(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
+                               M_LDR_INTERN(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
                                M_LDR_INTERN(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
-                               assert(IS_IMM(superindex));
-                               M_CMP_IMM(REG_ITMP3, superindex);
+
+                               /* we put unresolved or non-immediate superindices onto dseg */
+                               if ((super == NULL) || !IS_IMM(superindex)) {
+                                       /* disp was computed before we added the patcher */
+                                       M_DSEG_LOAD(REG_ITMP2, disp);
+                                       M_CMP(REG_ITMP3, REG_ITMP2);
+                               } else {
+                                       assert(IS_IMM(superindex));
+                                       M_CMP_IMM(REG_ITMP3, superindex);
+                               }
+
                                emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
 
-                               s2 = OFFSET(vftbl_t, interfacetable[0]) -
-                                       superindex * sizeof(methodptr*);
+                               /* if we loaded the superindex out of the dseg above, we do
+                                  things differently here! */
+                               if ((super == NULL) || !IS_IMM(superindex)) {
+
+                                       M_LDR_INTERN(REG_ITMP3, s1, OFFSET(java_object_t, vftbl));
+
+                                       /* this assumes something */
+                                       assert(OFFSET(vftbl_t, interfacetable[0]) == 0);
+
+                                       /* this does: REG_ITMP3 - superindex * sizeof(methodptr*) */
+                                       assert(sizeof(methodptr*) == 4);
+                                       M_SUB(REG_ITMP2, REG_ITMP3, REG_LSL(REG_ITMP2, 2));
+
+                                       s2 = 0;
+
+                               } else {
+
+                                       s2 = OFFSET(vftbl_t, interfacetable[0]) -
+                                                               superindex * sizeof(methodptr*);
+
+                               }
 
                                M_LDR_INTERN(REG_ITMP3, REG_ITMP2, s2);
                                M_TST(REG_ITMP3, REG_ITMP3);
@@ -2516,7 +2526,7 @@ bool codegen_emit(jitdata *jd)
 
                                        disp = dseg_add_unique_address(cd, NULL);
 
-                                       codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
+                                       patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
                                                            iptr->sx.s23.s3.c.ref,
                                                                                disp);
 
@@ -2530,19 +2540,19 @@ bool codegen_emit(jitdata *jd)
                                        emit_label_beq(cd, BRANCH_LABEL_5);
                                }
 
-                               M_LDR_INTERN(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
+                               M_LDR_INTERN(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
                                M_DSEG_LOAD(REG_ITMP3, disp);
-#if defined(ENABLE_THREADS)
-                               codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
+                               CODEGEN_CRITICAL_SECTION_START;
+
                                M_LDR_INTERN(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                M_LDR_INTERN(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
                                M_SUB(REG_ITMP2, REG_ITMP2, REG_ITMP3);
                                M_DSEG_LOAD(REG_ITMP3, disp);
                                M_LDR_INTERN(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
-#if defined(ENABLE_THREADS)
-                               codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
+                               CODEGEN_CRITICAL_SECTION_END;
+
                                M_CMP(REG_ITMP2, REG_ITMP3);
                                emit_classcast_check(cd, iptr, BRANCH_UGT, 0, s1);
 
@@ -2566,7 +2576,7 @@ bool codegen_emit(jitdata *jd)
                                if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                        disp = dseg_add_unique_address(cd, NULL);
 
-                                       codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
+                                       patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
                                                                                iptr->sx.s23.s3.c.ref,
                                                                                disp);
 
@@ -2596,7 +2606,7 @@ bool codegen_emit(jitdata *jd)
                        break;
 
                case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
-                                     /* val.a: (classinfo*) superclass               */
+
                        {
                        classinfo *super;
                        s4         superindex;
@@ -2610,11 +2620,12 @@ bool codegen_emit(jitdata *jd)
                                superindex = super->index;
                        }
 
-#if defined(ENABLE_THREADS)
-                       codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+                       if ((super == NULL) || !(super->flags & ACC_INTERFACE))
+                               CODEGEN_CRITICAL_SECTION_NEW;
+
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+
                        if (s1 == d) {
                                M_MOV(REG_ITMP1, s1);
                                s1 = REG_ITMP1;
@@ -2629,7 +2640,7 @@ bool codegen_emit(jitdata *jd)
                                emit_label_beq(cd, BRANCH_LABEL_1);
 
                                disp = dseg_add_unique_s4(cd, 0); /* super->flags */
-                               codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
+                               patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
                                                    iptr->sx.s23.s3.c.ref, disp);
 
                                if (opt_showdisassemble)
@@ -2645,15 +2656,17 @@ bool codegen_emit(jitdata *jd)
                        /* interface checkcast code */
 
                        if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
+                               if ((super == NULL) || !IS_IMM(superindex)) {
+                                       disp = dseg_add_unique_s4(cd, superindex);
+                               }
                                if (super == NULL) {
                                        /* If d == REG_ITMP2, then it's destroyed in check
                                           code above.  */
                                        if (d == REG_ITMP2)
                                                M_EOR(d, d, d);
 
-                                       codegen_addpatchref(cd,
-                                                           PATCHER_checkcast_instanceof_interface,
-                                                           iptr->sx.s23.s3.c.ref, 0);
+                                       patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_index,
+                                                           iptr->sx.s23.s3.c.ref, disp);
 
                                        if (opt_showdisassemble)
                                                M_NOP;
@@ -2664,15 +2677,47 @@ bool codegen_emit(jitdata *jd)
                                        emit_label_beq(cd, BRANCH_LABEL_3);
                                }
 
-                               M_LDR_INTERN(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
+                               M_LDR_INTERN(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
                                M_LDR_INTERN(REG_ITMP3,
                                                         REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
-                               assert(IS_IMM(superindex));
-                               M_CMP_IMM(REG_ITMP3, superindex);
-                               M_BLE(2);
 
-                               s2 = OFFSET(vftbl_t, interfacetable[0]) -
-                                       superindex * sizeof(methodptr*);
+                               /* we put unresolved or non-immediate superindices onto dseg
+                                  and do things slightly different */
+                               if ((super == NULL) || !IS_IMM(superindex)) {
+                                       /* disp was computed before we added the patcher */
+                                       M_DSEG_LOAD(REG_ITMP2, disp);
+                                       M_CMP(REG_ITMP3, REG_ITMP2);
+
+                                       if (d == REG_ITMP2) {
+                                               M_EORLE(d, d, d);
+                                               M_BLE(4);
+                                       } else {
+                                               M_BLE(3);
+                                       }
+
+                                       /* this assumes something */
+                                       assert(OFFSET(vftbl_t, interfacetable[0]) == 0);
+
+                                       /* this does: REG_ITMP3 - superindex * sizeof(methodptr*) */
+                                       assert(sizeof(methodptr*) == 4);
+                                       M_SUB(REG_ITMP1, REG_ITMP1, REG_LSL(REG_ITMP2, 2));
+
+                                       if (d == REG_ITMP2) {
+                                               M_EOR(d, d, d);
+                                       }
+
+                                       s2 = 0;
+
+                               } else {
+                                       assert(IS_IMM(superindex));
+                                       M_CMP_IMM(REG_ITMP3, superindex);
+
+                                       M_BLE(2);
+
+                                       s2 = OFFSET(vftbl_t, interfacetable[0]) -
+                                               superindex * sizeof(methodptr*);
+
+                               }
 
                                M_LDR_INTERN(REG_ITMP3, REG_ITMP1, s2);
                                M_TST(REG_ITMP3, REG_ITMP3);
@@ -2692,9 +2737,8 @@ bool codegen_emit(jitdata *jd)
 
                                        disp = dseg_add_unique_address(cd, NULL);
 
-                                       codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
-                                                           iptr->sx.s23.s3.c.ref,
-                                                                               disp);
+                                       patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
+                                                           iptr->sx.s23.s3.c.ref, disp);
 
                                        if (opt_showdisassemble)
                                                M_NOP;
@@ -2707,17 +2751,17 @@ bool codegen_emit(jitdata *jd)
                                        emit_label_beq(cd, BRANCH_LABEL_5);
                                }
 
-                               M_LDR_INTERN(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
+                               M_LDR_INTERN(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
                                M_DSEG_LOAD(REG_ITMP2, disp);
-#if defined(ENABLE_THREADS)
-                               codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
+                               CODEGEN_CRITICAL_SECTION_START;
+
                                M_LDR_INTERN(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
                                M_LDR_INTERN(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                M_LDR_INTERN(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
-#if defined(ENABLE_THREADS)
-                               codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
+                               CODEGEN_CRITICAL_SECTION_END;
+
                                M_SUB(REG_ITMP1, REG_ITMP1, REG_ITMP3);
                                M_CMP(REG_ITMP1, REG_ITMP2);
                                /* If d == REG_ITMP2, then it's destroyed */
@@ -2767,7 +2811,7 @@ bool codegen_emit(jitdata *jd)
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                disp = dseg_add_unique_address(cd, NULL);
 
-                               codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
+                               patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
                                                                        iptr->sx.s23.s3.c.ref, disp);
 
                                if (opt_showdisassemble)
@@ -2824,9 +2868,9 @@ bool codegen_emit(jitdata *jd)
        dseg_createlinenumbertable(cd);
 
 
-       /* generate stubs */
+       /* generate traps */
 
-       emit_patcher_stubs(jd);
+       emit_patcher_traps(jd);
 
        /* everything's ok */
 
@@ -2887,20 +2931,20 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
        /* calculate stackframe size */
 
-       cd->stackframesize = 
-               1 +                                                /* return address  */
-               sizeof(stackframeinfo) / SIZEOF_VOID_P +           /* stackframeinfo  */
-               sizeof(localref_table) / SIZEOF_VOID_P +           /* localref_table  */
-               nmd->memuse;                                       /* stack arguments */
+       cd->stackframesize =
+               4 +                                                /* return address  */
+               sizeof(stackframeinfo) +                           /* stackframeinfo  */
+               sizeof(localref_table) +                           /* localref_table  */
+               nmd->memuse * 4;                                   /* stack arguments */
 
        /* align stack to 8-byte */
 
-       cd->stackframesize = (cd->stackframesize + 1) & ~1;
+       cd->stackframesize = (cd->stackframesize + 4) & ~4;
 
        /* create method header */
 
        (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
-       (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
+       (void) dseg_add_unique_s4(cd, cd->stackframesize);     /* FrameSize       */
        (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
        (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
        (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
@@ -2911,7 +2955,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
        /* generate stub code */
 
        M_STMFD(1<<REG_LR, REG_SP);
-       M_SUB_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize - 1);
+       M_SUB_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize / 4 - 1);
 
 #if !defined(NDEBUG)
        if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
@@ -2924,7 +2968,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
 #if !defined(WITH_STATIC_CLASSPATH)
        if (f == NULL) {
-               codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
+               patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
 
                if (opt_showdisassemble)
                        M_NOP;
@@ -2939,11 +2983,11 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
        /* create native stackframe info */
 
-       assert(IS_IMM(4*4 + cd->stackframesize * 4));
-       M_ADD_IMM(REG_A0, REG_SP, 4*4 + cd->stackframesize * 4 - SIZEOF_VOID_P);
+       assert(IS_IMM(4*4 + cd->stackframesize));
+       M_ADD_IMM(REG_A0, REG_SP, 4*4 + cd->stackframesize - SIZEOF_VOID_P);
        M_MOV(REG_A1, REG_PV);
-       M_ADD_IMM(REG_A2, REG_SP, 4*4 + cd->stackframesize * 4);
-       M_LDR_INTERN(REG_A3, REG_SP, 4*4 + cd->stackframesize * 4 - SIZEOF_VOID_P);
+       M_ADD_IMM(REG_A2, REG_SP, 4*4 + cd->stackframesize);
+       M_LDR_INTERN(REG_A3, REG_SP, 4*4 + cd->stackframesize - SIZEOF_VOID_P);
        disp = dseg_add_functionptr(cd, codegen_start_native_call);
        M_DSEG_BRANCH(disp);
 
@@ -2970,8 +3014,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
                        if (!nmd->params[j].inmemory) {
 #if !defined(__ARM_EABI__)
-                               SPLIT_OPEN(t, s1, REG_ITMP1);
-                               SPLIT_LOAD(t, s1, cd->stackframesize);
                                SPLIT_OPEN(t, s2, REG_ITMP1);
 #endif
 
@@ -2985,16 +3027,10 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 #endif
                        }
                        else {
-#if !defined(__ARM_EABI__)
-                               SPLIT_OPEN(t, s1, REG_ITMP1);
-                               SPLIT_LOAD(t, s1, cd->stackframesize);
-#endif
-
                                if (IS_2_WORD_TYPE(t))
-                                       M_LST(s1, REG_SP, s2 * 4);
+                                       M_LST(s1, REG_SP, s2);
                                else
-                                       M_IST(s1, REG_SP, s2 * 4);
-                               /* no SPLIT_CLOSE here because argument is fully on stack now */
+                                       M_IST(s1, REG_SP, s2);
                        }
                }
                else {
@@ -3002,12 +3038,12 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
                        s2 = nmd->params[j].regoff;
 
                        if (IS_2_WORD_TYPE(t)) {
-                               M_LLD(REG_ITMP12_PACKED, REG_SP, s1 * 4);
-                               M_LST(REG_ITMP12_PACKED, REG_SP, s2 * 4);
+                               M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
+                               M_LST(REG_ITMP12_PACKED, REG_SP, s2);
                        }
                        else {
-                               M_ILD(REG_ITMP1, REG_SP, s1 * 4);
-                               M_IST(REG_ITMP1, REG_SP, s2 * 4);
+                               M_ILD(REG_ITMP1, REG_SP, s1);
+                               M_IST(REG_ITMP1, REG_SP, s2);
                        }
                }
        }
@@ -3064,7 +3100,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
        M_STMFD(BITMASK_RESULT, REG_SP);
 
-       M_ADD_IMM(REG_A0, REG_SP, 2*4 + cd->stackframesize * 4 - SIZEOF_VOID_P);
+       M_ADD_IMM(REG_A0, REG_SP, 2*4 + cd->stackframesize - SIZEOF_VOID_P);
        disp = dseg_add_functionptr(cd, codegen_finish_native_call);
        M_DSEG_BRANCH(disp);
        s1 = (s4) (cd->mcodeptr - cd->mcodebase);
@@ -3075,7 +3111,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
        /* finish stub code, but do not yet return to caller */
 
-       M_ADD_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize - 1);
+       M_ADD_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize / 4 - 1);
        M_LDMFD(1<<REG_LR, REG_SP);
 
        /* check for exception */
@@ -3093,7 +3129,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
        /* generate patcher stubs */
 
-       emit_patcher_stubs(jd);
+       emit_patcher_traps(jd);
 }