* src/vm/jit/x86_64/codegen.c (codegen): Load address for INVOKESTATIC
authortwisti <none@none>
Mon, 31 Jul 2006 20:42:46 +0000 (20:42 +0000)
committertwisti <none@none>
Mon, 31 Jul 2006 20:42:46 +0000 (20:42 +0000)
from data segment and pass the displacement to the patcher.

* src/vm/jit/x86_64/patcher.c (patcher_get_putstatic): Use
displacement from patcher, not from the instruction.
(patcher_builtin_multianewarray): Don't patch BUILTIN_multianewarray
address, it's not required.
(patcher_invokestatic_special): Use displacement passed and patch the
data segment.

* src/vm/jit/x86_64/md.c (md_stacktrace_get_returnaddress): Changed to
new INVOKESTATIC calling sequence.

src/vm/jit/x86_64/codegen.c
src/vm/jit/x86_64/md.c
src/vm/jit/x86_64/patcher.c

index a0bba619fa15c731ae1f69fca6e8ba2f2a7d8f15..26b3ad8bb7c1b2adfc06134fc3340b6baf8f5212 100644 (file)
@@ -30,7 +30,7 @@
    Changes: Christian Ullrich
             Edwin Steiner
 
-   $Id: codegen.c 5173 2006-07-25 15:57:11Z twisti $
+   $Id: codegen.c 5201 2006-07-31 20:42:46Z twisti $
 
 */
 
@@ -564,7 +564,7 @@ bool codegen(jitdata *jd)
 
                        d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
                        disp = dseg_addfloat(cd, iptr->val.f);
-                       emit_movdl_membase_reg(cd, RIP, -(((s8) cd->mcodeptr + ((d > 7) ? 9 : 8)) - (s8) cd->mcodebase) + disp, d);
+                       emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
                        emit_store(jd, iptr, iptr->dst, d);
                        break;
                
@@ -573,7 +573,7 @@ bool codegen(jitdata *jd)
 
                        d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
                        disp = dseg_adddouble(cd, iptr->val.d);
-                       emit_movd_membase_reg(cd, RIP, -(((s8) cd->mcodeptr + 9) - (s8) cd->mcodebase) + disp, d);
+                       emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
                        emit_store(jd, iptr, iptr->dst, d);
                        break;
 
@@ -1157,7 +1157,7 @@ bool codegen(jitdata *jd)
 
                        /* check as described in jvm spec */
                        disp = dseg_adds8(cd, 0x8000000000000000LL);
-                       M_LCMP_MEMBASE(RIP, -(((ptrint) cd->mcodeptr + 7) - (ptrint) cd->mcodebase) + disp, RAX);
+                       M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
                        M_BNE(4 + 6);
                        M_LCMP_IMM(-1, REG_ITMP3);                              /* 4 bytes */
                        M_BEQ(3 + 2 + 3);                                      /* 6 bytes */
@@ -1202,7 +1202,7 @@ bool codegen(jitdata *jd)
 
                        /* check as described in jvm spec */
                        disp = dseg_adds8(cd, 0x8000000000000000LL);
-                       M_LCMP_MEMBASE(RIP, -(((ptrint) cd->mcodeptr + 7) - (ptrint) cd->mcodebase) + disp, REG_ITMP1);
+                       M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
                        M_BNE(3 + 4 + 6);
 
 #if 0
@@ -1541,7 +1541,7 @@ bool codegen(jitdata *jd)
                        d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
                        disp = dseg_adds4(cd, 0x80000000);
                        M_FLTMOVE(s1, d);
-                       emit_movss_membase_reg(cd, RIP, -(((s8) cd->mcodeptr + 9) - (s8) cd->mcodebase) + disp, REG_FTMP2);
+                       emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
                        emit_xorps_reg_reg(cd, REG_FTMP2, d);
                        emit_store(jd, iptr, iptr->dst, d);
                        break;
@@ -1552,7 +1552,7 @@ bool codegen(jitdata *jd)
                        d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
                        disp = dseg_adds8(cd, 0x8000000000000000);
                        M_FLTMOVE(s1, d);
-                       emit_movd_membase_reg(cd, RIP, -(((s8) cd->mcodeptr + 9) - (s8) cd->mcodebase) + disp, REG_FTMP2);
+                       emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
                        emit_xorpd_reg_reg(cd, REG_FTMP2, d);
                        emit_store(jd, iptr, iptr->dst, d);
                        break;
@@ -2151,6 +2151,12 @@ bool codegen(jitdata *jd)
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                disp = dseg_addaddress(cd, NULL);
+                               disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
+
+                               /* must be calculated before codegen_addpatchref */
+
+                               if (opt_showdisassemble)
+                                       disp -= PATCHER_CALL_SIZE;
 
 /*                             PROFILE_CYCLE_STOP; */
 
