* src/vm/jit/jit.c (jit_asm_compile): New method.
authortwisti <none@none>
Fri, 21 Apr 2006 10:54:24 +0000 (10:54 +0000)
committertwisti <none@none>
Fri, 21 Apr 2006 10:54:24 +0000 (10:54 +0000)
* src/vm/jit/jit.h (jit_asm_compile): Added.
(md_get_method_patch_address): Likewise.

* src/vm/jit/x86_64/asmpart.S (asm_vm_call_method): Store
asm_call_jit_compiler on stack as for the other architectures.
(asm_call_jit_compiler): Use new jit_asm_compile.

* src/vm/jit/x86_64/codegen.c (codegen): Use REG_ITMP3 for calling
methods. This is required for asm_vm_call_method to work.

* src/vm/jit/x86_64/md.c (md_get_method_patch_address): New method.
(md_icacheflush): Added.
(md_dcacheflush): Added.
* src/vm/jit/x86_64/md-asm.h (mptr): Defined.

src/vm/jit/jit.c
src/vm/jit/jit.h
src/vm/jit/x86_64/asmpart.S
src/vm/jit/x86_64/codegen.c
src/vm/jit/x86_64/md-asm.h
src/vm/jit/x86_64/md.c

index 40688c373f89b0dc5397d82f8f3d96886d2f73d2..2ffb102694173f4a172378b3391ec287346c79a3 100644 (file)
@@ -31,7 +31,7 @@
             Christian Thalinger
             Christian Ullrich
 
-   $Id: jit.c 4768 2006-04-13 16:58:05Z edwin $
+   $Id: jit.c 4805 2006-04-21 10:54:24Z twisti $
 
 */
 
@@ -1722,6 +1722,57 @@ static u1 *jit_compile_intern(jitdata *jd)
 } 
 
 
+/* jit_asm_compile *************************************************************
+
+   This method is called from asm_vm_call_method and does things like:
+   create stackframe info for exceptions, compile the method, patch
+   the entrypoint of the method into the calculated address in the JIT
+   code, and flushes the instruction cache.
+
+*******************************************************************************/
+
+u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
+{
+       stackframeinfo  sfi;
+       u1             *entrypoint;
+       u1             *pa;
+       ptrint         *p;
+
+       /* create the stackframeinfo (XPC is equal to RA) */
+
+       stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
+
+       /* actually compile the method */
+
+       entrypoint = jit_compile(m);
+
+       /* remove the stackframeinfo */
+
+       stacktrace_remove_stackframeinfo(&sfi);
+
+       /* there was a problem during compilation */
+
+       if (entrypoint == NULL)
+               return NULL;
+
+       /* get the method patch address */
+
+       pa = md_get_method_patch_address(ra, &sfi, mptr);
+
+       /* patch the method entry point */
+
+       p = (ptrint *) pa;
+
+       *p = (ptrint) entrypoint;
+
+       /* flush the instruction cache */
+
+       md_icacheflush(pa, SIZEOF_VOID_P);
+
+       return entrypoint;
+}
+
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
index ee6e5200b1db7247b44d9ac9cd79fadce1625b3b..f34d9e6f5e35757a922e2ec459480eab2ca2f431 100644 (file)
@@ -30,7 +30,7 @@
    Changes: Christian Thalinger
                        Edwin Steiner
 
-   $Id: jit.h 4790 2006-04-18 20:36:40Z twisti $
+   $Id: jit.h 4805 2006-04-21 10:54:24Z twisti $
 
 */
 
@@ -60,6 +60,7 @@ typedef struct insinfo_inline insinfo_inline;
 #include "vm/statistics.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/reg.h"
+#include "vm/jit/stacktrace.h"
 
 #if defined(ENABLE_INLINING)
 # include "vm/jit/inline/inline.h"
@@ -1000,10 +1001,15 @@ void jit_close(void);
 /* compile a method with jit compiler */
 u1 *jit_compile(methodinfo *m);
 
+/* patch the method entrypoint */
+u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra);
+
 /* machine dependent functions */
 #if defined(ENABLE_JIT)
 void md_init(void);
 
+u1  *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr);
+
 void md_cacheflush(u1 *addr, s4 nbytes);
 void md_icacheflush(u1 *addr, s4 nbytes);
 void md_dcacheflush(u1 *addr, s4 nbytes);
index a502aaaa822b1ddb299e0c42ff6be403b90ededa..c246b932af361255002f2388e70fcfd726f3957e 100644 (file)
@@ -30,7 +30,7 @@
 
    Changes: Edwin Steiner
 
-   $Id: asmpart.S 4749 2006-04-11 10:20:18Z twisti $
+   $Id: asmpart.S 4805 2006-04-21 10:54:24Z twisti $
 
 */
 
@@ -202,7 +202,15 @@ L_stack_copy:
 
 L_copy_done:
                                            /* itmp1 still contains method pointer*/
-       lea     L_asm_call_jit_compiler(%rip),itmp3
+       lea     L_asm_call_jit_compiler(%rip),mptr
+       mov     sp,itmp3                    /* calculate the old stack pointer    */
+       add     bp,itmp3
+       mov     mptr,6*8(itmp3)
+       lea     (6*8-256)(itmp3),mptr       /* We subtract 256 to force the next  */
+                                           /* move instruction to have a 32-bit  */
+                                           /* offset.                            */
+
+       mov     (0*8+256)(mptr),itmp3       /* method call as in Java             */
        call    *itmp3                      /* call JIT compiler                  */
 
        add     bp,sp                       /* remove argument stack frame if any */
@@ -316,72 +324,24 @@ handle_fa7:
 
 asm_call_jit_compiler:
 L_asm_call_jit_compiler:                /* required for PIC code              */
-                                           /* keep stack 16-byte aligned         */
-       sub     $((3+ARG_CNT)*8+sizestackframeinfo),sp
+       sub     $(ARG_CNT+1)*8,sp           /* +1: keep stack 16-byte aligned     */
 
-       mov     t0,0*8(sp)                  /* save register                      */
-
-       mov     (3+ARG_CNT)*8+sizestackframeinfo(sp),itmp3 /* get return address  */
-       mov     -1(itmp3),%bl               /* get function code                  */
-       cmp     $0xd2,%bl                   /* called with `call *REG_ITMP2'?     */
-       jne     L_not_static_special
-
-       sub     $11,itmp3                   /* calculate address of immediate     */
-       jmp     L_call_jit_compile
-               
-L_not_static_special:
-       cmp     $0xd0,%bl                   /* called with `call *REG_ITMP1'      */
-       jne     L_not_virtual_interface
-               
-       sub     $7,itmp3                    /* calculate address of offset        */
-       mov     (itmp3),itmp3l              /* get offset (32-bit)                */
-       add     itmp2,itmp3                 /* add base address to get method addr*/
-       jmp     L_call_jit_compile
-
-L_not_virtual_interface:                /* a call from asm_calljavamethod     */
-       xor     itmp3,itmp3
-               
-L_call_jit_compile:
-       mov     0*8(sp),t0                  /* restore register                   */
-       mov     itmp3,0*8(sp)               /* save address for method pointer    */
-       mov     itmp1,1*8(sp)               /* save method pointer                */
-
-       SAVE_ARGUMENT_REGISTERS(3)
+       SAVE_ARGUMENT_REGISTERS(0)
 
-       mov     sp,a0                       /* create stackframe info             */
-       add     $((3+ARG_CNT)*8),a0         /* pass sfi                           */
-       xor     a1,a1                       /* if pv is NULL, use findmethod      */
+       mov     itmp1,a0                    /* pass methodinfo pointer            */
+       mov     mptr,a1                     /* pass method pointer                */
        mov     sp,a2                       /* pass java sp                       */
