* src/vm/jit/arm/codegen.c (codegen_emit): Allow larger displacements for
authorMichael Starzinger <michi@complang.tuwien.ac.at>
Thu, 13 Nov 2008 10:41:08 +0000 (11:41 +0100)
committerMichael Starzinger <michi@complang.tuwien.ac.at>
Thu, 13 Nov 2008 10:41:08 +0000 (11:41 +0100)
ICMD_INVOKEVIRTUAL.
* src/vm/jit/arm/patcher.c (patcher_invokevirtual): Adapted to above change.

src/vm/jit/arm/codegen.c
src/vm/jit/arm/patcher.c

index b78fdd2cfbb7048d5a861de167a38bc834a47c19..a0085a806efce8d275e22c62404722e04352c67c 100644 (file)
@@ -2296,21 +2296,33 @@ bool codegen_emit(jitdata *jd)
 
                        case ICMD_INVOKEVIRTUAL:
                                if (lm == NULL) {
-                                       patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
+                                       int32_t disp = dseg_add_unique_s4(cd, 0);
+                                       patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, disp);
 
-                                       s1 = 0;
-                               }
-                               else
-                                       s1 = OFFSET(vftbl_t, table[0]) +
-                                               sizeof(methodptr) * lm->vftblindex;
+                                       // The following instruction MUST NOT change a0 because of the implicit NPE check.
+                                       M_LDR_INTERN(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
 
-                               /* implicit null-pointer check */
-                               M_LDR_INTERN(REG_METHODPTR, REG_A0,
-                                                        OFFSET(java_object_t, vftbl));
-                               M_LDR_INTERN(REG_PV, REG_METHODPTR, s1);
+                                       // Sanity check.
+                                       assert(REG_ITMP1 != REG_METHODPTR);
+                                       assert(REG_ITMP2 == REG_METHODPTR);
 
-                               /* generate the actual call */
+                                       M_DSEG_LOAD(REG_ITMP1, disp);
+                                       M_ADD(REG_METHODPTR, REG_METHODPTR, REG_ITMP1);
 
+                                       // This must be a load with displacement,
+                                       // otherwise the JIT method address patching does
+                                       // not work anymore (see md_jit_method_patch_address).
+                                       M_LDR_INTERN(REG_PV, REG_METHODPTR, 0);
+                               }
+                               else {
+                                       s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
+
+                                       // The following instruction MUST NOT change a0 because of the implicit NPE check.
+                                       M_LDR_INTERN(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
+                                       M_LDR(REG_PV, REG_METHODPTR, s1);
+                               }
+
+                               // Generate the actual call.
                                M_MOV(REG_LR, REG_PC);
                                M_MOV(REG_PC, REG_PV);
                                s1 = (s4) (cd->mcodeptr - cd->mcodebase);
index 93432e094e5ee13cce25243c11f3f69c6696580e..c2fbbe3402b24789d2c8fef285f0af513191ebc5 100644 (file)
 #include "vm/jit/patcher-common.hpp"
 
 
-#define gen_resolveload(inst,offset) \
-       assert((offset) >= -0x0fff && (offset) <= 0x0fff); \
-       assert(!((inst) & 0x0fff)); \
-       if ((offset) <  0) { \
-               (inst) = ((inst) & 0xff7ff000) | ((-(offset)) & 0x0fff); \
-               /*(inst) &= ~(1 << 23);*/ \
-       } else { \
-               (inst) = ((inst) & 0xfffff000) | ((offset) & 0x0fff); \
-               /*(inst) |= (1 << 23);*/ \
-       }
-
-
 /* patcher_patch_code **********************************************************
 
    Just patches back the original machine code.
@@ -282,8 +270,8 @@ bool patcher_invokestatic_special(patchref_t *pr)
 
 bool patcher_invokevirtual(patchref_t *pr)
 {
-       uint32_t*          pc = (uint32_t*)           pr->mpc;
-       unresolved_method* um = (unresolved_method *) pr->ref;
+       unresolved_method* um    = (unresolved_method*) pr->ref;
+       int32_t*           datap = (int32_t*)           pr->datap;
 
        // Resolve the method.
        methodinfo* m = resolve_method_eager(um);
@@ -292,10 +280,8 @@ bool patcher_invokevirtual(patchref_t *pr)
                return false;
 
        // Patch vftbl index.
-       gen_resolveload(pc[1], (int32_t) (OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * m->vftblindex));
-
-       // Synchronize instruction cache.
-       md_icacheflush(pc + 1, 1 * 4);
+       int32_t disp = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * m->vftblindex;
+       *datap = disp;
 
        // Patch back the original code.
        patcher_patch_code(pr);
@@ -315,7 +301,6 @@ bool patcher_invokevirtual(patchref_t *pr)
    e1a0e00f    mov   lr, pc
    e1a0f00c    mov   pc, ip
 
-
 *******************************************************************************/
 
 bool patcher_invokeinterface(patchref_t *pr)