* src/vm/array.c: Changed copyright.
[cacao.git] / src / vm / exceptions.c
index 986de51e183f310c399e1a2ecca8c9c7c1861140..b231276c032f5c10ffec7468a0a53ed90c10f50a 100644 (file)
@@ -83,13 +83,13 @@ java_object_t *_no_threads_exceptionptr = NULL;
 #endif
 
 
-/* init_system_exceptions ******************************************************
+/* exceptions_init *************************************************************
 
-   Load and link exceptions used in the system.
+   Initialize the exceptions subsystem.
 
 *******************************************************************************/
 
-bool exceptions_init(void)
+void exceptions_init(void)
 {
 #if !(defined(__ARM__) && defined(__LINUX__))
        /* On arm-linux the first memory page can't be mmap'ed, as it
@@ -109,90 +109,6 @@ bool exceptions_init(void)
 
        if (OFFSET(java_bytearray_t, 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_t, data), EXCEPTION_HARDWARE_LARGEST);
-
-       /* java/lang/Throwable */
-
-       if (!(class_java_lang_Throwable =
-                 load_class_bootstrap(utf_java_lang_Throwable)) ||
-               !link_class(class_java_lang_Throwable))
-               return false;
-
-       /* java/lang/Error */
-
-       if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
-               !link_class(class_java_lang_Error))
-               return false;
-
-#if defined(ENABLE_JAVASE)
-       /* java/lang/LinkageError */
-
-       if (!(class_java_lang_LinkageError =
-                 load_class_bootstrap(utf_java_lang_LinkageError)) ||
-               !link_class(class_java_lang_LinkageError))
-               return false;
-#endif
-
-       /* java/lang/NoClassDefFoundError */
-
-       if (!(class_java_lang_NoClassDefFoundError =
-                 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
-               !link_class(class_java_lang_NoClassDefFoundError))
-               return false;
-
-       /* java/lang/OutOfMemoryError */
-
-       if (!(class_java_lang_OutOfMemoryError =
-                 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
-               !link_class(class_java_lang_OutOfMemoryError))
-               return false;
-
-       /* java/lang/VirtualMachineError */
-
-       if (!(class_java_lang_VirtualMachineError =
-                 load_class_bootstrap(utf_java_lang_VirtualMachineError)) ||
-               !link_class(class_java_lang_VirtualMachineError))
-               return false;
-
-
-       /* java/lang/Exception */
-
-       if (!(class_java_lang_Exception =
-                 load_class_bootstrap(utf_java_lang_Exception)) ||
-               !link_class(class_java_lang_Exception))
-               return false;
-
-       /* java/lang/ClassCastException */
-
-       if (!(class_java_lang_ClassCastException =
-                 load_class_bootstrap(utf_java_lang_ClassCastException)) ||
-               !link_class(class_java_lang_ClassCastException))
-               return false;
-
-       /* java/lang/ClassNotFoundException */
-
-       if (!(class_java_lang_ClassNotFoundException =
-                 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
-               !link_class(class_java_lang_ClassNotFoundException))
-               return false;
-
-       /* java/lang/NullPointerException */
-
-       if (!(class_java_lang_NullPointerException =
-                 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
-               !link_class(class_java_lang_NullPointerException))
-               return false;
-
-
-#if defined(WITH_CLASSPATH_GNU)
-       /* java/lang/VMThrowable */
-
-       if (!(class_java_lang_VMThrowable =
-                 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
-               !link_class(class_java_lang_VMThrowable))
-               return false;
-#endif
-
-       return true;
 }
 
 
@@ -204,17 +120,29 @@ bool exceptions_init(void)
 
 java_handle_t *exceptions_get_exception(void)
 {
+       java_object_t *o;
        java_handle_t *e;
+#if defined(ENABLE_THREADS)
+       threadobject  *t;
+
+       t = THREADOBJECT;
+#endif
 
-       /* get the exception */
+       /* Get the exception. */
 
        LLNI_CRITICAL_START;
 
-       e = LLNI_WRAP(*exceptionptr);
+#if defined(ENABLE_THREADS)
+       o = t->_exceptionptr;
+#else
+       o = _no_threads_exceptionptr;
+#endif
+
+       e = LLNI_WRAP(o);
 
        LLNI_CRITICAL_END;
 
-       /* return the exception */
+       /* Return the exception. */
 
        return e;
 }
@@ -226,13 +154,37 @@ java_handle_t *exceptions_get_exception(void)
 
 *******************************************************************************/
 
-void exceptions_set_exception(java_handle_t *o)
+void exceptions_set_exception(java_handle_t *e)
 {
-       /* set the exception */
+       threadobject  *t;
+       java_object_t *o;
+
+#if defined(ENABLE_THREADS)
+       t = THREADOBJECT;
+#else
+       t = NULL;
+#endif
+
+       /* Set the exception. */
 
        LLNI_CRITICAL_START;
 
-       *exceptionptr = LLNI_UNWRAP(o);
+       o = LLNI_UNWRAP(e);
+
+#if !defined(NDEBUG)
+       if (opt_DebugExceptions) {
+               printf("[exceptions_set_exception  : t=%p, o=%p, class=",
+                          (void *) t, (void *) o);
+               class_print(o->vftbl->class);
+               printf("]\n");
+       }
+#endif
+
+#if defined(ENABLE_THREADS)
+       t->_exceptionptr = o;
+#else
+       _no_threads_exceptionptr = o;
+#endif
 
        LLNI_CRITICAL_END;
 }
@@ -246,7 +198,27 @@ void exceptions_set_exception(java_handle_t *o)
 
 void exceptions_clear_exception(void)
 {
-       exceptions_set_exception(NULL);
+       threadobject *t;
+
+#if defined(ENABLE_THREADS)
+       t = THREADOBJECT;
+#else
+       t = NULL;
+#endif
+
+       /* Set the exception. */
+
+#if !defined(NDEBUG)
+       if (opt_DebugExceptions) {
+               printf("[exceptions_clear_exception: t=%p]\n", (void *) t);
+       }
+#endif
+
+#if defined(ENABLE_THREADS)
+       t->_exceptionptr = NULL;
+#else
+       _no_threads_exceptionptr = NULL;
+#endif
 }
 
 
@@ -261,13 +233,14 @@ java_handle_t *exceptions_get_and_clear_exception(void)
 {
        java_handle_t *o;
 
-       /* get the exception */
+       /* Get the exception... */
 
        o = exceptions_get_exception();
 
-       /* and clear the exception */
+       /* ...and clear the exception if it is set. */
 
-       exceptions_clear_exception();
+       if (o != NULL)
+               exceptions_clear_exception();
 
        /* return the exception */
 
@@ -275,25 +248,31 @@ java_handle_t *exceptions_get_and_clear_exception(void)
 }
 
 
-/* exceptions_new_class ********************************************************
+/* exceptions_abort ************************************************************
 
-   Creates an exception object from the given class and initalizes it.
+   Prints exception to be thrown and aborts.
 
    IN:
-      class....class pointer
+      classname....class name
+      message......exception message
 
 *******************************************************************************/
 
-static java_handle_t *exceptions_new_class(classinfo *c)
+static void exceptions_abort(utf *classname, utf *message)
 {
-       java_handle_t *o;
+       log_println("exception thrown while VM is initializing: ");
 
-       o = native_new_and_init(c);
+       log_start();
+       utf_display_printable_ascii_classname(classname);
 
-       if (o == NULL)
-               return exceptions_get_exception();
+       if (message != NULL) {
+               log_print(": ");
+               utf_display_printable_ascii_classname(message);
+       }
 
-       return o;
+       log_finish();
+
+       vm_abort("Aborting...");
 }
 
 
@@ -311,37 +290,20 @@ static java_handle_t *exceptions_new_utf(utf *classname)
        classinfo     *c;
        java_handle_t *o;
 
+       if (vm_initializing)
+               exceptions_abort(classname, NULL);
+
        c = load_class_bootstrap(classname);
 
        if (c == NULL)
                return exceptions_get_exception();
 
-       o = exceptions_new_class(c);
-
-       return o;
-}
-
-
-/* exceptions_throw_class ******************************************************
-
-   Creates an exception object from the given class, initalizes and
-   throws it.
-
-   IN:
-      class....class pointer
-
-*******************************************************************************/
-
-static void exceptions_throw_class(classinfo *c)
-{
-       java_handle_t *o;
-
-       o = exceptions_new_class(c);
+       o = native_new_and_init(c);
 
        if (o == NULL)
-               return;
+               return exceptions_get_exception();
 
-       exceptions_set_exception(o);
+       return o;
 }
 
 
@@ -357,14 +319,14 @@ static void exceptions_throw_class(classinfo *c)
 
 static void exceptions_throw_utf(utf *classname)
 {
-       classinfo *c;
+       java_handle_t *o;
 
-       c = load_class_bootstrap(classname);
+       o = exceptions_new_utf(classname);
 
-       if (c == NULL)
+       if (o == NULL)
                return;
 
-       exceptions_throw_class(c);
+       exceptions_set_exception(o);
 }
 
 
@@ -387,6 +349,9 @@ static void exceptions_throw_utf_throwable(utf *classname,
        methodinfo          *m;
        java_lang_Throwable *object;
 
+       if (vm_initializing)
+               exceptions_abort(classname, NULL);
+
        object = (java_lang_Throwable *) cause;
 
        c = load_class_bootstrap(classname);
@@ -436,6 +401,9 @@ static void exceptions_throw_utf_exception(utf *classname,
        java_handle_t *o;
        methodinfo    *m;
 
+       if (vm_initializing)
+               exceptions_abort(classname, NULL);
+
        c = load_class_bootstrap(classname);
 
        if (c == NULL)
@@ -484,6 +452,9 @@ static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
        java_lang_String    *s;
        java_lang_Throwable *object;
 
+       if (vm_initializing)
+               exceptions_abort(classname, NULL);
+
        object = (java_lang_Throwable *) cause;
 
        c = load_class_bootstrap(classname);
@@ -551,6 +522,9 @@ static java_handle_t *exceptions_new_utf_javastring(utf *classname,
        java_handle_t *o;
        classinfo     *c;
    
+       if (vm_initializing)
+               exceptions_abort(classname, NULL);
+
        c = load_class_bootstrap(classname);
 
        if (c == NULL)
@@ -565,35 +539,6 @@ static java_handle_t *exceptions_new_utf_javastring(utf *classname,
 }
 
 
-/* exceptions_new_class_utf ****************************************************
-
-   Creates an exception object of the given class and initalizes it.
-
-   IN:
-      c..........class pointer
-      message....the message as UTF-8 string
-
-*******************************************************************************/
-
-static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
-{
-       java_handle_t *o;
-       java_handle_t *s;
-
-       s = javastring_new(message);
-
-       if (s == NULL)
-               return exceptions_get_exception();
-
-       o = native_new_and_init_string(c, s);
-
-       if (o == NULL)
-               return exceptions_get_exception();
-
-       return o;
-}
-
-
 /* exceptions_new_utf_utf ******************************************************
 
    Creates an exception object with the given name and initalizes it
@@ -612,37 +557,28 @@ static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
 static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
 {
        classinfo     *c;
+       java_handle_t *s;
        java_handle_t *o;
 
+       if (vm_initializing)
+               exceptions_abort(classname, message);
+
        c = load_class_bootstrap(classname);
 
        if (c == NULL)
                return exceptions_get_exception();
 
-       o = exceptions_new_class_utf(c, message);
-
-       return o;
-}
-
-
-/* exceptions_throw_class_utf **************************************************
-
-   Creates an exception object of the given class, initalizes and
-   throws it with the given utf message.
-
-   IN:
-      c..........class pointer
-         message....the message as an UTF-8
+       s = javastring_new(message);
 
-*******************************************************************************/
+       if (s == NULL)
+               return exceptions_get_exception();
 
-static void exceptions_throw_class_utf(classinfo *c, utf *message)
-{
-       java_handle_t *o;
+       o = native_new_and_init_string(c, s);
 
-       o = exceptions_new_class_utf(c, message);
+       if (o == NULL)
+               return exceptions_get_exception();
 
-       exceptions_set_exception(o);
+       return o;
 }
 
 
@@ -694,7 +630,7 @@ static java_handle_t *exceptions_new_error(utf *message)
 {
        java_handle_t *o;
 
-       o = exceptions_new_class_utf(class_java_lang_Error, message);
+       o = exceptions_new_utf_utf(utf_java_lang_Error, message);
 
        return o;
 }
@@ -710,12 +646,13 @@ static java_handle_t *exceptions_new_error(utf *message)
 
 java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
 {
-       stackframeinfo  sfi;
-       java_handle_t  *e;
+       stackframeinfo_t  sfi;
+       java_handle_t    *e;
+       java_object_t    *o;
 
-       /* create the stackframeinfo (XPC is equal to RA) */
+       /* Fill and add a stackframeinfo (XPC is equal to RA). */
 
-       stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
+       stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
 
        /* create the exception */
 
@@ -725,11 +662,16 @@ java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
        e = exceptions_new_error(utf_java_lang_AbstractMethodError);
 #endif
 
-       /* remove the stackframeinfo */
+       /* Remove the stackframeinfo. */
 
-       stacktrace_remove_stackframeinfo(&sfi);
+       stacktrace_stackframeinfo_remove(&sfi);
 
-       return e;
+       /* unwrap the exception */
+       /* ATTENTION: do the this _after_ the stackframeinfo was removed */
+
+       o = LLNI_UNWRAP(e);
+
+       return o;
 }
 
 
@@ -851,10 +793,8 @@ void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
 *******************************************************************************/
 
 void exceptions_throw_classnotfoundexception(utf *name)
-{
-       /* we use class here, as this one is rather frequent */
-
-       exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
+{      
+       exceptions_throw_utf_utf(utf_java_lang_ClassNotFoundException, name);
 }
 
 
@@ -869,10 +809,7 @@ void exceptions_throw_classnotfoundexception(utf *name)
 
 void exceptions_throw_noclassdeffounderror(utf *name)
 {
-       if (vm_initializing)
-               vm_abort("java.lang.NoClassDefFoundError: %s", name->text);
-
-       exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
+       exceptions_throw_utf_utf(utf_java_lang_NoClassDefFoundError, name);
 }
 
 
@@ -1048,39 +985,35 @@ void exceptions_throw_internalerror(const char *message, ...)
 
 void exceptions_throw_linkageerror(const char *message, classinfo *c)
 {
-       java_handle_t *o;
-       char          *msg;
-       s4             msglen;
+       utf  *u;
+       char *msg;
+       int   len;
 
        /* calculate exception message length */
 
-       msglen = strlen(message) + 1;
+       len = strlen(message) + 1;
 
        if (c != NULL)
-               msglen += utf_bytes(c->name);
+               len += utf_bytes(c->name);
                
        /* allocate memory */
 
-       msg = MNEW(char, msglen);
+       msg = MNEW(char, len);
 
        /* generate message */
 
-       strcpy(msg,message);
+       strcpy(msg, message);
 
        if (c != NULL)
                utf_cat_classname(msg, c->name);
 
-       o = native_new_and_init_string(class_java_lang_LinkageError,
-                                                                  javastring_new_from_utf_string(msg));
+       u = utf_new_char(msg);
 
        /* free memory */
 
-       MFREE(msg, char, msglen);
+       MFREE(msg, char, len);
 
-       if (o == NULL)
-               return;
-
-       exceptions_set_exception(o);
+       exceptions_throw_utf_utf(utf_java_lang_LinkageError, u);
 }
 
 
@@ -1168,7 +1101,7 @@ void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
 #if defined(ENABLE_JAVASE)
        exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
 #else
-       exceptions_throw_class_utf(class_java_lang_Error, u);
+       exceptions_throw_utf_utf(utf_java_lang_Error, u);
 #endif
 }
 
@@ -1181,7 +1114,7 @@ void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
 
 void exceptions_throw_outofmemoryerror(void)
 {
-       exceptions_throw_class(class_java_lang_OutOfMemoryError);
+       exceptions_throw_utf(utf_java_lang_OutOfMemoryError);
 }
 
 
@@ -1200,7 +1133,7 @@ void exceptions_throw_unsatisfiedlinkerror(utf *name)
 #if defined(ENABLE_JAVASE)
        exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
 #else
-       exceptions_throw_class_utf(class_java_lang_Error, name);
+       exceptions_throw_utf_utf(utf_java_lang_Error, name);
 #endif
 }
 
@@ -1471,7 +1404,6 @@ void exceptions_throw_arrayindexoutofboundsexception(void)
 void exceptions_throw_arraystoreexception(void)
 {
        exceptions_throw_utf(utf_java_lang_ArrayStoreException);
-/*     e = native_new_and_init(class_java_lang_ArrayStoreException); */
 }
 
 
@@ -1491,7 +1423,7 @@ java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
 
        classname = c->name;
 
-       e = exceptions_new_class_utf(class_java_lang_ClassCastException, classname);
+       e = exceptions_new_utf_utf(utf_java_lang_ClassCastException, classname);
 
        return e;
 }
@@ -1612,7 +1544,7 @@ java_handle_t *exceptions_new_nullpointerexception(void)
 {
        java_handle_t *o;
 
-       o = exceptions_new_class(class_java_lang_NullPointerException);
+       o = exceptions_new_utf(utf_java_lang_NullPointerException);
 
        return o;
 }
@@ -1627,7 +1559,7 @@ java_handle_t *exceptions_new_nullpointerexception(void)
 
 void exceptions_throw_nullpointerexception(void)
 {
-       exceptions_throw_class(class_java_lang_NullPointerException);
+       exceptions_throw_utf(utf_java_lang_NullPointerException);
 }
 
 
@@ -1666,18 +1598,27 @@ void exceptions_throw_stringindexoutofboundsexception(void)
 
 void exceptions_classnotfoundexception_to_noclassdeffounderror(void)
 {
+       classinfo           *c;
        java_handle_t       *o;
        java_handle_t       *cause;
        java_lang_Throwable *object;
        java_lang_String    *s;
 
-       /* get the cause */
+       /* Load java/lang/ClassNotFoundException for the instanceof
+          check. */
+
+       c = load_class_bootstrap(utf_java_lang_ClassNotFoundException);
+
+       if (c == NULL)
+               return;
+
+       /* Get the cause. */
 
        cause = exceptions_get_exception();
 
-       /* convert ClassNotFoundException's to NoClassDefFoundError's */
+       /* Convert ClassNotFoundException's to NoClassDefFoundError's. */
 
-       if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
+       if (builtin_instanceof(cause, c)) {
                /* clear exception, because we are calling jit code again */
 
                exceptions_clear_exception();
@@ -1766,19 +1707,21 @@ java_handle_t *exceptions_fillinstacktrace(void)
 *******************************************************************************/
 
 #if defined(ENABLE_JIT)
-u1 *exceptions_handle_exception(java_object_t *xptr, u1 *xpc, u1 *pv, u1 *sp)
+u1 *exceptions_handle_exception(java_object_t *xptro, u1 *xpc, u1 *pv, u1 *sp)
 {
-       methodinfo            *m;
-       codeinfo              *code;
-       s4                     issync;
-       dseg_exception_entry  *ex;
-       s4                     exceptiontablelength;
-       s4                     i;
-       classref_or_classinfo  cr;
-       classinfo             *c;
+       stackframeinfo_t        sfi;
+       java_handle_t          *xptr;
+       methodinfo             *m;
+       codeinfo               *code;
+       exceptiontable_t       *et;
+       exceptiontable_entry_t *ete;
+       s4                      i;
+       classref_or_classinfo   cr;
+       classinfo              *c;
 #if defined(ENABLE_THREADS)
-       java_object_t         *o;
+       java_object_t          *o;
 #endif
+       u1                     *result;
 
 #ifdef __S390__
        /* Addresses are 31 bit integers */
@@ -1787,48 +1730,55 @@ u1 *exceptions_handle_exception(java_object_t *xptr, u1 *xpc, u1 *pv, u1 *sp)
 #      define ADDR_MASK(x) (x)
 #endif
 
-       xpc = ADDR_MASK(xpc);
+       xptr = LLNI_WRAP(xptro);
+       xpc  = ADDR_MASK(xpc);
+
+       /* Fill and add a stackframeinfo (XPC is equal to RA). */
 
-       /* get info from the method header */
+       stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
 
-       code                 = *((codeinfo **)            (pv + CodeinfoPointer));
-       issync               = *((s4 *)                   (pv + IsSync));
-       ex                   =   (dseg_exception_entry *) (pv + ExTableStart);
-       exceptiontablelength = *((s4 *)                   (pv + ExTableSize));
+       result = NULL;
+
+       /* Get the codeinfo for the current method. */
+
+       code = code_get_codeinfo_for_pv(pv);
 
        /* Get the methodinfo pointer from the codeinfo pointer. For
-          asm_vm_call_method the codeinfo pointer is NULL. */
+          asm_vm_call_method the codeinfo pointer is NULL and we simply
+          can return the proper exception handler. */
+
+       if (code == NULL) {
+               result = (u1 *) (uintptr_t) &asm_vm_call_method_exception_handler;
+               goto exceptions_handle_exception_return;
+       }
 
-       m = (code == NULL) ? NULL : code->m;
+       m = code->m;
 
 #if !defined(NDEBUG)
        /* print exception trace */
 
        if (opt_TraceExceptions)
-               trace_exception(xptr, m, xpc);
+               trace_exception(LLNI_DIRECT(xptr), m, xpc);
 
 # if defined(ENABLE_VMLOG)
        vmlog_cacao_throw(xptr);
 # endif
 #endif
 
-       for (i = 0; i < exceptiontablelength; i++) {
-               /* ATTENTION: keep this here, as we need to decrement the
-           pointer before the loop executes! */
+       /* Get the exception table. */
 
-               ex--;
+       et = code->exceptiontable;
 
-               /* If the start and end PC is NULL, this means we have the
-                  special case of asm_vm_call_method.  So, just return the
-                  proper exception handler. */
+       if (et != NULL) {
+       /* Iterate over all exception table entries. */
 
-               if ((ex->startpc == NULL) && (ex->endpc == NULL))
-                       return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
+       ete = et->entries;
 
+       for (i = 0; i < et->length; i++, ete++) {
                /* is the xpc is the current catch range */
 
-               if ((ADDR_MASK(ex->startpc) <= xpc) && (xpc < ADDR_MASK(ex->endpc))) {
-                       cr = ex->catchtype;
+               if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
+                       cr = ete->catchtype;
 
                        /* NULL catches everything */
 
@@ -1846,34 +1796,37 @@ u1 *exceptions_handle_exception(java_object_t *xptr, u1 *xpc, u1 *pv, u1 *sp)
                                }
 #endif
 
-                               return ex->handlerpc;
+                               result = ete->handlerpc;
+                               goto exceptions_handle_exception_return;
                        }
 
                        /* resolve or load/link the exception class */
 
                        if (IS_CLASSREF(cr)) {
                                /* The exception class reference is unresolved. */
-                               /* We have to do _eager_ resolving here. While the class of */
-                               /* the exception object is guaranteed to be loaded, it may  */
-                               /* well have been loaded by a different loader than the     */
-                               /* defining loader of m's class, which is the one we must   */
-                               /* use to resolve the catch class. Thus lazy resolving      */
-                               /* might fail, even if the result of the resolution would   */
-                               /* be an already loaded class.                              */
+                               /* We have to do _eager_ resolving here. While the
+                                  class of the exception object is guaranteed to be
+                                  loaded, it may well have been loaded by a different
+                                  loader than the defining loader of m's class, which
+                                  is the one we must use to resolve the catch
+                                  class. Thus lazy resolving might fail, even if the
+                                  result of the resolution would be an already loaded
+                                  class. */
 
                                c = resolve_classref_eager(cr.ref);
 
                                if (c == NULL) {
                                        /* Exception resolving the exception class, argh! */
-                                       return NULL;
+                                       goto exceptions_handle_exception_return;
                                }
 
-                               /* Ok, we resolved it. Enter it in the table, so we don't */
-                               /* have to do this again.                                 */
-                               /* XXX this write should be atomic. Is it?                */
+                               /* Ok, we resolved it. Enter it in the table, so we
+                                  don't have to do this again. */
+                               /* XXX this write should be atomic. Is it? */
 
-                               ex->catchtype.cls = c;
-                       } else {
+                               ete->catchtype.cls = c;
+                       }
+                       else {
                                c = cr.cls;
 
                                /* XXX I don't think this case can ever happen. -Edwin */
@@ -1881,14 +1834,14 @@ u1 *exceptions_handle_exception(java_object_t *xptr, u1 *xpc, u1 *pv, u1 *sp)
                                        /* use the methods' classloader */
                                        if (!load_class_from_classloader(c->name,
                                                                                                         m->class->classloader))
-                                               return NULL;
+                                               goto exceptions_handle_exception_return;
 
-                               /* XXX I think, if it is not linked, we can be sure that     */
-                               /* the exception object is no (indirect) instance of it, no? */
-                               /* -Edwin                                                    */
+                               /* XXX I think, if it is not linked, we can be sure
+                                  that the exception object is no (indirect) instance
+                                  of it, no?  -Edwin  */
                                if (!(c->state & CLASS_LINKED))
                                        if (!link_class(c))
-                                               return NULL;
+                                               goto exceptions_handle_exception_return;
                        }
 
                        /* is the thrown exception an instance of the catch class? */
@@ -1907,27 +1860,24 @@ u1 *exceptions_handle_exception(java_object_t *xptr, u1 *xpc, u1 *pv, u1 *sp)
                                }
 #endif
 
-                               return ex->handlerpc;
+                               result = ete->handlerpc;
+                               goto exceptions_handle_exception_return;
                        }
                }
        }
+       }
 
 #if defined(ENABLE_THREADS)
-       /* is this method synchronized? */
+       /* Is this method realization synchronized? */
 
-       if (issync) {
-               /* get synchronization object */
+       if (code_is_synchronized(code)) {
+               /* Get synchronization object. */
 
-# if (defined(__MIPS__) && (SIZEOF_VOID_P == 4)) || defined(__I386__) || defined(__S390__) || defined(__POWERPC__)
-               /* XXX change this if we ever want to use 4-byte stackslots */
-               o = *((java_object_t **) (sp + issync - 8));
-# else
-               o = *((java_object_t **) (sp + issync - SIZEOF_VOID_P));
-# endif
+               o = *((java_object_t **) (sp + code->synchronizedoffset));
 
                assert(o != NULL);
 
-               lock_monitor_exit(o);
+               lock_monitor_exit(LLNI_QUICKWRAP(o));
        }
 #endif
 
@@ -1956,7 +1906,15 @@ u1 *exceptions_handle_exception(java_object_t *xptr, u1 *xpc, u1 *pv, u1 *sp)
 # endif
 #endif /* !defined(NDEBUG) */
 
-       return NULL;
+       result = NULL;
+
+exceptions_handle_exception_return:
+
+       /* Remove the stackframeinfo. */
+
+       stacktrace_stackframeinfo_remove(&sfi);
+
+       return result;
 }
 #endif /* defined(ENABLE_JIT) */