* src/vm/jit/asmpart.h [!JIT_COMPILER_VIA_SIGNAL]
authorChristian Thalinger <twisti@complang.tuwien.ac.at>
Sat, 29 Sep 2007 18:09:34 +0000 (20:09 +0200)
committerChristian Thalinger <twisti@complang.tuwien.ac.at>
Sat, 29 Sep 2007 18:09:34 +0000 (20:09 +0200)
(asm_call_jit_compiler): Added #ifdef.

* src/vm/jit/codegen-common.c (codegen_generate_stub_compiler)
[JIT_COMPILER_VIA_SIGNAL]: Added new code.

* src/vm/jit/codegen-common.h [!JIT_COMPILER_VIA_SIGNAL]
(codegen_emit_stub_compiler): Added #ifdef.

* src/vm/jit/emit-common.h (emit_trap_compiler): Added.

* src/vm/jit/jit.c [!JIT_COMPILER_VIA_SIGNAL] (jit_asm_compile): Added
#ifdef.
(jit_compile_handle): New function.

* src/vm/jit/jit.h (vm/jit/stacktrace.h): Added.
[!JIT_COMPILER_VIA_SIGNAL] (jit_asm_compile): Added #ifdef.

* src/vm/jit/x86_64/arch.h (JIT_COMPILER_VIA_SIGNAL): Added
temporarily.

* src/vm/jit/x86_64/asmpart.S (asm_call_jit_compiler): Removed.

* src/vm/jit/x86_64/codegen.c (codegen_emit_stub_compiler): Removed.
* src/vm/jit/x86_64/codegen.h (COMPILERSTUB_CODESIZE): Adapted.

* src/vm/jit/x86_64/emit.c (emit_trap_compiler): New function.

* src/vm/jit/x86_64/linux/md-os.c (md_signal_handler_sigsegv): Added
JIT compiler handling code.
* src/vm/signal.c (signal_handle): Likewise.

13 files changed:
src/vm/jit/asmpart.h
src/vm/jit/codegen-common.c
src/vm/jit/codegen-common.h
src/vm/jit/emit-common.h
src/vm/jit/jit.c
src/vm/jit/jit.h
src/vm/jit/x86_64/arch.h
src/vm/jit/x86_64/asmpart.S
src/vm/jit/x86_64/codegen.c
src/vm/jit/x86_64/codegen.h
src/vm/jit/x86_64/emit.c
src/vm/jit/x86_64/linux/md-os.c
src/vm/signal.c

index e1ad0480786e0522c8f556df2769961a1db7a0ac..cb549c55f6c56242366b1853f8c94623cba42c02 100644 (file)
 /* machine dependent initialization */
 s4   asm_md_init(void);
 
+#if !defined(JIT_COMPILER_VIA_SIGNAL)
 /* 
    invokes the compiler for untranslated JavaVM methods.
    Register R0 contains a pointer to the method info structure
    (prepared by createcompilerstub).
 */
 void asm_call_jit_compiler(void);
+#endif
 
 #if defined(ENABLE_JIT)
 java_object_t *asm_vm_call_method(void *pv, uint64_t *array, int32_t stackargs);
index 4bcf87bff4a5fe4bca882a68bfa09899b54b8837..e02a579ef009c0ae4b0d427f863b2a82781e6fe3 100644 (file)
@@ -1160,6 +1160,7 @@ u1 *codegen_generate_stub_compiler(methodinfo *m)
 
        cd = jd->cd;
 