-       add     $((1+3+ARG_CNT)*8+sizestackframeinfo),a2
-                                           /* pass ra to java function           */
-       mov     ((3+ARG_CNT)*8+sizestackframeinfo)(sp),a3
-       mov     a3,a4                       /* xpc is equal to ra                 */
-       call    stacktrace_create_extern_stackframeinfo@PLT
-
-       mov     1*8(sp),a0                  /* pass method pointer                */
-       call    jit_compile@PLT
-       mov     v0,1*8(sp)                  /* save return value                  */
-
-       mov     sp,a0                       /* remove stackframe info             */
-       add     $((3+ARG_CNT)*8),a0         /* pass sfi                           */
-       call    stacktrace_remove_stackframeinfo@PLT
+       add     $(1+ARG_CNT+1)*8,a2
+       mov     (ARG_CNT+1)*8(sp),a3        /* pass ra to java function           */
+       call    jit_asm_compile@PLT
 
-       mov     0*8(sp),itmp3               /* restore address for method pointer */
-       mov     1*8(sp),v0                  /* restore return value               */
-
-       RESTORE_ARGUMENT_REGISTERS(3)
+       RESTORE_ARGUMENT_REGISTERS(0)
 
-       add     $((3+ARG_CNT)*8+sizestackframeinfo),sp /* remove stack frame      */
+       add     $(ARG_CNT+1)*8,sp           /* remove stack frame                 */
 
        test    v0,v0                       /* check for exception                */
        je      L_asm_call_jit_compiler_exception
 
-       test    itmp3,itmp3                 /* is address == 0 (asm_calljavamethod*/
-       je      L_call_method
-
-       mov     v0,(itmp3)                  /* and now save the new pointer       */
-
-L_call_method:
        jmp     *v0                         /* ...and now call the new method     */
 
 L_asm_call_jit_compiler_exception:
index abe863d8c706ede94148ce816ee9a168037d2c7b..0f39dc038139e61b6939e71601cb375c6e753b8a 100644 (file)
@@ -30,7 +30,7 @@
    Changes: Christian Ullrich
             Edwin Steiner
 
-   $Id: codegen.c 4791 2006-04-18 21:16:36Z twisti $
+   $Id: codegen.c 4805 2006-04-21 10:54:24Z twisti $
 
 */
 
@@ -3241,11 +3241,10 @@ gen_method:
                                        d = lm->parseddesc->returntype.type;
                                }
 
-                               x86_64_mov_membase_reg(cd, rd->argintregs[0],
-                                                                          OFFSET(java_objectheader, vftbl),
-                                                                          REG_ITMP2);
-                               x86_64_mov_membase32_reg(cd, REG_ITMP2, s1, REG_ITMP1);
-                               M_CALL(REG_ITMP1);
+                               M_ALD(REG_METHODPTR, rd->argintregs[0],
+                                         OFFSET(java_objectheader, vftbl));
+                               M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
+                               M_CALL(REG_ITMP3);
                                break;
 
                        case ICMD_INVOKEINTERFACE:
@@ -3274,11 +3273,11 @@ gen_method:
                                        d = lm->parseddesc->returntype.type;
                                }
 
-                               M_ALD(REG_ITMP2, rd->argintregs[0],
+                               M_ALD(REG_METHODPTR, rd->argintregs[0],
                                          OFFSET(java_objectheader, vftbl));
-                               x86_64_mov_membase32_reg(cd, REG_ITMP2, s1, REG_ITMP2);
-                               x86_64_mov_membase32_reg(cd, REG_ITMP2, s2, REG_ITMP1);
-                               M_CALL(REG_ITMP1);
+                               M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
+                               M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
+                               M_CALL(REG_ITMP3);
                                break;
                        }
 
