* src/vm/jit/sparc64/*: implemented patching (partly), adherent fixes.
authorajordan <none@none>
Sat, 11 Nov 2006 19:26:55 +0000 (19:26 +0000)
committerajordan <none@none>
Sat, 11 Nov 2006 19:26:55 +0000 (19:26 +0000)
src/vm/jit/sparc64/asmpart.S
src/vm/jit/sparc64/codegen.c
src/vm/jit/sparc64/emit.c
src/vm/jit/sparc64/md-abi.c
src/vm/jit/sparc64/md-abi.h
src/vm/jit/sparc64/md-asm.h
src/vm/jit/sparc64/md.c
src/vm/jit/sparc64/patcher.c

index 718f90de05879e2618a9698cd4af3bfa540c5968..f6f981809ed50304fe3eaed22276e599b3525a2c 100644 (file)
@@ -59,6 +59,7 @@
        .global asm_handle_exception
        .global asm_handle_nat_exception
 
+       .global asm_patcher_wrapper
 
        .global asm_abstractmethoderror
        
@@ -339,6 +340,66 @@ asm_abstractmethoderror:
 
        /* XXX: leave the register window open for handle_exception ??? */
 
+/* asm_patcher_wrapper *********************************************************
+
+   XXX
+
+   Stack layout, when called from patcher stub
+     40   return address into JIT code (patch position)
+     32   pointer to virtual java_objectheader
+     24   machine code (which is patched back later)
+     16   unresolved class/method/field reference
+      8   data segment displacement from load instructions
+      0   patcher function pointer to call
+   -128   WINSAVE REGS (current SP)
+
+*******************************************************************************/
+               
+
+asm_patcher_wrapper:
+       /* get pv and ra from current window */
+       mov     ra_callee,temp4
+       mov     pv_callee,temp5
+
+       /* create window and stack frame              */
+       save  %sp,-((FLT_ARG_CNT+FLT_TMP_CNT+ABICALL_OFF+4)*8),%sp
+
+       SAVE_FLOAT_ARGUMENT_REGISTERS(ABICALL_OFF)
+       SAVE_FLOAT_TEMPORARY_REGISTERS(ABICALL_OFF+FLT_ARG_CNT)
+
+       mov     itmp1,%l0               /* save itmp1                             */
+       mov     itmp2,%l1               /* save itmp2                             */
+
+       add     %fp,USESTACK,%o0      /* pass pseudo SP                           */
+       mov     temp5,%o1             /* pass PV                                  */
+       mov     temp4,%o2             /* pass RA (correct for leafs)              */
+       call    patcher_wrapper
+       nop
+
+       RESTORE_FLOAT_ARGUMENT_REGISTERS(ABICALL_OFF)
+       RESTORE_FLOAT_ARGUMENT_REGISTERS(ABICALL_OFF+FLT_ARG_CNT)
+
+       mov     %l0,itmp1               /* restore itmp1                          */
+       mov     %l1,itmp2               /* restore itmp2                          */
+
+       brnz    %o0,L_asm_patcher_wrapper_exception
+
+       /* load RA (patch position from patcher data on the stack */
+       ldx     [%fp+USESTACK+5*8],itmp3
+
+       /* remove window and stack frame (and stack space allocated in the stub code */
+       restore  %fp,6*8,%sp /* (source regs refer to old window, rd to new window)  */
+
+       jmpl     itmp3,zero              /* jump to newly patched code               */
+
+L_asm_patcher_wrapper_exception:
+       mov      itmp3,xptr_itmp2      /* get exception                            */
+       ldx      [%fp+USESTACK+5*8],xpc_itmp3 /* xpc is RA                         */
+       restore  %fp,6*8,%sp           /* remove stack frame                       */
+       ba       asm_handle_exception
+       nop
+
+
 asm_getclassvalues_atomic:
 _crit_restart:
 _crit_begin:
index 8553317cd885139524a7254b0806ca0208947c86..01b3fabab68c2370afad58b180e1271e58570b21 100644 (file)
@@ -2938,7 +2938,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
        /* prepare data structures for native function call */
 
