* src/vm/jit/sparc64/solaris/md-os.c: Implemented hardware exception handling.
[cacao.git] / src / vm / exceptions.c
index efaef79a9574326c6036d3780d061fbf49fa3ab7..51cb6ce9596ca00c6e37c28c310565768b3c0598 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: exceptions.c 8087 2007-06-14 16:01:12Z twisti $
+   $Id: exceptions.c 8178 2007-07-05 11:13:20Z michi $
 
 */
 
@@ -64,6 +64,7 @@
 #include "vm/jit/disass.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/methodheader.h"
+#include "vm/jit/patcher-common.h"
 #include "vm/jit/stacktrace.h"
 
 #include "vmcore/class.h"
@@ -91,6 +92,10 @@ java_objectheader *_no_threads_exceptionptr = NULL;
 
 bool exceptions_init(void)
 {
+#if !(defined(__ARM__) && defined(__LINUX__))
+       /* On arm-linux the first memory page can't be mmap'ed, as it
+          contains the exception vectors. */
+
        int pagesize;
 
        /* mmap a memory page at address 0x0, so our hardware-exceptions
@@ -99,11 +104,12 @@ bool exceptions_init(void)
        pagesize = getpagesize();
 
        (void) memory_mmap_anon(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
+#endif
 
        /* check if we get into trouble with our hardware-exceptions */
 
-       if (OFFSET(java_bytearray, data) <= EXCEPTION_HARDWARE_PATCHER)
-               vm_abort("signal_init: array-data offset is less or equal the maximum hardware-exception displacement: %d <= %d", OFFSET(java_bytearray, data), EXCEPTION_HARDWARE_PATCHER);
+       if (OFFSET(java_bytearray, data) <= EXCEPTION_HARDWARE_LARGEST)
+               vm_abort("signal_init: array-data offset is less or equal the maximum hardware-exception displacement: %d <= %d", OFFSET(java_bytearray, data), EXCEPTION_HARDWARE_LARGEST);
 
        /* java/lang/Throwable */
 
@@ -272,7 +278,7 @@ static java_objectheader *exceptions_new_class(classinfo *c)
        o = native_new_and_init(c);
 
        if (o == NULL)
-               return *exceptionptr;
+               return exceptions_get_exception();
 
        return o;
 }
@@ -295,7 +301,7 @@ static java_objectheader *exceptions_new_utf(utf *classname)
        c = load_class_bootstrap(classname);
 
        if (c == NULL)
-               return *exceptionptr;
+               return exceptions_get_exception();
 
        o = exceptions_new_class(c);
 
@@ -322,7 +328,7 @@ static void exceptions_throw_class(classinfo *c)
        if (o == NULL)
                return;
 
-       *exceptionptr = o;
+       exceptions_set_exception(o);
 }
 
 
