* src/vm/jit/jit.c [ENABLE_PYTHON]: Changed name of hardcoded script.
[cacao.git] / src / vm / signal.c
index 8aa02dd4a02f0f3fb8d9abe32d08d890e67a6a15..5d32fb4db306c67be5627028976740ccd0451d9d 100644 (file)
@@ -22,8 +22,6 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: signal.c 8370 2007-08-20 21:44:10Z twisti $
-
 */
 
 
@@ -45,6 +43,8 @@
 
 #include "mm/memory.h"
 
+#include "native/llni.h"
+
 #if defined(ENABLE_THREADS)
 # include "threads/threads-common.h"
 #else
@@ -147,7 +147,7 @@ bool signal_init(void)
                                                           SA_NODEFER | SA_SIGINFO);
 #  endif
 
-#  if defined(__ARM__) || defined(__S390__)
+#  if defined(__ARM__) || defined(__I386__) || defined(__S390__) || defined(__X86_64__) || defined(__M68K__)
                /* XXX use better defines for that (in arch.h) */
                /* SIGILL handler */
 
@@ -173,6 +173,13 @@ bool signal_init(void)
        signal_register_signal(SIGHUP, (functionptr) signal_handler_sighup, 0);
 #endif
 
+#if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
+       /* SIGUSR1 handler for the exact GC to suspend threads */
+
+       signal_register_signal(SIGUSR1, (functionptr) md_signal_handler_sigusr1,
+                                                  SA_SIGINFO);
+#endif
+
 #if defined(ENABLE_THREADS) && defined(ENABLE_PROFILING)
        /* SIGUSR2 handler for profiling sampling */
 
@@ -220,11 +227,46 @@ void signal_register_signal(int signum, functionptr handler, int flags)
 
 *******************************************************************************/
 
-void *signal_handle(void *xpc, int type, intptr_t val)
+void *signal_handle(int type, intptr_t val,
+                                       void *pv, void *sp, void *ra, void *xpc, void *context)
 {
-       void          *p;
-       int32_t        index;
-       java_object_t *o;
+       stackframeinfo_t  sfi;
+       int32_t           index;
+       java_handle_t    *o;
+       methodinfo       *m;
+       java_handle_t    *p;
+
+       /* Prevent compiler warnings. */
+
+       o = NULL;
+       m = NULL;
+
+       /* wrap the value into a handle if it is a reference */
+       /* BEFORE: creating stackframeinfo */
+
+       switch (type) {
+       case EXCEPTION_HARDWARE_CLASSCAST:
+               o = LLNI_WRAP((java_object_t *) val);
+               break;
+
+       case EXCEPTION_HARDWARE_COMPILER:
+               /* In this case the passed PV points to the compiler stub.  We
+                  get the methodinfo pointer here and set PV to NULL so
+                  stacktrace_stackframeinfo_add determines the PV for the
+                  parent Java method. */
+
+               m  = code_get_methodinfo_for_pv(pv);
+               pv = NULL;
+               break;
+
+       default:
+               /* do nothing */
+               break;
+       }
+
+       /* Fill and add a stackframeinfo. */
+
+       stacktrace_stackframeinfo_add(&sfi, pv, sp, ra, xpc);
 
        switch (type) {
        case EXCEPTION_HARDWARE_NULLPOINTER:
@@ -240,8 +282,11 @@ void *signal_handle(void *xpc, int type, intptr_t val)
                p = exceptions_new_arrayindexoutofboundsexception(index);
                break;
 
+       case EXCEPTION_HARDWARE_ARRAYSTORE:
+               p = exceptions_new_arraystoreexception();
+               break;
+
        case EXCEPTION_HARDWARE_CLASSCAST:
-               o = (java_object_t *) val;
                p = exceptions_new_classcastexception(o);
                break;
 
@@ -251,7 +296,7 @@ void *signal_handle(void *xpc, int type, intptr_t val)
 
        case EXCEPTION_HARDWARE_PATCHER:
 #if defined(ENABLE_REPLACEMENT)
-               if (replace_me_wrapper(xpc)) {
+               if (replace_me_wrapper(xpc, context)) {
                        p = NULL;
                        break;
                }
@@ -259,6 +304,10 @@ void *signal_handle(void *xpc, int type, intptr_t val)
                p = patcher_handler(xpc);
                break;
 
+       case EXCEPTION_HARDWARE_COMPILER:
+               p = jit_compile_handle(m, sfi.pv, ra, (void *) val);
+               break;
+
        default:
                /* Let's try to get a backtrace. */
 
@@ -266,7 +315,7 @@ void *signal_handle(void *xpc, int type, intptr_t val)
 
                /* If that does not work, print more debug info. */
 
-               log_println("exceptions_new_hardware_exception: unknown exception type %d", type);
+               log_println("signal_handle: unknown hardware exception type %d", type);
 
 #if SIZEOF_VOID_P == 8
                log_println("PC=0x%016lx", xpc);
@@ -286,7 +335,17 @@ void *signal_handle(void *xpc, int type, intptr_t val)
                p = NULL;
        }
 
-       return p;
+       /* Remove stackframeinfo. */
+
+       stacktrace_stackframeinfo_remove(&sfi);
+
+       /* unwrap and return the exception object */
+       /* AFTER: removing stackframeinfo */
+
+       if (type == EXCEPTION_HARDWARE_COMPILER)
+               return p;
+       else
+               return LLNI_UNWRAP(p);
 }