-       M_MOV(REG_FP, REG_OUT0); /* top of the stack frame */
+       M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* top of the stack frame, absolute*/
        M_MOV(REG_PV_CALLEE, REG_OUT1);
        M_MOV(REG_FP, REG_OUT2); /* java sp */
        M_MOV(REG_RA_CALLEE, REG_OUT3);
index 5a95661e5dd10de8e06ba6b618f205b8ee2206fc..9ce6e5121ee36f160d1e31cfdd62f814c5388e67 100644 (file)
@@ -48,6 +48,9 @@
 #include "vm/jit/jit.h"
 #include "vm/jit/replace.h"
 
+/* how to leaf optimization in the emitted stubs?? */
+#define REG_PV REG_PV_CALLEE
+
 
 /* emit_load *******************************************************************
 
@@ -213,7 +216,128 @@ void emit_exception_stubs(jitdata *jd)
 
 void emit_patcher_stubs(jitdata *jd)
 {
+       codegendata *cd;
+       patchref    *pref;
+       u4           mcode[2];
+       u1          *savedmcodeptr;
+       u1          *tmpmcodeptr;
+       s4           targetdisp;
+       s4           disp;
+
+       /* get required compiler data */
+
+       cd = jd->cd;
+
+       /* generate code patching stub call code */
+
+       targetdisp = 0;
+
+       for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
+               /* check code segment size */
+
+               MCODECHECK(100);
+
+               /* Get machine code which is patched back in later. The
+                  call is 2 instruction words long. */
+
+               tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
+
+               /* We use 2 loads here as an unaligned 8-byte read on 64-bit
+                  SPARC causes a SIGSEGV */
+
+               mcode[0] = ((u4 *) tmpmcodeptr)[0];
+               mcode[1] = ((u4 *) tmpmcodeptr)[1];
+
+               /* Patch in the call to call the following code (done at
+                  compile time). */
+
+               savedmcodeptr = cd->mcodeptr;   /* save current mcodeptr          */
+               cd->mcodeptr  = tmpmcodeptr;    /* set mcodeptr to patch position */
+
+               disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1);
+/* XXX TODO imm?? */
+               if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
+                       *exceptionptr =
+                               new_internalerror("Jump offset is out of range: %d > +/-%d",
+                                                                 disp, 0x00007fff);
+                       return;
+               }
+
+               M_BR(disp);
+               M_NOP;
+
+       cd->mcodeptr = savedmcodeptr;   /* restore the current mcodeptr   */
+
+               /* extend stack frame for wrapper data */
+
+               M_ASUB_IMM(REG_SP, 6 * 8, REG_SP);
+
+               /* calculate return address and move it onto the stack */
+
+               M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
+               M_AST(REG_ITMP3, REG_SP, USESTACK + 5 * 8);
+
+               /* move pointer to java_objectheader onto stack */
+
+#if defined(ENABLE_THREADS)
+               /* create a virtual java_objectheader */
+
+               (void) dseg_addaddress(cd, NULL);                          /* flcword */
+               (void) dseg_addaddress(cd, lock_get_initial_lock_word());
+               disp = dseg_addaddress(cd, NULL);                          /* vftbl   */
+
+               M_LDA(REG_ITMP3, REG_PV, disp);
+               M_AST(REG_ITMP3, REG_SP, USESTACK + 4 * 8);
+#else
+               /* do nothing */
+#endif
+
+               /* move machine code onto stack */
+
+               disp = dseg_adds4(cd, mcode[0]);
+               M_ILD(REG_ITMP3, REG_PV, disp);
+               M_IST(REG_ITMP3, REG_SP, USESTACK + 3 * 8);
+
+               disp = dseg_adds4(cd, mcode[1]);
+               M_ILD(REG_ITMP3, REG_PV, disp);
+               M_IST(REG_ITMP3, REG_SP, USESTACK + 3 * 8 + 4);
+
+               /* move class/method/field reference onto stack */
+
+               disp = dseg_addaddress(cd, pref->ref);
+               M_ALD(REG_ITMP3, REG_PV, disp);
+               M_AST(REG_ITMP3, REG_SP, USESTACK + 2 * 8);
+
+       /* move data segment displacement onto stack */
+
+               disp = dseg_adds4(cd, pref->disp);
+               M_ILD(REG_ITMP3, REG_PV, disp);
+               M_IST(REG_ITMP3, REG_SP, USESTACK + 1 * 8);
+
+               /* move patcher function pointer onto stack */
+
+               disp = dseg_addaddress(cd, pref->patcher);
+               M_ALD(REG_ITMP3, REG_PV, disp);
+               M_AST(REG_ITMP3, REG_SP, USESTACK + 0 * 8);
+
+               if (targetdisp == 0) {
+                       targetdisp = ((u4 *) cd->mcodeptr) - ((u4 *) cd->mcodebase);
+
+                       disp = dseg_addaddress(cd, asm_patcher_wrapper);
+                       M_ALD(REG_ITMP3, REG_PV, disp);
+                       M_JMP(REG_ZERO, REG_ITMP3, REG_ZERO);
+                       M_NOP;
 }