@@ -384,19 +390,12 @@ static void exceptions_throw_utf_throwable(utf *classname,
 
        /* call initializer */
 
-       m = class_findmethod(c, utf_init, utf_java_lang_String__void);
+       m = class_resolveclassmethod(c,
+                                                                utf_init,
+                                                                utf_java_lang_Throwable__void,
+                                                                NULL,
+                                                                true);
                                                      
-       if (m == NULL)
-               return;
-
-       (void) vm_call_method(m, o, object->detailMessage);
-
-       /* call initCause */
-
-       m = class_resolvemethod(c,
-                                                       utf_initCause,
-                                                       utf_java_lang_Throwable__java_lang_Throwable);
-
        if (m == NULL)
                return;
 
@@ -438,7 +437,11 @@ static void exceptions_throw_utf_exception(utf *classname,
 
        /* call initializer */
 
-       m = class_findmethod(c, utf_init, utf_java_lang_Exception__V);
+       m = class_resolveclassmethod(c,
+                                                                utf_init,
+                                                                utf_java_lang_Exception__V,
+                                                                NULL,
+                                                                true);
                                                      
        if (m == NULL)
                return;
@@ -449,6 +452,68 @@ static void exceptions_throw_utf_exception(utf *classname,
 }
 
 
+/* exceptions_throw_utf_cause **************************************************
+
+   Creates an exception object with the given name and initalizes it
+   with the given java/lang/Throwable exception with initCause.
+
+   IN:
+      classname....class name in UTF-8
+         cause........the given Throwable
+
+*******************************************************************************/
+
+static void exceptions_throw_utf_cause(utf *classname, java_objectheader *cause)
+{
+       classinfo           *c;
+       java_objectheader   *o;
+       methodinfo          *m;
+       java_lang_Throwable *object;
+
+       object = (java_lang_Throwable *) cause;
+
+       c = load_class_bootstrap(classname);
+
+       if (c == NULL)
+               return;
+
+       /* create object */
+
+       o = builtin_new(c);
+       
+       if (o == NULL)
+               return;
+
+       /* call initializer */
+
+       m = class_resolveclassmethod(c,
+                                                                utf_init,
+                                                                utf_java_lang_String__void,
+                                                                NULL,
+                                                                true);
+                                                     
+       if (m == NULL)
+               return;
+
+       (void) vm_call_method(m, o, object->detailMessage);
+
+       /* call initCause */
+
+       m = class_resolveclassmethod(c,
+                                                                utf_initCause,
+                                                                utf_java_lang_Throwable__java_lang_Throwable,
+                                                                NULL,
+                                                                true);
+
+       if (m == NULL)
+               return;
+
+       (void) vm_call_method(m, o, cause);
+
+       exceptions_set_exception(o);
+}
+
+
 /* exceptions_new_utf_javastring ***********************************************
 
    Creates an exception object with the given name and initalizes it
@@ -473,12 +538,12 @@ static java_objectheader *exceptions_new_utf_javastring(utf *classname,
        c = load_class_bootstrap(classname);
 
        if (c == NULL)
-               return *exceptionptr;
+               return exceptions_get_exception();
 
        o = native_new_and_init_string(c, message);
 
        if (o == NULL)
-               return *exceptionptr;
+               return exceptions_get_exception();
 
        return o;
 }
@@ -502,12 +567,12 @@ static java_objectheader *exceptions_new_class_utf(classinfo *c, utf *message)
        s = javastring_new(message);
 
        if (s == NULL)
-               return *exceptionptr;
+               return exceptions_get_exception();
 
        o = native_new_and_init_string(c, s);
 
        if (o == NULL)
-               return *exceptionptr;
+               return exceptions_get_exception();
 
        return o;
 }
@@ -536,7 +601,7 @@ static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
        c = load_class_bootstrap(classname);
 
        if (c == NULL)
-               return *exceptionptr;
+               return exceptions_get_exception();
 
        o = exceptions_new_class_utf(c, message);
 
@@ -557,7 +622,11 @@ static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
 
 static void exceptions_throw_class_utf(classinfo *c, utf *message)
 {
-       *exceptionptr = exceptions_new_class_utf(c, message);
+       java_objectheader *o;
+
+       o = exceptions_new_class_utf(c, message);
+
+       exceptions_set_exception(o);
 }
 
 
@@ -574,7 +643,11 @@ static void exceptions_throw_class_utf(classinfo *c, utf *message)
 
 static void exceptions_throw_utf_utf(utf *classname, utf *message)
 {
-       *exceptionptr = exceptions_new_utf_utf(classname, message);
+       java_objectheader *o;
+
+       o = exceptions_new_utf_utf(classname, message);
+
+       exceptions_set_exception(o);
 }
 
 
@@ -796,7 +869,7 @@ void exceptions_throw_noclassdeffounderror(utf *name)
 
 void exceptions_throw_noclassdeffounderror_cause(java_objectheader *cause)
 {
-       exceptions_throw_utf_throwable(utf_java_lang_NoClassDefFoundError, cause);
+       exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
 }
 
 
@@ -991,7 +1064,7 @@ void exceptions_throw_linkageerror(const char *message, classinfo *c)
        if (o == NULL)
                return;
 
-       *exceptionptr = o;
+       exceptions_set_exception(o);
 }
 
 
@@ -1343,18 +1416,18 @@ java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
                                                                 true);
 
        if (m == NULL)
-               return *exceptionptr;
+               return exceptions_get_exception();
 
        s = vm_call_method(m, NULL, index);
 
        if (s == NULL)
-               return *exceptionptr;
+               return exceptions_get_exception();
 
        o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
                                                                          s);
 
        if (o == NULL)
-               return *exceptionptr;
+               return exceptions_get_exception();
 
        return o;
 }
@@ -1567,7 +1640,7 @@ void exceptions_throw_stringindexoutofboundsexception(void)
 
 /* exceptions_classnotfoundexception_to_noclassdeffounderror *******************
 
-   Check the *exceptionptr for a ClassNotFoundException. If it is one,
+   Check the exception for a ClassNotFoundException. If it is one,
    convert it to a NoClassDefFoundError.
 
 *******************************************************************************/
@@ -1624,12 +1697,9 @@ java_objectheader *exceptions_fillinstacktrace(void)
 
        /* get exception */
 
-       o = *exceptionptr;
-       assert(o);
-
-       /* clear exception */
+       o = exceptions_get_and_clear_exception();
 
-       *exceptionptr = NULL;
+       assert(o);
 
        /* resolve methodinfo pointer from exception object */
 
@@ -1662,16 +1732,15 @@ java_objectheader *exceptions_fillinstacktrace(void)
 
 *******************************************************************************/
 
-java_objectheader *exceptions_new_hardware_exception(u1 *pv, u1 *sp, u1 *ra, u1 *xpc, s4 type, ptrint val)
+java_objectheader *exceptions_new_hardware_exception(u1 *pv, u1 *sp, u1 *ra, u1 *xpc, s4 type, ptrint val, stackframeinfo *sfi)
 {
-       stackframeinfo     sfi;
        java_objectheader *e;
        java_objectheader *o;
        s4                 index;
 
        /* create stackframeinfo */
 
-       stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
+       stacktrace_create_extern_stackframeinfo(sfi, pv, sp, ra, xpc);
 
        switch (type) {
        case EXCEPTION_HARDWARE_NULLPOINTER:
@@ -1696,6 +1765,10 @@ java_objectheader *exceptions_new_hardware_exception(u1 *pv, u1 *sp, u1 *ra, u1
                e = exceptions_fillinstacktrace();
                break;
 
+       case EXCEPTION_HARDWARE_PATCHER:
+               e = patcher_handler(xpc);
+               break;
+
        default:
                /* let's try to get a backtrace */
 
@@ -1725,7 +1798,7 @@ java_objectheader *exceptions_new_hardware_exception(u1 *pv, u1 *sp, u1 *ra, u1
 
        /* remove stackframeinfo */
 
-       stacktrace_remove_stackframeinfo(&sfi);
+       stacktrace_remove_stackframeinfo(sfi);
 
        /* return the exception object */
 
@@ -1790,7 +1863,7 @@ u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp
 #if !defined(NDEBUG)
        /* print exception trace */
 
-       if (opt_verbose || opt_verbosecall || opt_verboseexception)
+       if (opt_verbose || opt_verbosecall || opt_TraceExceptions)
                builtin_trace_exception(xptr, m, xpc, 1);
 #endif
 
@@ -1826,7 +1899,7 @@ u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp
                                vmlog_cacao_catch(xptr);
 #endif
 
-                               if (opt_verboseexception) {
+                               if (opt_TraceExceptions) {
                                        exceptions_print_exception(xptr);
                                        stacktrace_print_trace(xptr);
                                }
@@ -1887,7 +1960,7 @@ u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp
                                vmlog_cacao_catch(xptr);
 #endif
 
-                               if (opt_verboseexception) {
+                               if (opt_TraceExceptions) {
                                        exceptions_print_exception(xptr);
                                        stacktrace_print_trace(xptr);
                                }
@@ -1997,11 +2070,11 @@ void exceptions_print_exception(java_objectheader *xptr)
 
 void exceptions_print_current_exception(void)
 {
-       java_objectheader *xptr;
+       java_objectheader *o;
 
-       xptr = *exceptionptr;
+       o = exceptions_get_exception();
 
-       exceptions_print_exception(xptr);
+       exceptions_print_exception(o);
 }