+#if !defined(JIT_COMPILER_VIA_SIGNAL)
        /* allocate code memory */
 
        c = CNEW(u1, 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
@@ -1192,6 +1193,39 @@ u1 *codegen_generate_stub_compiler(methodinfo *m)
        /* flush caches */
 
        md_cacheflush(cd->mcodebase, 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
+#else
+       /* Allocate code memory. */
+
+       c = CNEW(uint8_t, 2 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
+
+       /* Set pointers correctly. */
+
+       d = (ptrint *) c;
+
+       cd->mcodebase = c;
+
+       c = c + 2 * SIZEOF_VOID_P;
+       cd->mcodeptr = c;
+
+       /* NOTE: The codeinfo pointer is actually a pointer to the
+          methodinfo (this fakes a codeinfo structure). */
+
+       d[0] = (ptrint) m;
+       d[1] = (ptrint) &d[0];                                    /* fake code->m */
+
+       /* Emit the trap instruction. */
+
+       emit_trap_compiler(cd);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_cstub_len += 2 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE;
+#endif
+
+       /* Flush caches. */
+
+       md_cacheflush(cd->mcodebase, 2 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
+#endif
 
        /* release dump memory */
 
index c545e151e8ff78bd1f269585258a35acfc85ddeb..24365494bac7546334aa089c3e0d8e1ff82b0e9f 100644 (file)
@@ -313,7 +313,9 @@ u1       *codegen_generate_stub_compiler(methodinfo *m);
 void      codegen_generate_stub_builtin(methodinfo *m, builtintable_entry *bte);
 codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f);
 
+#if !defined(JIT_COMPILER_VIA_SIGNAL)
 void      codegen_emit_stub_compiler(jitdata *jd);
+#endif
 void      codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams);
 
 #if defined(ENABLE_INTRP)
index baad4d1c347bdd1d01675a17061b279da922ca73..11ba8f33038dbf1694fe302b9fafc0bc85fbda0b 100644 (file)
@@ -177,6 +177,7 @@ void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 r
 void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg);
 void emit_exception_check(codegendata *cd, instruction *iptr);
 
+void emit_trap_compiler(codegendata *cd);
 uint32_t emit_trap(codegendata *cd);
 
 void emit_patcher_stubs(jitdata *jd);
index 0838ce2b4fa5e2ba2badbf80591389a751f6e395..d45f71fc5d4c12c2ce35df6a98e4abb361386464 100644 (file)
@@ -1669,6 +1669,7 @@ codeinfo *jit_get_current_code(methodinfo *m)
 *******************************************************************************/
 
 #if defined(ENABLE_JIT)
+#if !defined(JIT_COMPILER_VIA_SIGNAL)
 u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
 {
        stackframeinfo  sfi;
@@ -1710,6 +1711,56 @@ u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
 
        return entrypoint;
 }
+#endif
+
+/* jit_compile_handle **********************************************************
+
+   This method is called from the appropriate signal handler which
+   handles compiler-traps and does the following:
+
+     - compile the method
+     - patch the entrypoint of the method into the calculated address in
+       the JIT code
+     - flush the instruction cache
+
+*******************************************************************************/
+
+void *jit_compile_handle(void *pc, void *pv, void *ra, void *mptr)
+{
+       methodinfo *m;
+       void       *newpv;                              /* new compiled method PV */
+       void       *pa;                                          /* patch address */
+       uintptr_t  *p;                                     /* convenience pointer */
+
+       /* Get methodinfo pointer. */
+
+       m = *((methodinfo **) (((intptr_t) pc) - 2 * SIZEOF_VOID_P));
+
+       /* Compile the method. */
+
+       newpv = jit_compile(m);
+
+       /* There was a problem during compilation. */
+
+       if (newpv == NULL)
+               return NULL;
+
+       /* Get the method patch address. */
+
+       pa = md_jit_method_patch_address(pv, ra, mptr);
+
+       /* Patch the method entry point. */
+
+       p = (uintptr_t *) pa;
+
+       *p = (uintptr_t) newpv;
+
+       /* Flush the instruction cache. */
+
+       md_icacheflush(p, SIZEOF_VOID_P);
+
+       return newpv;
+}
 #endif /* defined(ENABLE_JIT) */
 
 
index c1ea4bf3bb7c49e314795ed619444c72f7e18ee9..e0a49df7a9b91b7ad1dc712d3aa31f1531550cbc 100644 (file)
@@ -50,6 +50,7 @@ typedef struct exception_entry exception_entry;
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
+#include "vm/jit/stacktrace.h"
 
 #if defined(ENABLE_INLINING)
 # include "vm/jit/inline/inline.h"
@@ -1309,7 +1310,10 @@ codeinfo *jit_get_current_code(methodinfo *m);
 void jit_request_optimization(methodinfo *m);
 
 /* patch the method entrypoint */
+#if !defined(JIT_COMPILER_VIA_SIGNAL)
 u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra);
+#endif
+void *jit_compile_handle(void *pc, void *pv, void *ra, void *mptr);
 
 s4 jit_complement_condition(s4 opcode);
 
index c7c4c0fc96f9802b2a41ea7d16fb0731e2a11816..331e3afc70b53391ac9ffb90e9f36a6a05819991 100644 (file)
@@ -28,6 +28,8 @@
 #ifndef _ARCH_H
 #define _ARCH_H
 
+#define JIT_COMPILER_VIA_SIGNAL
+
 #include "config.h"
 
 
index 6ddd7dde62c8334b918a190bf4c1c7ec889e2b22..af15de533c1ac9baa4a58e5d1cad24dbcd3ea964 100644 (file)
@@ -48,8 +48,6 @@
        .globl asm_vm_call_method_exception_handler
        .globl asm_vm_call_method_end
 
-       .globl asm_call_jit_compiler
-
        .globl asm_handle_exception
        .globl asm_handle_nat_exception
 
@@ -182,62 +180,6 @@ asm_vm_call_method_end:
        nop
 
 
-/****************** function asm_call_jit_compiler *****************************
-*                                                                              *
-*   invokes the compiler for untranslated JavaVM methods.                      *
-*                                                                              *
-*   Register R0 contains a pointer to the method info structure (prepared      *
-*   by createcompilerstub). Using the return address in R26 and the            *
-*   offset in the LDA instruction or using the value in methodptr R28 the      *
-*   patching address for storing the method address can be computed:           *
-*                                                                              *
-*   method address was either loaded using                                     *
-*                                                                              *
-*   i386_mov_imm_reg(a, REG_ITMP2)                ; invokestatic/special       *
-*   i386_call_reg(REG_ITMP2)                                                   *
-*                                                                              *
-*   or                                                                         *
-*                                                                              *
-*   i386_mov_membase_reg(REG_SP, 0, REG_ITMP2)    ; invokevirtual/interface    *
-*   i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3)                *
-*   i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \                *
-*       sizeof(methodptr) * m->vftblindex, REG_ITMP1)                          *
-*   i386_call_reg(REG_ITMP1)                                                   *
-*                                                                              *
-*   in the static case the method pointer can be computed using the            *
-*   return address and the lda function following the jmp instruction          *
-*                                                                              *
-*******************************************************************************/
-
-asm_call_jit_compiler:
-L_asm_call_jit_compiler:                /* required for PIC code              */
-       sub     $(ARG_CNT+1)*8,sp           /* +1: keep stack 16-byte aligned     */
-
-       SAVE_ARGUMENT_REGISTERS(0)
-
-       mov     itmp1,a0                    /* pass methodinfo pointer            */
-       mov     mptr,a1                     /* pass method pointer                */
-       mov     sp,a2                       /* pass java sp                       */
-       add     $(1+ARG_CNT+1)*8,a2
-       mov     (ARG_CNT+1)*8(sp),a3        /* pass ra to java function           */
-       call    jit_asm_compile@PLT
-
-       RESTORE_ARGUMENT_REGISTERS(0)
-
-       add     $(ARG_CNT+1)*8,sp           /* remove stack frame                 */
-
-       test    v0,v0                       /* check for exception                */
-       je      L_asm_call_jit_compiler_exception
-
-       jmp     *v0                         /* ...and now call the new method     */
-
-L_asm_call_jit_compiler_exception:
-       call    exceptions_get_and_clear_exception@PLT
-       pop     xpc                         /* delete return address              */
-       sub     $3,xpc                      /* faulting address is ra - 3         */
-       jmp     L_asm_handle_exception
-
-
 /* asm_handle_exception ********************************************************
 *                                                                              *
 *   This function handles an exception. It does not use the usual calling      *
index dff6060f7fab6d5e9264ccc9630a4a7de4da14ba..6824bf53243b7ffcdd40dc40d407458b2472bacc 100644 (file)
@@ -2877,32 +2877,6 @@ gen_method:
 }
 
 
-/* codegen_emit_stub_compiler **************************************************
-
-   Emit a stub routine which calls the compiler.
-       
-*******************************************************************************/
-
-void codegen_emit_stub_compiler(jitdata *jd)
-{
-       methodinfo  *m;
-       codegendata *cd;
-
-       /* get required compiler data */
-
-       m  = jd->m;
-       cd = jd->cd;
-
-       /* code for the stub */
-
-       M_LLD(REG_ITMP1, RIP, -(7 * 1 + 2 * SIZEOF_VOID_P));               /* methodinfo  */
-/*     M_ALD(REG_ITMP1, RIP, -(2 * SIZEOF_VOID_P));               /\* methodinfo  *\/ */
-       M_LLD(REG_ITMP3, RIP, -(7 * 2 + 3 * SIZEOF_VOID_P));          /* compiler pointer */
-/*     M_ALD(REG_ITMP3, RIP, -(3 * SIZEOF_VOID_P));          /\* compiler pointer *\/ */
-       M_JMP(REG_ITMP3);
-}
-
-
 /* codegen_emit_stub_native ****************************************************
 
    Emits a stub routine which calls a native method.
index 6b0fb88fc2ef3be100810093efa96b06eb255621..add6b306a1df7f94eabd069e79f4a5db88bca874 100644 (file)
 
 /* stub defines ***************************************************************/
 