+               else {
+                       disp = (((u4 *) cd->mcodebase) + targetdisp) -
+                               (((u4 *) cd->mcodeptr) + 1);
+
+                       M_BR(disp);
+                       M_NOP;
+               }
+       }
+}
+
 
 /* emit_replacement_stubs ******************************************************
 
index 619abe4dc6bcc1060fff98009bef22f9c93be9f7..a6c5e8a6bd3ba7c4674df8b09c335a62e0c6ed89 100644 (file)
@@ -266,55 +266,13 @@ void md_native_reg_setup(jitdata *jd)
 
 /* md_return_alloc *************************************************************
 
-   Precolor the Java Stackelement containing the Return Value. Since
-   alpha has a dedicated return register (not an reused arg or
-   reserved reg), this is striaghtforward possible, as long, as this
-   stackelement does not have to survive a method invokation
-   (SAVEDVAR)
-
-   --- in
-   m:                       Methodinfo of current method
-   return_type:             Return Type of the Method (TYPE_INT.. TYPE_ADR)
-                                                       TYPE_VOID is not allowed!
-   stackslot:               Java Stackslot to contain the Return Value
-   
-   --- out
-   if precoloring was possible:
-   stackslot->varkind       =ARGVAR
-                       ->varnum        =-1
-                       ->flags         =0
-                       ->regoff        =[REG_RESULT, REG_FRESULT]
+  XXX
 
 *******************************************************************************/
 
 void md_return_alloc(jitdata *jd, stackptr stackslot)
 {
-       methodinfo *m;
-       methoddesc *md;
-       
-       assert(0);
-
-       /* get required compiler data */
-
-       m = jd->m;
-
-       md = m->parseddesc;
-
-       /* Only precolor the stackslot, if it is not a SAVEDVAR <-> has
-          not to survive method invokations. */
-
-
-       if (!(stackslot->flags & SAVEDVAR)) {
-               stackslot->varkind = ARGVAR;
-               stackslot->varnum = -1;
-               stackslot->flags = 0;
-
-               if (IS_INT_LNG_TYPE(md->returntype.type)) {
-                       stackslot->regoff = REG_RESULT_CALLEE;
-               } else { /* float/double */
-                       stackslot->regoff = REG_FRESULT;
-               }
-       }
+       /* XXX */
 }
 
 
index 5564b21aac1e6ccc7e9ee34dfdf574912695a0d4..e40efcf1ae9c5b4c1998e4d39378f0ed521c36f2 100644 (file)
 #define ABI_PARAMARRAY_SLOTS    6
 
 #define WINSAVE_CNT     16    /* number of regs that SPARC saves onto stack    */