@@ -2162,12 +2168,10 @@ bool codegen(jitdata *jd)
                                }
 
 /*                             PROFILE_CYCLE_START; */
-
-                       else {
+                       }
+                       else {
                                fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
 
-                               disp = dseg_addaddress(cd, &(fi->value));
-
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
                                        PROFILE_CYCLE_STOP;
 
@@ -2179,13 +2183,15 @@ bool codegen(jitdata *jd)
 
                                        PROFILE_CYCLE_START;
                                }
+
+                               disp = dseg_addaddress(cd, &(fi->value));
+                               disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
                        }
 
                        /* This approach is much faster than moving the field
                           address inline into a register. */
 
-                       M_ALD(REG_ITMP1, RIP, -(((ptrint) cd->mcodeptr + 7) -
-                                                                       (ptrint) cd->mcodebase) + disp);
+                       M_ALD(REG_ITMP1, RIP, disp);
 
                        switch (iptr->op1) {
                        case TYPE_INT:
@@ -2214,6 +2220,12 @@ bool codegen(jitdata *jd)
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                disp = dseg_addaddress(cd, NULL);
+                               disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
+
+                               /* must be calculated before codegen_addpatchref */
+
+                               if (opt_showdisassemble)
+                                       disp -= PATCHER_CALL_SIZE;
 
 /*                             PROFILE_CYCLE_STOP; */
 
@@ -2225,12 +2237,10 @@ bool codegen(jitdata *jd)
                                }
 
 /*                             PROFILE_CYCLE_START; */
-
-                       else {
+                       }
+                       else {
                                fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
 
-                               disp = dseg_addaddress(cd, &(fi->value));
-
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
                                        PROFILE_CYCLE_STOP;
 
@@ -2238,17 +2248,20 @@ bool codegen(jitdata *jd)
 
                                        if (opt_showdisassemble) {
                                                M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                                               disp -= PATCHER_CALL_SIZE;
                                        }
 
                                        PROFILE_CYCLE_START;
                                }
+
+                               disp = dseg_addaddress(cd, &(fi->value));
+                               disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
                        }
 
                        /* This approach is much faster than moving the field
                           address inline into a register. */
 
-                       M_ALD(REG_ITMP1, RIP, -(((ptrint) cd->mcodeptr + 7) -
-                                                                       (ptrint) cd->mcodebase) + disp);
+                       M_ALD(REG_ITMP1, RIP, disp);
 
                        switch (iptr->op1) {
                        case TYPE_INT:
@@ -2278,23 +2291,29 @@ bool codegen(jitdata *jd)
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
                                disp = dseg_addaddress(cd, NULL);
+                               disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
+
+                               /* must be calculated before codegen_addpatchref */
+
+                               if (opt_showdisassemble)
+                                       disp -= PATCHER_CALL_SIZE;
+
 
 /*                             PROFILE_CYCLE_STOP; */
 
                                codegen_addpatchref(cd, PATCHER_get_putstatic,
-                                                                       INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), disp);
+                                                                       INSTRUCTION_UNRESOLVED_FIELD(iptr + 1),
+                                                                       disp);
 
                                if (opt_showdisassemble) {
                                        M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                }
 
 /*                             PROFILE_CYCLE_START; */
-
-                       else {
+                       }
+                       else {
                                fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
 
-                               disp = dseg_addaddress(cd, &(fi->value));
-
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
                                        PROFILE_CYCLE_STOP;
 
@@ -2306,13 +2325,15 @@ bool codegen(jitdata *jd)
 
                                        PROFILE_CYCLE_START;
                                }
+
+                               disp = dseg_addaddress(cd, &(fi->value));
+                               disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
                        }
 
                        /* This approach is much faster than moving the field
                           address inline into a register. */
 
