* Removed all Id tags.
[cacao.git] / src / vm / jit / intrp / asmpart.c
index a0ab92935a61e21b5745333ce7e2dbcbbfec42d7..1d886a5352158e742c1b0f7d4fad50422b68410c 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/intrp/asmpart.c - Java-C interface functions for Interpreter
 
-   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
-            Anton Ertl
-
-   Changes:
-
-   $Id: asmpart.c 5055 2006-06-28 20:33:38Z edwin $
-
 */
 
 
 
 #include "arch.h"
 
+#if defined(ENABLE_THREADS)
+# include "threads/native/threads.h"
+#else
+# include "threads/none/threads.h"
+#endif
+
 #include "vm/builtin.h"
-#include "vm/class.h"
 #include "vm/exceptions.h"
-#include "vm/loader.h"
-#include "vm/options.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/methodheader.h"
 #include "vm/jit/intrp/intrp.h"
+#include "vm/jit/dseg.h"
+
+#include "vmcore/class.h"
+#include "vmcore/linker.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+
+#if defined(ENABLE_VMLOG)
+#include <vmlog_cacao.h>
+#endif
 
 
 static bool intrp_asm_vm_call_method_intern(methodinfo *m, s4 vmargscount,
@@ -175,54 +180,130 @@ 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;
+       dseg_exception_entry *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                   =   (dseg_exception_entry *) 
+                                                                                                 (((u1 *) f) + ExTableStart);
+         exceptiontablelength = *((s4 *)             (((u1 *) f) + ExTableSize));
 
 #if !defined(NDEBUG)
          if (opt_verbose || opt_verbosecall || opt_verboseexception)
                  builtin_trace_exception(o, m, ip, 1);
 #endif
 
+#if defined(ENABLE_VMLOG)
+         vmlog_cacao_throw(o);
+#endif
+
          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?    */
 
-                         if (!(c->state & CLASS_LINKED))
-                                 if (!link_class(c))
+                                 global_sp = (Cell *)(((u1 *)fp) - framesize - SIZEOF_VOID_P);
+
+                                 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 &&
-                         (c == NULL || builtin_instanceof(o, c))) {
+                         (c == NULL || builtin_instanceof(o, c))) 
+                 {
+#if defined(ENABLE_VMLOG)
+                         vmlog_cacao_catch(o);
+#endif
+
                          *new_spp = (Cell *)(((u1 *)fp) - framesize - SIZEOF_VOID_P);
                          *new_fpp = fp;
                          return (Inst *) (ex->handlerpc);
                  }
          }
 
+#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 */
+
+#if defined(ENABLE_VMLOG)
+         vmlog_cacao_unwnd_method(m);
+#endif
+
          ip = (Inst *)access_local_cell(-framesize - SIZEOF_VOID_P);
          fp = (Cell *)access_local_cell(-framesize);
   }
@@ -231,21 +312,23 @@ Inst *intrp_asm_handle_exception(Inst *ip, java_objectheader *o, Cell *fp, Cell
 }
 
 
+void intrp_asm_abstractmethoderror(void)
+{
+       vm_abort("intrp_asm_abstractmethoderror: IMPLEMENT ME!");
+}
+
+
 void intrp_asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out)
 {
        s4 sbv, sdv, sv;
 
-#if defined(ENABLE_THREADS)
-       compiler_lock();
-#endif
+       LOCK_MONITOR_ENTER(linker_classrenumber_lock);
 
        sbv = super->baseval;
        sdv = super->diffval;
        sv  = sub->baseval;
 
-#if defined(ENABLE_THREADS)
-       compiler_unlock();
-#endif
+       LOCK_MONITOR_EXIT(linker_classrenumber_lock);
 
        out->super_baseval = sbv;
        out->super_diffval = sdv;
@@ -264,4 +347,5 @@ void intrp_asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */