* src/vm/jit/asmpart.h [!JIT_COMPILER_VIA_SIGNAL]
[cacao.git] / src / vm / jit / x86_64 / linux / md-os.c
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;
+       }
 }