-                       M_ALD(REG_ITMP1, RIP, -(((ptrint) cd->mcodeptr + 7) -
-                                                                       (ptrint) cd->mcodebase) + disp);
+                       M_ALD(REG_ITMP1, RIP, disp);
 
                        switch (iptr->op1) {
                        case TYPE_INT:
@@ -2351,8 +2372,8 @@ bool codegen(jitdata *jd)
 /*                             PROFILE_CYCLE_START; */
 
                                disp = 0;
-
-                       else
+                       }
+                       else
                                disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
 
                        switch (iptr->op1) {
@@ -2401,8 +2422,8 @@ bool codegen(jitdata *jd)
 /*                             PROFILE_CYCLE_START; */
 
                                disp = 0;
-
-                       else
+                       }
+                       else
                                disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
 
                        switch (iptr->op1) {
@@ -2443,8 +2464,8 @@ bool codegen(jitdata *jd)
 /*                             PROFILE_CYCLE_START; */
 
                                disp = 0;
-
-                       else
+                       }
+                       else
                                disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
 
                        switch (iptr->op1) {
@@ -3079,20 +3100,22 @@ gen_method:
                                M_BEQ(0);
                                codegen_add_nullpointerexception_ref(cd);
 
-                               /* first argument contains pointer */
-/*                             gen_nullptr_check(rd->argintregs[0]); */
-
-                               /* access memory for hardware nullptr */
-/*                             emit_mov_membase_reg(cd, rd->argintregs[0], 0, REG_ITMP2); */
-
                                /* fall through */
 
                        case ICMD_INVOKESTATIC:
                                if (lm == NULL) {
                                        unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
 
+                                       disp = dseg_addaddress(cd, NULL);
+                                       disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
+
+                                       /* must be calculated before codegen_addpatchref */
+
+                                       if (opt_showdisassemble)
+                                               disp -= PATCHER_CALL_SIZE;
+
                                        codegen_addpatchref(cd, PATCHER_invokestatic_special,
-                                                                               um, 0);
+                                                                               um, disp);
 
                                        if (opt_showdisassemble) {
                                                M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
@@ -3100,13 +3123,17 @@ gen_method:
 
                                        a = 0;
                                        d = um->methodref->parseddesc.md->returntype.type;
+                               }
+                               else {
+                                       disp = dseg_addaddress(cd, lm->stubroutine);
+                                       disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
 
-                               } else {
                                        a = (ptrint) lm->stubroutine;
                                        d = lm->parseddesc->returntype.type;
                                }
 
-                               M_MOV_IMM(a, REG_ITMP2);
+/*                             M_MOV_IMM(a, REG_ITMP2); */
+                               M_ALD(REG_ITMP2, RIP, disp);
                                M_CALL(REG_ITMP2);
                                break;
 
@@ -3757,7 +3784,7 @@ gen_method:
                        } else {
                                savedmcodeptr = cd->mcodeptr;
 
-                               emit_lea_membase_reg(cd, RIP, -(((ptrint) cd->mcodeptr + 7) - (ptrint) cd->mcodebase), rd->argintregs[0]);
+                               emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), rd->argintregs[0]);
                                M_MOV(REG_SP, rd->argintregs[1]);
                                M_ALD(rd->argintregs[2], REG_SP, stackframesize * 8);
 
@@ -3806,7 +3833,7 @@ gen_method:
                        (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
                        a = dseg_addaddress(cd, NULL);                            /* vftbl      */
 
-                       emit_lea_membase_reg(cd, RIP, -(((ptrint) cd->mcodeptr + 7) - (ptrint) cd->mcodebase) + a, REG_ITMP3);
+                       emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + a, REG_ITMP3);
                        M_PUSH(REG_ITMP3);
 #else
                        M_PUSH_IMM(0);
@@ -4089,7 +4116,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
        /* create dynamic stack info */
 
        M_ALEA(REG_SP, stackframesize * 8, rd->argintregs[0]);
-       emit_lea_membase_reg(cd, RIP, -(((ptrint) cd->mcodeptr + 7) - (ptrint) cd->mcodebase), rd->argintregs[1]);
+       emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), rd->argintregs[1]);
        M_ALEA(REG_SP, stackframesize * 8 + SIZEOF_VOID_P, rd->argintregs[2]);
        M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8);
        M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
@@ -4274,7 +4301,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                        (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
                        disp = dseg_addaddress(cd, NULL);                         /* vftbl      */
 
-                       emit_lea_membase_reg(cd, RIP, -(((ptrint) cd->mcodeptr + 7) - (ptrint) cd->mcodebase) + disp, REG_ITMP3);
+                       emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP3);
                        M_PUSH(REG_ITMP3);
 #else
                        M_PUSH_IMM(0);
index 3573096ca0e4f600c3e4f11b4618aa5e85e692b6..0646894c6a73c0a5cb6db2c758dc41df5841f8a8 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Edwin Steiner
 
-   $Id: md.c 5172 2006-07-25 15:33:58Z twisti $
+   $Id: md.c 5201 2006-07-31 20:42:46Z twisti $
 
 */
 