-#define COMPILERSTUB_CODESIZE    7 + 7 + 3
+#define COMPILERSTUB_CODESIZE    8
 
 
 /* macros to create code ******************************************************/
index 4693e218c26a2513bd57db0936c8c9376b4abed2..fe08a7f4127a25684533b95c6e6143412798cd95 100644 (file)
@@ -435,6 +435,18 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
 }
 
 
+/* emit_trap *******************************************************************
+
+   Emit a JIT compiler trap instruction.
+
+*******************************************************************************/
+
+void emit_trap_compiler(codegendata *cd)
+{
+       M_ALD_MEM(REG_METHODPTR, EXCEPTION_HARDWARE_COMPILER);
+}
+
+
 /* emit_trap *******************************************************************
 
    Emit a trap instruction and return the original machine code.
index 146dba3bfc1013ebb4359a6980eb69f758e427bf..da050b8da316734fb7534fa2439b66bd501ec306 100644 (file)
@@ -70,6 +70,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
        int             type;
        intptr_t        val;
        void           *p;
+       java_handle_t  *o;
 
        _uc = (ucontext_t *) _p;
        _mc = &_uc->uc_mcontext;
@@ -149,6 +150,17 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
                }
 
                val = _mc->gregs[d];
+
+               if (type == EXCEPTION_HARDWARE_COMPILER) {
+                       /* We use a framesize of zero here because the call pushed
+                          the return addres onto the stack. */
+
+                       ra = md_stacktrace_get_returnaddress(sp, 0);
+
+                       /* And remove the RA from the stack. */
+
+                       sp = sp + 1 * SIZEOF_VOID_P;
+               }
        }
        else {
                /* this was a normal NPE */
@@ -161,11 +173,30 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
        p = signal_handle(type, val, NULL, sp, ra, xpc, _p);
 
-       /* set registers */
+       /* Set registers. */
 
-       _mc->gregs[REG_RAX] = (intptr_t) p;
-       _mc->gregs[REG_R10] = (intptr_t) xpc;                    /* REG_ITMP2_XPC */
-       _mc->gregs[REG_RIP] = (intptr_t) asm_handle_exception;
+       if (type == EXCEPTION_HARDWARE_COMPILER) {
+               if (p == NULL) {
+                       o = exceptions_get_and_clear_exception();
+
+                       log_println("compiler exception");
+                       ra = ra - 3;                     /* XPC is before the actual call */
+
+                       _mc->gregs[REG_RSP] = (uintptr_t) sp;    /* Remove RA from stack. */
+
+                       _mc->gregs[REG_RAX] = (uintptr_t) o;
+                       _mc->gregs[REG_R10] = (uintptr_t) ra;            /* REG_ITMP2_XPC */
+                       _mc->gregs[REG_RIP] = (uintptr_t) asm_handle_exception;
+               }
+               else {
+                       _mc->gregs[REG_RIP] = (uintptr_t) p;
+               }
+       }
+       else {
+               _mc->gregs[REG_RAX] = (uintptr_t) p;
+               _mc->gregs[REG_R10] = (uintptr_t) xpc;               /* REG_ITMP2_XPC */
+               _mc->gregs[REG_RIP] = (uintptr_t) asm_handle_exception;
+       }
 }
 
 
index f20196d82476bc17c8c690d453f7d1765ca683c5..979b0f521d57108de521257bb65128d6c7283b76 100644 (file)
@@ -288,6 +288,10 @@ void *signal_handle(int type, intptr_t val,
                p = patcher_handler(xpc);
                break;
 
+       case EXCEPTION_HARDWARE_COMPILER:
+               p = jit_compile_handle(xpc, pv, ra, (void *) val);
+               break;
+
        default:
                /* Let's try to get a backtrace. */
 
@@ -322,7 +326,10 @@ void *signal_handle(int type, intptr_t val,
        /* unwrap and return the exception object */
        /* AFTER: removing stackframeinfo */
 
-       return LLNI_UNWRAP(p);
+       if (type == EXCEPTION_HARDWARE_COMPILER)
+               return p;
+       else
+               return LLNI_UNWRAP(p);
 }