Merged revisions 8245-8298 via svnmerge from
[cacao.git] / src / vm / jit / powerpc64 / linux / md-os.c
index 3b63ad6f9a5221a78a32a33873344c64adc9515a..98c2c2bbd0307b5d7732c47f4a66548472289c44 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 $
+   $Id: md-os.c 8283 2007-08-09 15:10:05Z twisti $
 
 */
 
 #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 +132,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 +143,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.