* Removed all Id tags.
[cacao.git] / src / vm / jit / intrp / asmpart.c
index 05ce77d4aad34e0bdd1e123b6ff970b2d8145c7e..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 4856 2006-04-28 00:46:39Z 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,53 +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 */
 
-         methodinfo *m = *(methodinfo **) (((u1 *) f) + MethodPointer);
+         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);
   }
@@ -230,29 +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(USE_THREADS)
-#if defined(NATIVE_THREADS)
-       compiler_lock();
-#else
-       intsDisable();
-#endif
-#endif
+       LOCK_MONITOR_ENTER(linker_classrenumber_lock);
 
        sbv = super->baseval;
        sdv = super->diffval;
        sv  = sub->baseval;
 
-#if defined(USE_THREADS)
-#if defined(NATIVE_THREADS)
-       compiler_unlock();
-#else
-       intsRestore();
-#endif
-#endif
+       LOCK_MONITOR_EXIT(linker_classrenumber_lock);
 
        out->super_baseval = sbv;
        out->super_diffval = sdv;
@@ -271,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:
  */