@@ -79,11 +79,11 @@ void md_init(void)
 
 void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 {
-       ucontext_t  *_uc;
-       mcontext_t  *_mc;
-       u1          *sp;
-       u1          *ra;
-       u1          *xpc;
+       ucontext_t *_uc;
+       mcontext_t *_mc;
+       u1         *sp;
+       u1         *ra;
+       u1         *xpc;
 
        _uc = (ucontext_t *) _p;
        _mc = &_uc->uc_mcontext;
@@ -95,6 +95,12 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
        xpc = (u1 *) _mc->gregs[REG_RIP];
        ra  = xpc;                          /* return address is equal to xpc     */
 
+#if 0
+       /* check for StackOverflowException */
+
+       threads_check_stackoverflow(sp);
+#endif
+
        _mc->gregs[REG_RAX] =
                (ptrint) stacktrace_hardware_nullpointerexception(NULL, sp, ra, xpc);
 
@@ -208,7 +214,7 @@ u1 *md_stacktrace_get_returnaddress(u1 *sp, u4 framesize)
 
    INVOKESTATIC/SPECIAL:
 
-   49 ba 98 3a ed ab aa 2a 00 00    mov    $0x2aaaabed3a98,%r10
+   4d 8b 15 e2 fe ff ff             mov    -286(%rip),%r10
    49 ff d2                         rex64Z callq  *%r10
 
    INVOKEVIRTUAL:
@@ -242,14 +248,19 @@ u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
 
        /* check for the different calls */
 
-       /* INVOKESTATIC/SPECIAL */
-
        if (mcode == 0xd2) {
-               /* patch address is 8-bytes before the call instruction */
+               /* INVOKESTATIC/SPECIAL */
 
-               pa = ra - 8;
+               /* Get the offset from the instruction (the offset address is
+                  4-bytes before the call instruction). */
+
+               offset = *((s4 *) (ra - 4));
 
-       } else if (mcode == 0xd3) {
+               /* add the offset to the return address (IP-relative addressing) */
+
+               pa = ra + offset;
+       }
+       else if (mcode == 0xd3) {
                /* INVOKEVIRTUAL/INTERFACE */
 
                /* Get the offset from the instruction (the offset address is
@@ -260,8 +271,8 @@ u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
                /* add the offset to the method pointer */
 
                pa = mptr + offset;
-
-       else {
+       }
+       else {
                /* catch any problems */
 
                assert(0);
index ce9df0711b5a579756c6115699e9797962ace2e0..1d380dac45c68d53f353bdfa20edc40f65f33e51 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: patcher.c 5142 2006-07-17 09:47:02Z twisti $
+   $Id: patcher.c 5201 2006-07-31 20:42:46Z twisti $
 
 */
 
@@ -144,7 +144,6 @@ bool patcher_get_putstatic(u1 *sp)
        unresolved_field *uf;
        s4                disp;
        fieldinfo        *fi;
-       s4                offset;
 
        /* get stuff from the stack */
 
@@ -173,13 +172,9 @@ bool patcher_get_putstatic(u1 *sp)
        if (opt_showdisassemble)
                ra = ra + 5;
 
-       /* get RIP offset from machine instruction */
+       /* patch the field value's address */
 
-       offset = *((u4 *) (ra + 3));
-
-       /* patch the field value's address (+ 7: is the size of the RIP move) */
-
-       *((ptrint *) (ra + 7 + offset)) = (ptrint) &(fi->value);
+       *((ptrint *) (ra + 7 + disp)) = (ptrint) &(fi->value);
 
        return true;
 }
@@ -402,10 +397,6 @@ bool patcher_builtin_multianewarray(u1 *sp)
 
        *((ptrint *) (ra + 10 + 2)) = (ptrint) c;
 
-       /* patch new function address */
-
-       *((ptrint *) (ra + 10 + 10 + 3 + 2)) = (ptrint) BUILTIN_multianewarray;
-
        return true;
 }
 
@@ -471,6 +462,7 @@ bool patcher_invokestatic_special(u1 *sp)
        u1                *ra;
        u8                 mcode;
        unresolved_method *um;
+       s4                 disp;
        methodinfo        *m;
 
        /* get stuff from the stack */
@@ -478,6 +470,7 @@ bool patcher_invokestatic_special(u1 *sp)
        ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
        mcode =                       *((u8 *)     (sp + 3 * 8));
        um    = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
+       disp  =                       *((s4 *)     (sp + 1 * 8));
 
        /* get the fieldinfo */
 
@@ -495,7 +488,8 @@ bool patcher_invokestatic_special(u1 *sp)
 
        /* patch stubroutine */
 
-       *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine;
+/*     *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine; */
+       *((ptrint *) (ra + 7 + disp)) = (ptrint) m->stubroutine;
 
        return true;
 }