* Merged with default branch at rev 16f3633aaa5a.
[cacao.git] / src / vm / jit / powerpc64 / linux / md-os.c
index 3b63ad6f9a5221a78a32a33873344c64adc9515a..3e62f609598ae29371a409dc0d70b8dea04934d8 100644 (file)
@@ -1,6 +1,6 @@
-/* src/vm/jit/powerpc64/linux/md-os.c - machine dependent PowerPC Linux functions
+/* src/vm/jit/powerpc64/linux/md-os.c - machine dependent PowerPC64 Linux functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
-   $Id: md-os.c 5081 2006-07-06 13:59:01Z tbfg $
-
 */
 
 
 #include "config.h"
 
 #include <assert.h>
+#include <stdint.h>
 #include <ucontext.h>
 
 #include "vm/types.h"
 
+#include "vm/jit/powerpc64/codegen.h"
 #include "vm/jit/powerpc64/linux/md-abi.h"
 
 #if defined(ENABLE_THREADS)
 
 #include "vm/exceptions.h"
 #include "vm/signallocal.h"
-#include "vm/stringlocal.h"
+
 #include "vm/jit/asmpart.h"
 
 #if defined(ENABLE_PROFILING)
-# include "vm/jit/profile/profile.h"
+# include "vm/jit/optimizing/profile.h"
 #endif
 
 #include "vm/jit/stacktrace.h"
 
 
 /* md_signal_handler_sigsegv ***************************************************
-
-   NullPointerException signal handler for hardware null pointer
-   check.
+       Signal handler for hardware-exceptions.
 
 *******************************************************************************/
 
-void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) {}
-void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p) {}
-void thread_restartcriticalsection(ucontext_t *_uc) {}
-
-#if 0
 void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 {
-       ucontext_t  *_uc;
-       mcontext_t  *_mc;
-       u4           instr;
-       s4           reg;
-       ptrint       addr;
-       u1          *pv;
-       u1          *sp;
-       u1          *ra;
-       u1          *xpc;
+       stackframeinfo  sfi;
+       ucontext_t     *_uc;
+       mcontext_t     *_mc;
+       u1             *pv;
+       u1             *sp;
+       u1             *ra;
+       u1             *xpc;
+       u4              mcode;
+       int             s1;
+       int16_t         disp;
+       int             d;
+       int             type;
+       intptr_t        addr;
+       intptr_t        val;
+       void           *p;
 
        _uc = (ucontext_t *) _p;
-       _mc = _uc->uc_mcontext.uc_regs;
+       _mc = &(_uc->uc_mcontext);
+
+       /* get register values */
+
+       pv = (u1*) _mc->gp_regs[REG_PV];
+       sp = (u1*) _mc->gp_regs[REG_SP];
+       ra = (u1*) _mc->gp_regs[PT_LNK];                     /* correct for leafs */
+       xpc =(u1*) _mc->gp_regs[PT_NIP];
+
+       /* get the throwing instruction */
+
+       mcode = *((u4*)xpc);
+
+       s1   = M_INSTR_OP2_IMM_A(mcode);
+       disp = M_INSTR_OP2_IMM_I(mcode);
+       d    = M_INSTR_OP2_IMM_D(mcode);
 
-       instr = *((u4 *) _mc->gregs[PT_NIP]);
-       reg = (instr >> 16) & 0x1f;
-       addr = _mc->gregs[reg];
+       val  = _mc->gp_regs[d];
 
-       if (addr == 0) {
-               pv  = (u1 *) _mc->gregs[REG_PV];
-               sp  = (u1 *) _mc->gregs[REG_SP];
-               ra  = (u1 *) _mc->gregs[PT_LNK];         /* this is correct for leafs */
-               xpc = (u1 *) _mc->gregs[PT_NIP];
+       if (s1 == REG_ZERO) {
+               /* we use the exception type as load displacement */
+               type = disp;
+       }
+       else {
+               /* normal NPE */
+               addr = _mc->gp_regs[s1];
+               type = (s4) addr;
+       }
 
-               _mc->gregs[REG_ITMP1_XPTR] =
-                       (ptrint) stacktrace_hardware_nullpointerexception(pv, sp, ra, xpc);
+       /* create stackframeinfo */
 
-               _mc->gregs[REG_ITMP2_XPC] = (ptrint) xpc;
-               _mc->gregs[PT_NIP] = (ptrint) asm_handle_exception;
+       stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
 
-       } else {
-               throw_cacao_exception_exit(string_java_lang_InternalError,
-                                                                  "Segmentation fault: 0x%08lx at 0x%08lx",
-                                                                  addr, _mc->gregs[PT_NIP]);
-       }               
+       /* Handle the type. */
+
+       p = signal_handle(xpc, type, val);
+
+       /* remove stackframeinfo */
+
+       stacktrace_remove_stackframeinfo(&sfi);
+
+       _mc->gp_regs[REG_ITMP1]     = (intptr_t) p;
+       _mc->gp_regs[REG_ITMP2_XPC] = (intptr_t) xpc;
+       _mc->gp_regs[PT_NIP]        = (intptr_t) asm_handle_exception;
 }
 
 
@@ -115,6 +130,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
 *******************************************************************************/
 
+#if defined(ENABLE_THREADS)
 void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 {
        threadobject *tobj;
@@ -125,33 +141,40 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
        tobj = THREADOBJECT;
 
        _uc = (ucontext_t *) _p;
-       _mc = _uc->uc_mcontext.uc_regs;
+       _mc = &(_uc->uc_mcontext);
 
-       pc = (u1 *) _mc->gregs[PT_NIP];
+       pc = (u1 *) _mc->gp_regs[PT_NIP];
 
        tobj->pc = pc;
 }
+#endif
 
 
+/* md_critical_section_restart *************************************************
+
+   Search the critical sections tree for a matching section and set
+   the PC to the restart point, if necessary.
+
+*******************************************************************************/
+
 #if defined(ENABLE_THREADS)
-void thread_restartcriticalsection(ucontext_t *_uc)
+void md_critical_section_restart(ucontext_t *_uc)
 {
        mcontext_t *_mc;
        u1         *pc;
-       void       *critical;
+       u1         *npc;
 
-       _mc = _uc->uc_mcontext.uc_regs;
+       _mc = &(_uc->uc_mcontext);
 
-       pc = (u1 *) _mc->gregs[PT_NIP];
+       pc = (u1 *) _mc->gp_regs[PT_NIP];
 
-       critical = critical_find_restart_point(pc);
+       npc = critical_find_restart_point(pc);
 
-       if (critical)
-               _mc->gregs[PT_NIP] = (ptrint) critical;
+       if (npc != NULL)
+               _mc->gp_regs[PT_NIP] = (ptrint) npc;
 }
 #endif
 
-#endif
 
 /*
  * These are local overrides for various environment variables in Emacs.