/* 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,
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);
}
}
+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;
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/