-#define ABICALL_OFF     22    /* 8-byte slots for save regs and arg slots      */
+#define ABICALL_PARAMS   6    /* param slots the ABI always requires           */
+#define ABICALL_OFF     22    /* 8-byte slots for save regs and param slots    */
 #define BIAS          2047
 #define USESTACK      (WINSAVE_CNT * 8 + BIAS)
 #define USESTACK_PARAMS ((WINSAVE_CNT + ABI_PARAMARRAY_SLOTS) * 8 + BIAS)
index 88a371397ac7a1d9cce784da3204b863b5a006e0..c7db522b5fa7f8f32b9608249213b65457feb2cf 100644 (file)
 #define itmp2  %g2
 #define itmp3  %g3
 
+/* PLT unsafe temp regs */
+#define temp4 %g4
+#define temp5 %g5
+
 #define mptr_itmp2 itmp2
 
 #define xptr_itmp2 itmp2
index 313e3e5c6a1a54115a017ad5d5eb78b869ccc641..f07db41df7bdee669281998cec46beeeb12ecc53 100644 (file)
@@ -49,6 +49,48 @@ void md_init(void)
 }
 
 
+/* md_codegen_patch_branch *****************************************************
+
+   Back-patches a branch instruction.
+
+*******************************************************************************/
+
+void md_codegen_patch_branch(codegendata *cd, s4 branchmpc, s4 targetmpc)
+{
+       s4 *mcodeptr;
+       s4  mcode;
+       s4  disp;                           /* branch displacement                */
+
+       assert(0);
+
+       /* calculate the patch position */
+
+       mcodeptr = (s4 *) (cd->mcodebase + branchmpc);
+
+       /* get the instruction before the exception point */
+
+       mcode = mcodeptr[-1];
+
+       /* check for BPcc instruction */
+       if (((mcode >> 16) & 0xc1c0) != 0x0040)
+               assert(0);
+
+       /* Calculate the branch displacement.  For branches we need a
+          displacement relative and shifted to the branch PC. */
+
+       disp = (targetmpc - branchmpc) >> 2;
+
+       /* check branch displacement */
+
+       if ((disp < (s4) 0xfffc0000) || (disp > (s4) 0x003ffff))
+               vm_abort("branch displacement is out of range: %d > +/-%d", disp, 0x003ffff);
+
+       /* patch the branch instruction before the mcodeptr */
+
+       mcodeptr[-1] |= (disp & 0x003ffff);
+}
+
+
 /* md_stacktrace_get_returnaddress *********************************************
 
    Returns the return address of the current stackframe, specified by
index 39091476ea18a17615ed3decb0c660ae6ea2ddbf..a8a03d1b4978ca36c97b4455723f26cb4d71cb14 100644 (file)
@@ -52,6 +52,8 @@
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher.h"
 
+#include "vm/jit/sparc64/md-abi.h"
+
 
 /* patcher_wrapper *************************************************************
 
@@ -68,12 +70,12 @@ java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
 {
        stackframeinfo     sfi;
        u1                *xpc;
+       u1                *javasp;
        java_objectheader *o;
        functionptr        f;
        bool               result;
        java_objectheader *e;
        
-       assert(0);
 
        /* define the patcher function */
 
@@ -98,10 +100,14 @@ java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
        /* enter a monitor on the patching position */
 
        PATCHER_MONITORENTER;
+       
+       /* calculate sp of the current java function considering the WINSAVE regs */
+       
+       javasp = sp - 16 * 8 - BIAS;
 
        /* create the stackframeinfo */
 
-       stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 6 * 8, ra, xpc);
+       stacktrace_create_extern_stackframeinfo(&sfi, pv, javasp, ra, xpc);
 
        /* call the proper patcher function */
 
@@ -1052,10 +1058,7 @@ bool patcher_resolve_native(u1 *sp)
        disp     =                *((s4 *)     (sp + 1 * 8));
        pv       = (u1 *)         *((ptrint *) (sp + 0 * 8));
 
-       /* calculate and set the new return address */
-
-       ra = ra - 2 * 4;
-       *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
+       /* return address on SPARC is address of jump, therefore correct */
 
        /* resolve native function */