* src/vm/jit/intrp/codegen.c (codegen): Save synchronized object in
[cacao.git] / src / vm / jit / intrp / asmpart.c
index a0ab92935a61e21b5745333ce7e2dbcbbfec42d7..90282310e469bb1e09670c9daf40aa4e8ba6e763 100644 (file)
@@ -29,7 +29,7 @@
 
    Changes:
 
-   $Id: asmpart.c 5055 2006-06-28 20:33:38Z edwin $
+   $Id: asmpart.c 5694 2006-10-05 16:12:16Z edwin $
 
 */
 
@@ -175,25 +175,28 @@ double intrp_asm_vm_call_method_double(methodinfo *m, s4 vmargscount,
 
 Inst *intrp_asm_handle_exception(Inst *ip, java_objectheader *o, Cell *fp, Cell **new_spp, Cell **new_fpp)
 {
-       classinfo      *c;
-       s4              framesize;
-       exceptionentry *ex;
-       s4              exceptiontablelength;
-       s4              i;
+       classinfo            *c;
+       classref_or_classinfo cr;
+       s4                    framesize;
+       s4                    issync;
+       exceptionentry       *ex;
+       s4                    exceptiontablelength;
+       s4                    i;
 
   /* for a description of the stack see IRETURN in java.vmg */
 
   for (; fp != NULL; ) {
-         u1 *f = codegen_findmethod((u1 *) (ip - 1));
+         u1 *f = codegen_get_pv_from_pc((u1 *) (ip - 1));
 
          /* get methodinfo pointer from method header */
 
          codeinfo *code = *((codeinfo **) ((u1 *)f + CodeinfoPointer));
          methodinfo *m = code->m;
 
-         framesize = (*((s4 *) (((u1 *) f) + FrameSize)));
-         ex = (exceptionentry *) (((u1 *) f) + ExTableStart);
-         exceptiontablelength = *((s4 *) (((u1 *) f) + ExTableSize));
+         framesize            = *((s4 *)             (((u1 *) f) + FrameSize));
+         issync               = *((s4 *)             (((u1 *) f) + IsSync));
+         ex                   =   (exceptionentry *) (((u1 *) f) + ExTableStart);
+         exceptiontablelength = *((s4 *)             (((u1 *) f) + ExTableSize));
 
 #if !defined(NDEBUG)
          if (opt_verbose || opt_verbosecall || opt_verboseexception)
@@ -202,17 +205,53 @@ Inst *intrp_asm_handle_exception(Inst *ip, java_objectheader *o, Cell *fp, Cell
 
          for (i = 0; i < exceptiontablelength; i++) {
                  ex--;
-                 c = ex->catchtype.cls;
 
-                 if (c != NULL) {
-                         if (!(c->state & CLASS_LOADED))
-                                 /* XXX fix me! */
-                                 if (!load_class_bootstrap(c->name))
-                                         assert(0);
+                 cr = ex->catchtype;
+
+                 if (cr.any == NULL) {
+                         /* catch all */
+                         c = NULL;
+                 }
+                 else {
+                         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.                              */
+
+                                 /* The resolving may involve Java code, so we need a usable */
+                                 /* global_sp. XXX is this a correct value for global_sp?    */
+
+                                 global_sp = (Cell *)(((u1 *)fp) - framesize - SIZEOF_VOID_P);
 
-                         if (!(c->state & CLASS_LINKED))
-                                 if (!link_class(c))
+                                 c = resolve_classref_eager(cr.ref);
+
+                                 CLEAR_global_sp;
+
+                                 if (c == NULL) {
+                                         /* Exception resolving the exception class, argh! */
+                                         /* XXX how to report that error? */
                                          assert(0);
+                                 }
+
+                                 /* 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 {
+                                 c = cr.cls;
+                               
+                                 /* If the class is not linked, the exception object cannot */
+                                 /* be an instance of it.                                   */
+                                 if (!(c->state & CLASS_LINKED))
+                                         continue;
+                         }
                  }
 
                  if (ip-1 >= (Inst *) ex->startpc && ip-1 < (Inst *) ex->endpc &&
@@ -223,6 +262,29 @@ Inst *intrp_asm_handle_exception(Inst *ip, java_objectheader *o, Cell *fp, Cell
                  }
          }
 
+#if defined(ENABLE_THREADS)
+         /* is this method synchronized? */
+
+         if (issync) {
+                 java_objectheader *syncobj;
+
+                 /* get synchronization object */
+
+                 if (m->flags & ACC_STATIC) {
+                         syncobj = (java_objectheader *) m->class;
+                 }
+                 else {
+                         syncobj = (java_objectheader *) access_local_cell(-framesize + SIZEOF_VOID_P);
+                 }
+
+                 assert(syncobj != NULL);
+
+                 lock_monitor_exit(syncobj);
+         }
+#endif /* defined(ENABLE_THREADS) */
+
+         /* unwind stack frame */
+
          ip = (Inst *)access_local_cell(-framesize - SIZEOF_VOID_P);
          fp = (Cell *)access_local_cell(-framesize);
   }