[kaffe] -O4 jit3 problem
Patrick Tullmann
tullmann@cs.utah.edu
Fri, 14 Jun 2002 18:16:45 -0600
Tim wrote:
> I had a little problem
...
> in exception.h. The "assert(start < end);" needs to be changed to
> "assert(start <= end);" otherwise it will fail if there are no
> instructions between the start_label and end_label. Which seems to
> happen with Kaffe_ExceptionOccurred() and if NEED_JNIREFS isn't
> defined...
Ah, good catch.
I've updated the patch to do per-method native exception handlers to
include Tim's fix, and to hide the GCC-isms behind "#if
defined(__GNUC__)", as Gwenole Beauchesne pointed out.
Note that with this patch, jni.c will *fail to compile* with an
"#error" if its not being compiled with GCC. Looking at the sources,
there is currently a lot of GCC-specific code (mostly asm's) in Kaffe.
However, all of that stuff is kept off in the config/ tree, so the
core of the VM is actually free of GCC-isms (I think).
Is this a problem if Kaffe requires GCC? Anyone out there compile
Kaffe with a non-gcc compiler?
Note that the there is still a problem with intern'd strings and dead
value arrays. (This patch tickles things just right so that InternHog
in the intrp+debug version will fail.) At this point, I'm quite
confident that that is a separate bug, and that Tim's suggestion to
gcAddRef/gcRemRef on the underlying char array will at least fix the
crashes. But that will be a separate patch.
Anywhere, here is the latest patch. And a ChangeLog entry:
Patrick Tullmann <pat@tullmann.org>
* kaffe/kaffevm/classMethod.c: Compile methodNeedsTrampoline()
in JIT only.
* kaffe/kaffevm/exception.h: Replace VMException struct
with VMExceptHandler, add accessors,
* kaffe/kaffevm/exception.c: Use new VMExceptHandler struct in
place of VMException, update test to see if a JNI handler is
installed when dispatching exceptions
* kaffe/kaffevm/intrp/machine.c: Use new VMExceptHandler and
accessors
* kaffe/kaffevm/jni.c: Use label-addresses to provide
exception handler coverage for JNI entrypoints.
* kaffe/kaffevm/kaffe_jni.h: New header JNI entrypoints used
elsewhere in kaffevm.
* kaffe/kaffevm/stackTrace.h: Use new VMExceptHandler.
* kaffe/kaffevm/support.c: Use new VMExceptHandler.
-Pat
----- ----- ---- --- --- -- - - - - -
Pat Tullmann tullmann@cs.utah.edu
Indifference may cause the downfall of mankind, but who really cares?
diff -u -r -N --exclude=CVS --exclude=.* --exclude=DEAD --exclude=Makefile.in --exclude=configure pure/kaffe/kaffevm/classMethod.c optjit/kaffe/kaffevm/classMethod.c
--- pure/kaffe/kaffevm/classMethod.c Wed May 29 16:58:43 2002
+++ optjit/kaffe/kaffevm/classMethod.c Mon Jun 3 20:25:58 2002
@@ -1559,6 +1559,7 @@
return true;
}
+#if defined(TRANSLATOR)
/*
* When do we need a trampoline?
*
@@ -1604,6 +1605,9 @@
}
return (false);
}
+#endif /* TRANSLATOR */
+
+
/*
* Build a trampoline if necessary, return the address of the native code
diff -u -r -N --exclude=CVS --exclude=.* --exclude=DEAD --exclude=Makefile.in --exclude=configure pure/kaffe/kaffevm/exception.c optjit/kaffe/kaffevm/exception.c
--- pure/kaffe/kaffevm/exception.c Wed May 29 13:46:24 2002
+++ optjit/kaffe/kaffevm/exception.c Mon Jun 3 22:57:20 2002
@@ -37,6 +37,7 @@
#include "machine.h"
#include "slots.h"
#include "gcj/gcj.h"
+#include "kaffe_jni.h"
#if defined(INTERPRETER)
#define FIRSTFRAME(f, e) /* Does nothing */
@@ -48,8 +49,6 @@
static void floatingException(struct _exceptionFrame *);
static void dispatchException(Hjava_lang_Throwable*, stackTraceInfo*) __NORETURN__;
-extern void Kaffe_JNIExceptionHandler(void);
-
extern void printStackTrace(struct Hjava_lang_Throwable*, struct Hjava_lang_Object*, int);
static bool findExceptionBlockInMethod(uintp, Hjava_lang_Class*, Method*, exceptionInfo*);
@@ -297,9 +296,9 @@
return (0);
}
#endif
-#else
- vmException* nfm;
- nfm = ((vmException*)fm)->prev;
+#else /* INTERPRETER */
+ VmExceptHandler* nfm;
+ nfm = ((VmExceptHandler*)fm)->prev;
return (nfm);
#endif
}
@@ -330,8 +329,22 @@
meth = findExceptionInMethod(frame->pc, class, &einfo);
- if (einfo.method == 0 && IS_IN_JNI_RANGE(frame->pc)) {
- Kaffe_JNIExceptionHandler();
+ assert(meth == einfo.method);
+
+ /*
+ * If no exception block found in method, perhaps
+ * it is a Kaffe_JNI entrypoint?
+ */
+ if (einfo.method == 0)
+ {
+ VmExceptHandler* ebuf = (VmExceptHandler*)(unhand(getCurrentThread())->exceptPtr);
+ if ((ebuf != 0)
+ && vmExcept_isJNIFrame(ebuf)
+ && vmExcept_JNIContains(ebuf, frame->pc))
+ {
+ /* Does not return. */
+ Kaffe_JNIExceptionHandler(ebuf);
+ }
}
/* Find the sync. object */
@@ -404,18 +417,21 @@
{
Hjava_lang_Object* obj;
exceptionInfo einfo;
- vmException* frame;
+ VmExceptHandler* frame;
bool res;
- for (frame = (vmException*)unhand(ct)->exceptPtr; frame != 0; frame = frame->prev) {
+ for (frame = (VmExceptHandler*)unhand(ct)->exceptPtr; frame != 0; frame = frame->prev) {
- if (frame->meth == (Method*)1) {
+ if (vmExcept_isJNIFrame(frame)) {
unhand(ct)->exceptPtr = (struct Hkaffe_util_Ptr*)frame;
- Kaffe_JNIExceptionHandler();
+ Kaffe_JNIExceptionHandler(frame); /* No Return */
}
/* Look for handler */
- res = findExceptionBlockInMethod(frame->pc, eobj->base.dtable->class, frame->meth, &einfo);
+ res = findExceptionBlockInMethod(frame->frame.intrp.pc,
+ eobj->base.dtable->class,
+ frame->meth,
+ &einfo);
/* Find the sync. object */
if (einfo.method == 0 || (einfo.method->accflags & ACC_SYNCHRONISED) == 0) {
@@ -425,14 +441,14 @@
obj = &einfo.class->head;
}
else {
- obj = frame->mobj;
+ obj = vmExcept_getSyncobj(frame);
}
/* If handler found, call it */
if (res == true) {
unhand(ct)->needOnStack = STACK_HIGH;
- frame->pc = einfo.handler;
- JTHREAD_LONGJMP(JTHREAD_ACCESS_JMPBUF(frame, jbuf), 1);
+ vmExcept_setPC(frame, einfo.handler);
+ vmExcept_jumpToHandler(frame); /* Does not return */
}
/* If not here, exit monitor if synchronised. */
@@ -569,6 +585,9 @@
/*
* Look for exception block in method.
* Returns true if there is an exception handler, false otherwise.
+ *
+ * Passed 'pc' is the program counter where the exception entered
+ * the current frame (the 'throw' or from a nested method call).
*/
static bool
findExceptionBlockInMethod(uintp pc, Hjava_lang_Class* class, Method* ptr, exceptionInfo* info)
diff -u -r -N --exclude=CVS --exclude=.* --exclude=DEAD --exclude=Makefile.in --exclude=configure pure/kaffe/kaffevm/exception.h optjit/kaffe/kaffevm/exception.h
--- pure/kaffe/kaffevm/exception.h Wed May 29 13:46:24 2002
+++ optjit/kaffe/kaffevm/exception.h Mon Jun 10 12:32:44 2002
@@ -13,6 +13,23 @@
#include "config-setjmp.h"
+/*
+ * Values for Thread.needOnStack. This variable
+ * says how many bytes need to be left on the stack when entering a function
+ * call. When throwing a StackOverflowException, this variable is set to
+ * STACK_LOW to have enough space to create the StackOverflowError --- if
+ * the error is caught, we set it back to STACK_HIGH.
+ */
+#define STACK_HIGH (8*1024)
+#define STACK_LOW 256
+
+/* XXX Why is this here? Its duplicated in a number of places. */
+#if defined(__WIN32__)
+#define SIG_T void(*)()
+#else
+#define SIG_T void*
+#endif
+
struct _exceptionFrame;
struct Hjava_lang_Class;
struct Hjava_lang_Object;
@@ -36,13 +53,46 @@
jexceptionEntry entry[1];
} jexception;
-typedef struct _vmException {
- struct _vmException* prev;
- JTHREAD_DECLARE_JMPBUF (jbuf);
+/*
+ * A VmExceptHandle is used to handle *any* exception in native code
+ * in the core of the VM. Set up when entering Kaffe_JNI methods, or
+ * when callMethodA or callMethodV are invoked.
+ *
+ * Each thread in the system has a exceptPtr, which points
+ * to the most recent VmExceptHandler buffer (the buffers
+ * are chained throught the 'prev' field.)
+ *
+ * In the interpreter *every frame* has a VmExceptHandler
+ * associated with it, this is used for catching exceptions at
+ * each interpreter stack frame and unlocking synchronized
+ * objects if necessary.
+ */
+typedef struct VmExceptHandler {
+ struct VmExceptHandler* prev;
struct _methods* meth;
- u4 pc;
- struct Hjava_lang_Object* mobj;
-} vmException;
+ union
+ {
+ /* Only valid if meth == VMEXCEPTHANDLER_KAFFEJNI_HANDLER */
+ struct
+ {
+ const void* start;
+ const void* end;
+ } jni;
+ /*
+ * Only valid if meth != 0 && meth != VMEXCEPTHANDLER_KAFFEJNI_HANDLER
+ *
+ * XXX Only used in the interpreter...
+ */
+ struct
+ {
+ struct Hjava_lang_Object* syncobj;
+ u4 pc;
+ } intrp;
+ } frame;
+ JTHREAD_DECLARE_JMPBUF (jbuf);
+} VmExceptHandler;
+
+#define VMEXCEPTHANDLER_KAFFEJNI_HANDLER ((struct _methods*)1)
struct _exceptionFrame;
@@ -56,26 +106,118 @@
struct Hjava_lang_Throwable *eobj);
void unhandledException(struct Hjava_lang_Throwable *eobj) __NORETURN__;
-extern uintp Kaffe_JNI_estart;
-extern uintp Kaffe_JNI_eend;
-#define IS_IN_JNI_RANGE(pc) ((pc) >= Kaffe_JNI_estart && (pc) < Kaffe_JNI_eend)
-
extern void initExceptions(void);
-#if defined(__WIN32__)
-#define SIG_T void(*)()
-#else
-#define SIG_T void*
+static inline bool vmExcept_isJNIFrame(VmExceptHandler* eh) __UNUSED__;
+static inline bool vmExcept_JNIContains(VmExceptHandler* eh, void *pc) __UNUSED__;
+static inline void vmExcept_setJNIFrame(VmExceptHandler* eh, const void* start, const void* end) __UNUSED__;
+static inline struct _methods* vmExcept_getMeth(VmExceptHandler* eh) __UNUSED__;
+static inline void vmExcept_setMeth(VmExceptHandler* eh, struct _methods* m) __UNUSED__;
+static inline void vmExcept_setSyncobj(VmExceptHandler* eh, struct Hjava_lang_Object* syncobj) __UNUSED__;
+static inline struct Hjava_lang_Object* vmExcept_getSyncobj(VmExceptHandler* eh) __UNUSED__;
+static inline void vmExcept_setPC(volatile VmExceptHandler* eh, u4 pc) __UNUSED__;
+static inline u4 vmExcept_getPC(const VmExceptHandler* eh) __UNUSED__;
+static inline void vmExcept_jumpToHandler(VmExceptHandler* frame) __UNUSED__ __NORETURN__;
+
+static inline bool
+vmExcept_isJNIFrame(VmExceptHandler* eh)
+{
+ assert(eh);
+ return (eh->meth == VMEXCEPTHANDLER_KAFFEJNI_HANDLER);
+}
+
+static inline bool
+vmExcept_JNIContains(VmExceptHandler* eh, void *pc)
+{
+ assert(eh);
+ assert(eh->meth == VMEXCEPTHANDLER_KAFFEJNI_HANDLER);
+ assert(pc);
+
+ return (eh->frame.jni.start <= pc)
+ && (eh->frame.jni.end > pc);
+}
+
+static inline void
+vmExcept_jumpToHandler(VmExceptHandler* frame)
+{
+ JTHREAD_LONGJMP(JTHREAD_ACCESS_JMPBUF(frame, jbuf), 1);
+}
+
+static inline void
+vmExcept_setJNIFrame(VmExceptHandler* eh, const void* start, const void* end)
+{
+ assert(eh);
+ assert(start != 0);
+ assert(start <= end);
+
+ eh->meth = VMEXCEPTHANDLER_KAFFEJNI_HANDLER;
+ eh->frame.jni.start = start;
+ eh->frame.jni.end = end;
+}
+
+static inline void
+vmExcept_setIntrpFrame(VmExceptHandler* eh, u4 pc, struct _methods* meth, struct Hjava_lang_Object* syncobj)
+{
+ assert(eh);
+ assert(meth);
+
+ eh->meth = meth;
+ eh->frame.intrp.pc = pc;
+ eh->frame.intrp.syncobj = syncobj;
+}
+
+static inline void
+vmExcept_setSyncobj(VmExceptHandler* eh, struct Hjava_lang_Object* syncobj)
+{
+ assert(eh);
+ assert(eh->meth != 0);
+ assert(eh->meth != VMEXCEPTHANDLER_KAFFEJNI_HANDLER);
+ eh->frame.intrp.syncobj = syncobj;
+}
+
+static inline struct Hjava_lang_Object*
+vmExcept_getSyncobj(VmExceptHandler* eh)
+{
+ assert(eh);
+ assert(eh->meth != 0);
+ assert(eh->meth != VMEXCEPTHANDLER_KAFFEJNI_HANDLER);
+ return eh->frame.intrp.syncobj;
+}
+
+static inline void
+vmExcept_setMeth(VmExceptHandler* eh, struct _methods* meth)
+{
+ assert(eh);
+ assert(meth);
+ eh->meth = meth;
+}
+
+static inline struct _methods*
+vmExcept_getMeth(VmExceptHandler* eh)
+{
+ assert(eh);
+ return eh->meth;
+}
+
+static inline void
+vmExcept_setPC(volatile VmExceptHandler* eh, u4 pc)
+{
+ assert(eh);
+ assert(eh->meth != 0);
+ assert(eh->meth != VMEXCEPTHANDLER_KAFFEJNI_HANDLER);
+ eh->frame.intrp.pc = pc;
+}
+
+static inline u4
+vmExcept_getPC(const VmExceptHandler* eh)
+{
+ assert(eh);
+ assert(eh->meth != 0);
+ assert(eh->meth != VMEXCEPTHANDLER_KAFFEJNI_HANDLER);
+ return eh->frame.intrp.pc;
+}
+
#endif
-/*
- * Values for Thread.needOnStack. This variable
- * says how many bytes need to be left on the stack when entering a function
- * call. When throwing a StackOverflowException, this variable is set to
- * STACK_LOW to have enough space to create the StackOverflowError --- if
- * the error is caught, we set it back to STACK_HIGH.
- */
-#define STACK_HIGH (8*1024)
-#define STACK_LOW 256
-#endif
+
diff -u -r -N --exclude=CVS --exclude=.* --exclude=DEAD --exclude=Makefile.in --exclude=configure pure/kaffe/kaffevm/intrp/machine.c optjit/kaffe/kaffevm/intrp/machine.c
--- pure/kaffe/kaffevm/intrp/machine.c Sun Jun 17 10:39:34 2001
+++ optjit/kaffe/kaffevm/intrp/machine.c Mon Jun 3 21:09:05 2002
@@ -84,14 +84,14 @@
int profFlag; /* flag to control profiling */
#endif
-void runVirtualMachine(methods *meth, slots *lcl, slots *sp, uintp npc, slots *retval, volatile vmException *mjbuf, Hjava_lang_Thread *tid);
+void runVirtualMachine(methods *meth, slots *lcl, slots *sp, uintp npc, slots *retval, volatile VmExceptHandler *mjbuf, Hjava_lang_Thread *tid);
void
virtualMachine(methods*volatile meth, slots* volatile arg, slots* volatile retval, Hjava_lang_Thread* volatile tid)
{
methods *volatile const vmeth = meth;
Hjava_lang_Object* volatile mobj;
- vmException mjbuf;
+ VmExceptHandler mjbuf;
accessFlags methaccflags;
slots* volatile lcl;
@@ -168,11 +168,9 @@
/* If we have any exception handlers we must prepare to catch them.
* We also need to catch if we are synchronised (so we can release it).
*/
- mjbuf.pc = 0;
- mjbuf.mobj = mobj;
- mjbuf.meth = meth;
+ vmExcept_setIntrpFrame(&mjbuf, 0, meth, mobj);
if (tid != NULL && unhand(tid)->PrivateInfo != 0) {
- mjbuf.prev = (vmException*)unhand(tid)->exceptPtr;
+ mjbuf.prev = (VmExceptHandler*)unhand(tid)->exceptPtr;
unhand(tid)->exceptPtr = (struct Hkaffe_util_Ptr*)&mjbuf;
}
@@ -180,7 +178,7 @@
if (JTHREAD_SETJMP(mjbuf.jbuf) != 0) {
meth = vmeth;
unhand(tid)->exceptPtr = (struct Hkaffe_util_Ptr*)&mjbuf;
- npc = mjbuf.pc;
+ npc = vmExcept_getPC(&mjbuf);
sp = &lcl[meth->localsz];
#if defined(DEBUG)
{
@@ -219,11 +217,13 @@
}
/* this lock is safe for Thread.stop() */
lockObject(mobj);
- /* We must store the object on which we synchronized in
- * the mjbuf chain or else the exception handler routine
- * won't find it.
+
+ /*
+ * We must store the object on which we synchronized
+ * in the mjbuf chain for the exception handler
+ * routine to find it (and unlock it when unwinding).
*/
- mjbuf.mobj = mobj;
+ vmExcept_setSyncobj(&mjbuf, mobj);
}
sp = &lcl[meth->localsz - 1];
@@ -242,7 +242,7 @@
RDBG( dprintf("Returning from method %s%s.\n", meth->name->data, METHOD_SIGD(meth)); )
}
-void runVirtualMachine(methods *meth, slots *lcl, slots *sp, uintp npc, slots *retval, volatile vmException *mjbuf, Hjava_lang_Thread *tid) {
+void runVirtualMachine(methods *meth, slots *lcl, slots *sp, uintp npc, slots *retval, volatile VmExceptHandler *mjbuf, Hjava_lang_Thread *tid) {
bytecode *code = (bytecode*)meth->c.bcode.code;
/* Misc machine variables */
@@ -268,7 +268,7 @@
register uintp pc = npc;
assert(npc < meth->c.bcode.codelen);
- mjbuf->pc = pc;
+ vmExcept_setPC(mjbuf, pc);
npc = pc + insnLen[code[pc]];
switch (code[pc]) {
diff -u -r -N --exclude=CVS --exclude=.* --exclude=DEAD --exclude=Makefile.in --exclude=configure pure/kaffe/kaffevm/jni.c optjit/kaffe/kaffevm/jni.c
--- pure/kaffe/kaffevm/jni.c Wed May 29 16:58:44 2002
+++ optjit/kaffe/kaffevm/jni.c Tue Jun 4 03:04:53 2002
@@ -47,6 +47,7 @@
#include "machine.h"
#include "feedback.h"
#endif
+#include "kaffe_jni.h"
/*
* Define the version of JNI we support.
@@ -80,34 +81,50 @@
*/
#define JNI_METHOD_CODE(M) METHOD_INDIRECTMETHOD(M)
+#if defined(__GNUC__)
+/*
+ * Yes, that's a unary "&&" to get the address of a label. See:
+ * http://gcc.gnu.org/onlinedocs/gcc/Local-Labels.html#Local%20Labels
+ * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html#Labels%20as%20Values
+ */
+#define LABEL_ADDR(x) (&&x)
+#else
+#error LABEL_ADDR Taking the address of a label is a GCC-extension to C
+#endif
+
/*
* Define how we handle exceptions in JNI.
*
- * XXX variable declarations in macros are nasty.
+ * Each BEGIN_EXCEPTION_HANDLING macro must be matched by an
+ * END_EXCEPTION_HANDLING macro call in the same scope. Each should
+ * be used only once in a given JNI entrypoint.
*/
#define BEGIN_EXCEPTION_HANDLING(X) \
- vmException ebuf; \
- ebuf.prev = (vmException*)unhand(getCurrentThread())->exceptPtr;\
- ebuf.meth = (Method*)1; \
- if (JTHREAD_SETJMP(ebuf.jbuf) != 0) { \
+ VmExceptHandler ebuf; \
+ vmExcept_setJNIFrame(&ebuf, LABEL_ADDR(start_label), LABEL_ADDR(end_label)); \
+ ebuf.prev = (VmExceptHandler*)(unhand(getCurrentThread())->exceptPtr);\
+ if (JTHREAD_SETJMP(JTHREAD_ACCESS_JMPBUF(&ebuf, jbuf)) != 0) { \
unhand(getCurrentThread())->exceptPtr = \
(struct Hkaffe_util_Ptr*)ebuf.prev; \
return X; \
} \
+ start_label: \
unhand(getCurrentThread())->exceptPtr = (struct Hkaffe_util_Ptr*)&ebuf
#define BEGIN_EXCEPTION_HANDLING_VOID() \
- vmException ebuf; \
- ebuf.prev = (vmException*)unhand(getCurrentThread())->exceptPtr;\
- ebuf.meth = (Method*)1; \
- if (JTHREAD_SETJMP(ebuf.jbuf) != 0) { \
+ VmExceptHandler ebuf; \
+ vmExcept_setJNIFrame(&ebuf, LABEL_ADDR(start_label), LABEL_ADDR(end_label)); \
+ ebuf.prev = (VmExceptHandler*)(unhand(getCurrentThread())->exceptPtr);\
+ if (JTHREAD_SETJMP(JTHREAD_ACCESS_JMPBUF(&ebuf, jbuf)) != 0) { \
unhand(getCurrentThread())->exceptPtr = \
(struct Hkaffe_util_Ptr*)ebuf.prev; \
return; \
} \
+ start_label: \
unhand(getCurrentThread())->exceptPtr = (struct Hkaffe_util_Ptr*)&ebuf
#define END_EXCEPTION_HANDLING() \
+ end_label: \
unhand(getCurrentThread())->exceptPtr = (struct Hkaffe_util_Ptr*)ebuf.prev
/*
@@ -118,9 +135,6 @@
#define GET_STATIC_FIELD(T,F) *(T*)FIELD_ADDRESS((Field*)F)
#define SET_STATIC_FIELD(T,F,V) *(T*)FIELD_ADDRESS((Field*)F) = (V)
-uintp Kaffe_JNI_estart;
-uintp Kaffe_JNI_eend;
-
extern struct JNINativeInterface Kaffe_JNINativeInterface;
extern JavaVMInitArgs Kaffe_JavaVMInitArgs;
extern JavaVM Kaffe_JavaVM;
@@ -133,7 +147,6 @@
static void Kaffe_wrapper(Method* xmeth, void* func, bool use_JNI);
#endif
-void Kaffe_JNIExceptionHandler(void);
static jint Kaffe_GetVersion(JNIEnv*);
static jclass Kaffe_FindClass(JNIEnv*, const char*);
static jint Kaffe_ThrowNew(JNIEnv*, jclass, const char*);
@@ -166,10 +179,6 @@
Kaffe_JavaVMArgs[0] = *args;
initialiseKaffe();
- /* Setup the JNI Exception handler */
- Kaffe_JNI_estart = (uintp)&Kaffe_GetVersion; /* First routine */
- Kaffe_JNI_eend = (uintp)&Kaffe_JNIExceptionHandler; /* Last routine */
-
/* Setup JNI for main thread */
#if defined(NEED_JNIREFS)
unhand(getCurrentThread())->jnireferences = gc_malloc(sizeof(jnirefs), &gcNormal);
@@ -198,8 +207,6 @@
*
* Everything from Kaffe_GetVersion to Kaffe_JNIExceptionHandler
* should be bracketed with BEGIN and END _EXCEPTION_HANDLING.
- * Question: what happens when an asynchronous exception occurs at the
- * very start or end of one of these calls.
*/
static void
Kaffe_FatalError(JNIEnv* env, const char* mess)
@@ -3493,18 +3500,10 @@
* Handle exceptions which fall back to the JNI layer.
*/
void
-Kaffe_JNIExceptionHandler(void)
+Kaffe_JNIExceptionHandler(VmExceptHandler* frame)
{
- vmException* frame;
-
- frame = (vmException*)unhand(getCurrentThread())->exceptPtr;
- if (frame) {
- /* Worry about window around BEGIN and END exception
- * handling, as well as functions which only delay
- * external exceptions.
- */
- JTHREAD_LONGJMP(JTHREAD_ACCESS_JMPBUF(frame, jbuf), 1);
- }
+ assert(frame != 0);
+ vmExcept_jumpToHandler(frame);
}
/*
diff -u -r -N --exclude=CVS --exclude=.* --exclude=DEAD --exclude=Makefile.in --exclude=configure pure/kaffe/kaffevm/kaffe_jni.h optjit/kaffe/kaffevm/kaffe_jni.h
--- pure/kaffe/kaffevm/kaffe_jni.h Wed Dec 31 17:00:00 1969
+++ optjit/kaffe/kaffevm/kaffe_jni.h Mon Jun 3 20:44:20 2002
@@ -0,0 +1,21 @@
+/*
+ * kaffe_jni.h
+ * Prototypes for jni.c methods used elsewhere
+ *
+ * Copyright (c) 2002
+ * Pat Tullmann <pat@tullmann.org>. All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file.
+ */
+
+#ifndef KAFFE_KAFFEVM_KAFFE_JNI_H
+#define KAFFE_KAFFEVM_KAFFE_JNI_H
+
+#include "config.h"
+
+struct VmExceptHandler; /* exception.h */
+
+extern void Kaffe_JNIExceptionHandler(struct VmExceptHandler* handler) __NORETURN__;
+
+#endif /* KAFFE_KAFFEVM_KAFFE_JNI_H */
diff -u -r -N --exclude=CVS --exclude=.* --exclude=DEAD --exclude=Makefile.in --exclude=configure pure/kaffe/kaffevm/stackTrace.h optjit/kaffe/kaffevm/stackTrace.h
--- pure/kaffe/kaffevm/stackTrace.h Fri Jun 16 11:47:13 2000
+++ optjit/kaffe/kaffevm/stackTrace.h Mon Jun 3 22:46:48 2002
@@ -26,7 +26,7 @@
#if defined(INTERPRETER)
typedef struct _stackTrace {
- vmException* frame;
+ VmExceptHandler* frame;
} stackTrace;
/* Dummy exceptionFrame */
@@ -34,13 +34,13 @@
char dummy;
};
-#define STACKTRACEINIT(S,I,O,R) ((S).frame = (vmException*)unhand(getCurrentThread())->exceptPtr)
+#define STACKTRACEINIT(S,I,O,R) ((S).frame = (VmExceptHandler*)unhand(getCurrentThread())->exceptPtr)
#define STACKTRACESTEP(S) ((S).frame = nextFrame((S).frame))
-#define STACKTRACEPC(S) ((S).frame->pc)
+#define STACKTRACEPC(S) (vmExcept_getPC((S).frame))
#define STACKTRACEFP(S) (0)
-#define STACKTRACEMETHCREATE(S) ((S).frame->meth)
+#define STACKTRACEMETHCREATE(S) (vmExcept_getMeth((S).frame))
#define STACKTRACEEND(S) ((S).frame == 0)
-#define STACKTRACESKIP(S) ((S).frame->meth == (Method*)1)
+#define STACKTRACESKIP(S) (vmExcept_isJNIFrame((S).frame))
#elif defined(TRANSLATOR)
diff -u -r -N --exclude=CVS --exclude=.* --exclude=DEAD --exclude=Makefile.in --exclude=configure pure/kaffe/kaffevm/support.c optjit/kaffe/kaffevm/support.c
--- pure/kaffe/kaffevm/support.c Wed May 29 16:58:44 2002
+++ optjit/kaffe/kaffevm/support.c Mon Jun 3 21:07:17 2002
@@ -529,7 +529,7 @@
}
else {
Hjava_lang_Object* syncobj = 0;
- vmException mjbuf;
+ VmExceptHandler mjbuf;
Hjava_lang_Thread* tid = getCurrentThread();
if (meth->accflags & ACC_SYNCHRONISED) {
@@ -542,11 +542,9 @@
lockObject(syncobj);
}
- mjbuf.pc = 0;
- mjbuf.mobj = syncobj;
- mjbuf.meth = meth;
+ vmExcept_setIntrpFrame(&mjbuf, 0, meth, syncobj);
if (tid != NULL && unhand(tid)->PrivateInfo != 0) {
- mjbuf.prev = (vmException*)unhand(tid)->exceptPtr;
+ mjbuf.prev = (VmExceptHandler*)unhand(tid)->exceptPtr;
unhand(tid)->exceptPtr = (struct Hkaffe_util_Ptr*)&mjbuf;
}
@@ -747,7 +745,7 @@
}
else {
Hjava_lang_Object* syncobj = 0;
- vmException mjbuf;
+ VmExceptHandler mjbuf;
Hjava_lang_Thread* tid = getCurrentThread();
if (meth->accflags & ACC_SYNCHRONISED) {
@@ -760,11 +758,9 @@
lockObject(syncobj);
}
- mjbuf.pc = 0;
- mjbuf.mobj = syncobj;
- mjbuf.meth = meth;
+ vmExcept_setIntrpFrame(&mjbuf, 0, meth, syncobj);
if (tid != NULL && unhand(tid)->PrivateInfo != 0) {
- mjbuf.prev = (vmException*)unhand(tid)->exceptPtr;
+ mjbuf.prev = (VmExceptHandler*)unhand(tid)->exceptPtr;
unhand(tid)->exceptPtr = (struct Hkaffe_util_Ptr*)&mjbuf;
}