index def2855948fe75ef915aed4cacca0762119a5abc..e624dcac146def244b4fde211a398c58b5a6ca44 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: md-asm.h 4357 2006-01-22 23:33:38Z twisti $
+   $Id: md-asm.h 4805 2006-04-21 10:54:24Z twisti $
 
 */
 
@@ -75,6 +75,7 @@
 
 #define xptr     itmp1
 #define xpc      itmp2
+#define mptr     itmp2
 
 
 #define fa0      %xmm0
index b5ed97d497dd58d8a75b374e75dedd59c82d8a38..9b946a4cefa5740b0cfb16ed738a58442541c377 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Edwin Steiner
 
-   $Id: md.c 4698 2006-03-28 14:31:53Z twisti $
+   $Id: md.c 4805 2006-04-21 10:54:24Z twisti $
 
 */
 
@@ -37,6 +37,7 @@
 
 #include "config.h"
 
+#include <assert.h>
 #include <stdlib.h>
 #include <ucontext.h>
 
@@ -163,6 +164,77 @@ u1 *md_stacktrace_get_returnaddress(u1 *sp, u4 framesize)
 }
 
 
+/* md_get_method_patch_address *************************************************
+
+   Gets the patch address of the currently compiled method. The offset
+   is extracted from the load instruction(s) before the jump and added
+   to the right base address (PV or REG_METHODPTR).
+
+   INVOKESTATIC/SPECIAL:
+
+   49 ba 98 3a ed ab aa 2a 00 00    mov    $0x2aaaabed3a98,%r10
+   49 ff d2                         rex64Z callq  *%r10
+
+   INVOKEVIRTUAL:
+
+   4c 8b 17                         mov    (%rdi),%r10
+   49 8b 82 00 00 00 00             mov    0x0(%r10),%rax
+   48 ff d3                         rex64 callq  *%rax
+
+   INVOKEINTERFACE:
+
+   4c 8b 17                         mov    (%rdi),%r10
+   4d 8b 92 00 00 00 00             mov    0x0(%r10),%r10
+   49 8b 82 00 00 00 00             mov    0x0(%r10),%rax
+   48 ff d3                         rex64 callq  *%r11
+
+*******************************************************************************/
+
+u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
+{
+       u1  mcode;
+       s4  offset;
+       u1 *pa;                             /* patch address                      */
+
+       /* go back to the actual call instruction (3-bytes) */
+
+       ra = ra - 3;
+
+       /* get the last byte of the call */
+
+       mcode = ra[2];
+
+       /* check for the different calls */
+
+       /* INVOKESTATIC/SPECIAL */
+
+       if (mcode == 0xd2) {
+               /* patch address is 8-bytes before the call instruction */
+
+               pa = ra - 8;
+
+       } else if (mcode == 0xd3) {
+               /* INVOKEVIRTUAL/INTERFACE */
+
+               /* Get the offset from the instruction (the offset address is
+                  4-bytes before the call instruction). */
+
+               offset = *((s4 *) (ra - 4));
+
+               /* add the offset to the method pointer */
+
+               pa = mptr + offset;
+
+       } else {
+               /* catch any problems */
+
+               assert(0);
+       }
+
+       return pa;
+}
+
+
 /* md_codegen_findmethod *******************************************************
 
    On this architecture just a wrapper function to codegen_findmethod.
@@ -195,6 +267,30 @@ void md_cacheflush(u1 *addr, s4 nbytes)
 }
 
 
+/* md_icacheflush **************************************************************
+
+   Calls the system's function to flush the instruction cache.
+
+*******************************************************************************/
+
+void md_icacheflush(u1 *addr, s4 nbytes)
+{
+       /* do nothing */
+}
+
+
+/* md_dcacheflush **************************************************************
+
+   Calls the system's function to flush the data cache.
+
+*******************************************************************************/
+
+void md_dcacheflush(u1 *addr, s4 nbytes)
+{
+       /* do nothing */
+}
+
+
 /* md_patch_replacement_point **************************************************
 
    Patch the given replacement point.