aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Seitz <keiths@redhat.com>2007-05-04 01:04:11 +0000
committerKeith Seitz <kseitz@gcc.gnu.org>2007-05-04 01:04:11 +0000
commitbefd756626fa71b89c1cd6563d97c968618103f4 (patch)
treea8f4058c8d5dc274f095fb50893c2f74cfe875a2
parent820b51ae16ab41233ef12a8918df61937cfdd8b4 (diff)
downloadgcc-befd756626fa71b89c1cd6563d97c968618103f4.zip
gcc-befd756626fa71b89c1cd6563d97c968618103f4.tar.gz
gcc-befd756626fa71b89c1cd6563d97c968618103f4.tar.bz2
jvmti-int.h (_Jv_ReportJVMTIExceptionThrow): Declare.
* include/jvmti-int.h (_Jv_ReportJVMTIExceptionThrow): Declare. * interpret.cc (_Jv_ReportJVMTIExceptionThrow): New function. (find_catch_location): New function. (REPORT_EXCEPTION): New macro. (throw_internal_error): Use REPORT_EXCEPTION. (throw_incompatible_class_change_error): Likewise. (throw_null_pointer_exception): Likewise. (throw_class_format_error): Likewise. * interpret-run.cc (INTERP_REPORT_EXCEPTION)[DEBUG]: Set to REPORT_EXCEPTION. (INTERP_REPORT_EXCEPTION)[!DEBUG]: Make nop. (insn_new): Use INTERP_REPORT_EXCEPTION. (insn_athrow): Likewise. Remove previous JVMTI exception notifications. Add JVMTI ExceptionCatch notificatin. * jni.cc (_Jv_PopSystemFrame): Notify JVMTI clients of exception throw. * gnu/gcj/jvmti/ExceptionEvent.java: Removed. * gnu/gcj/jvmti/ExceptionEvent.h: Removed. * classpath/lib/gnu/gcj/jvmti/ExceptionEvent.class: Removed. * gnu/classpath/jdwp/natVMVirtualMachine.cc (jdwpExceptionCB): New function. (jdwpVMInitCB): Set Exception event handler and enable. * sources.am: Regenerated. * Makefile.in: Regenerated. From-SVN: r124406
-rw-r--r--libjava/ChangeLog29
-rw-r--r--libjava/Makefile.in1
-rw-r--r--libjava/classpath/lib/gnu/gcj/jvmti/ExceptionEvent.classbin1534 -> 0 bytes
-rw-r--r--libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc57
-rw-r--r--libjava/gnu/gcj/jvmti/ExceptionEvent.h44
-rw-r--r--libjava/gnu/gcj/jvmti/ExceptionEvent.java96
-rw-r--r--libjava/include/jvmti-int.h2
-rw-r--r--libjava/interpret-run.cc43
-rw-r--r--libjava/interpret.cc91
-rw-r--r--libjava/jni.cc3
-rw-r--r--libjava/sources.am1
11 files changed, 198 insertions, 169 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 9607a3d..ccaf00b 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,32 @@
+2007-05-03 Keith Seitz <keiths@redhat.com>
+
+ * include/jvmti-int.h (_Jv_ReportJVMTIExceptionThrow):
+ Declare.
+ * interpret.cc (_Jv_ReportJVMTIExceptionThrow): New function.
+ (find_catch_location): New function.
+ (REPORT_EXCEPTION): New macro.
+ (throw_internal_error): Use REPORT_EXCEPTION.
+ (throw_incompatible_class_change_error): Likewise.
+ (throw_null_pointer_exception): Likewise.
+ (throw_class_format_error): Likewise.
+ * interpret-run.cc (INTERP_REPORT_EXCEPTION)[DEBUG]: Set
+ to REPORT_EXCEPTION.
+ (INTERP_REPORT_EXCEPTION)[!DEBUG]: Make nop.
+ (insn_new): Use INTERP_REPORT_EXCEPTION.
+ (insn_athrow): Likewise.
+ Remove previous JVMTI exception notifications.
+ Add JVMTI ExceptionCatch notificatin.
+ * jni.cc (_Jv_PopSystemFrame): Notify JVMTI clients of
+ exception throw.
+ * gnu/gcj/jvmti/ExceptionEvent.java: Removed.
+ * gnu/gcj/jvmti/ExceptionEvent.h: Removed.
+ * classpath/lib/gnu/gcj/jvmti/ExceptionEvent.class: Removed.
+ * gnu/classpath/jdwp/natVMVirtualMachine.cc
+ (jdwpExceptionCB): New function.
+ (jdwpVMInitCB): Set Exception event handler and enable.
+ * sources.am: Regenerated.
+ * Makefile.in: Regenerated.
+
2007-05-03 Thomas Fitzsimmons <fitzsim@redhat.com>
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=237304
diff --git a/libjava/Makefile.in b/libjava/Makefile.in
index 369c191..48ae71b3 100644
--- a/libjava/Makefile.in
+++ b/libjava/Makefile.in
@@ -1349,7 +1349,6 @@ gnu_gcj_io_header_files = $(patsubst %.java,%.h,$(gnu_gcj_io_source_files))
gnu_gcj_jvmti_source_files = \
gnu/gcj/jvmti/Breakpoint.java \
gnu/gcj/jvmti/BreakpointManager.java \
-gnu/gcj/jvmti/ExceptionEvent.java \
gnu/gcj/jvmti/Location.java
gnu_gcj_jvmti_header_files = $(patsubst %.java,%.h,$(gnu_gcj_jvmti_source_files))
diff --git a/libjava/classpath/lib/gnu/gcj/jvmti/ExceptionEvent.class b/libjava/classpath/lib/gnu/gcj/jvmti/ExceptionEvent.class
deleted file mode 100644
index bfdedd0..0000000
--- a/libjava/classpath/lib/gnu/gcj/jvmti/ExceptionEvent.class
+++ /dev/null
Binary files differ
diff --git a/libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc b/libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc
index 1dfc529..d6edf34 100644
--- a/libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc
+++ b/libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc
@@ -21,6 +21,7 @@ details. */
#include <java/lang/String.h>
#include <java/lang/StringBuilder.h>
#include <java/lang/Thread.h>
+#include <java/lang/Throwable.h>
#include <java/nio/ByteBuffer.h>
#include <java/nio/ByteBufferImpl.h>
#include <java/util/ArrayList.h>
@@ -37,6 +38,7 @@ details. */
#include <gnu/classpath/jdwp/VMVirtualMachine.h>
#include <gnu/classpath/jdwp/event/BreakpointEvent.h>
#include <gnu/classpath/jdwp/event/ClassPrepareEvent.h>
+#include <gnu/classpath/jdwp/event/ExceptionEvent.h>
#include <gnu/classpath/jdwp/event/EventManager.h>
#include <gnu/classpath/jdwp/event/EventRequest.h>
#include <gnu/classpath/jdwp/event/SingleStepEvent.h>
@@ -82,6 +84,9 @@ static void handle_single_step (jvmtiEnv *, struct step_info *, jthread,
static void JNICALL jdwpBreakpointCB (jvmtiEnv *, JNIEnv *, jthread,
jmethodID, jlocation);
static void JNICALL jdwpClassPrepareCB (jvmtiEnv *, JNIEnv *, jthread, jclass);
+static void JNICALL jdwpExceptionCB (jvmtiEnv *, JNIEnv *jni_env, jthread,
+ jmethodID, jlocation, jobject,
+ jmethodID, jlocation);
static void JNICALL jdwpSingleStepCB (jvmtiEnv *, JNIEnv *, jthread,
jmethodID, jlocation);
static void JNICALL jdwpThreadEndCB (jvmtiEnv *, JNIEnv *, jthread);
@@ -933,6 +938,56 @@ jdwpClassPrepareCB (MAYBE_UNUSED jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env,
}
static void JNICALL
+jdwpExceptionCB (jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env, jthread thread,
+ jmethodID method, jlocation location, jobject exception,
+ jmethodID catch_method, jlocation catch_location)
+{
+ using namespace gnu::classpath::jdwp;
+ jclass throw_klass;
+ jvmtiError err = env->GetMethodDeclaringClass (method, &throw_klass);
+ if (err != JVMTI_ERROR_NONE)
+ {
+ fprintf (stderr, "libgcj: internal error: could not find class for ");
+ fprintf (stderr, "method throwing exception -- continuing\n");
+ return;
+ }
+
+ VMMethod *vmmethod = new VMMethod (throw_klass,
+ reinterpret_cast<jlong> (method));
+ Location *throw_loc = new Location (vmmethod, location);
+ Location *catch_loc = NULL;
+ if (catch_method == 0)
+ catch_loc = Location::getEmptyLocation ();
+ else
+ {
+ jclass catch_klass;
+ err = env->GetMethodDeclaringClass (catch_method, &catch_klass);
+ if (err != JVMTI_ERROR_NONE)
+ {
+ fprintf (stderr,
+ "libgcj: internal error: could not find class for ");
+ fprintf (stderr,
+ "method catching exception -- ignoring\n");
+ }
+ else
+ {
+ vmmethod = new VMMethod (catch_klass,
+ reinterpret_cast<jlong> (catch_method));
+ catch_loc = new Location (vmmethod, catch_location);
+ }
+ }
+
+ _Jv_InterpFrame *iframe
+ = reinterpret_cast<_Jv_InterpFrame *> (thread->interp_frame);
+ jobject instance = (iframe == NULL) ? NULL : iframe->get_this_ptr ();
+ Throwable *throwable = reinterpret_cast<Throwable *> (exception);
+ event::ExceptionEvent *e = new ExceptionEvent (throwable, thread,
+ throw_loc, catch_loc,
+ throw_klass, instance);
+ Jdwp::notify (e);
+}
+
+static void JNICALL
jdwpSingleStepCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread,
jmethodID method, jlocation location)
{
@@ -1034,6 +1089,7 @@ jdwpVMInitCB (MAYBE_UNUSED jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env,
jvmtiEventCallbacks callbacks;
DEFINE_CALLBACK (callbacks, Breakpoint);
DEFINE_CALLBACK (callbacks, ClassPrepare);
+ DEFINE_CALLBACK (callbacks, Exception);
DEFINE_CALLBACK (callbacks, SingleStep);
DEFINE_CALLBACK (callbacks, ThreadEnd);
DEFINE_CALLBACK (callbacks, ThreadStart);
@@ -1043,6 +1099,7 @@ jdwpVMInitCB (MAYBE_UNUSED jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env,
// Enable callbacks
ENABLE_EVENT (BREAKPOINT, NULL);
ENABLE_EVENT (CLASS_PREPARE, NULL);
+ ENABLE_EVENT (EXCEPTION, NULL);
// SingleStep is enabled only when needed
ENABLE_EVENT (THREAD_END, NULL);
ENABLE_EVENT (THREAD_START, NULL);
diff --git a/libjava/gnu/gcj/jvmti/ExceptionEvent.h b/libjava/gnu/gcj/jvmti/ExceptionEvent.h
deleted file mode 100644
index 825c339..0000000
--- a/libjava/gnu/gcj/jvmti/ExceptionEvent.h
+++ /dev/null
@@ -1,44 +0,0 @@
-
-// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
-
-#ifndef __gnu_gcj_jvmti_ExceptionEvent__
-#define __gnu_gcj_jvmti_ExceptionEvent__
-
-#pragma interface
-
-#include <java/lang/Object.h>
-extern "Java"
-{
- namespace gnu
- {
- namespace gcj
- {
- namespace jvmti
- {
- class ExceptionEvent;
- }
- }
- }
-}
-
-class gnu::gcj::jvmti::ExceptionEvent : public ::java::lang::Object
-{
-
- ExceptionEvent(::java::lang::Thread *, jlong, jlong, ::java::lang::Throwable *, jlong, jlong);
-public:
- static void postExceptionEvent(::java::lang::Thread *, jlong, jlong, ::java::lang::Throwable *, jlong, jlong);
- virtual void sendEvent();
- virtual void checkCatch();
-private:
- jlong __attribute__((aligned(__alignof__( ::java::lang::Object)))) _throwMeth;
- jlong _throwLoc;
- jlong _catchMeth;
- jlong _catchLoc;
- ::java::lang::Thread * _thread;
- ::java::lang::Throwable * _ex;
- static ::java::util::WeakHashMap * _exMap;
-public:
- static ::java::lang::Class class$;
-};
-
-#endif // __gnu_gcj_jvmti_ExceptionEvent__
diff --git a/libjava/gnu/gcj/jvmti/ExceptionEvent.java b/libjava/gnu/gcj/jvmti/ExceptionEvent.java
deleted file mode 100644
index 26ddec2..0000000
--- a/libjava/gnu/gcj/jvmti/ExceptionEvent.java
+++ /dev/null
@@ -1,96 +0,0 @@
-// ExceptionEvent - an exception event for JVMTI
-
-/* Copyright (C) 2007 Free Software Foundation
-
- This file is part of libgcj.
-
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
-
-package gnu.gcj.jvmti;
-
-import java.util.WeakHashMap;
-
-/**
- * Class to create and send JVMTI Exception events
- *
- * @author Kyle Galloway (kgallowa@redhat.com)
- */
-public class ExceptionEvent
-{
- // Information about where the exception was thrown
- private long _throwMeth, _throwLoc;
-
- // Information about where the exception was or can be caught
- private long _catchMeth, _catchLoc;
-
- // Thread where the exception occurred
- private Thread _thread;
-
- // The exception
- private Throwable _ex;
-
- // A hash map of the exceptions we've already seen in a thread's call stack
- private static WeakHashMap<Thread, Throwable> _exMap = new WeakHashMap<Thread, Throwable>();
-
- /**
- * Constructs a new ExceptionEvent and sends it. If it is not caught
- * within the frame where it was thrown (catchMeth and catchLoc are null),
- * check_catch will check for a possible catch further up the call stack
- * before marking it uncaught.
- *
- * @param thr the thread where the exception occurred
- * @param throwMeth the method of the throw (a jmethodID)
- * @param throwLoc the location of the throw (a jlocation)
- * @param ex the exception
- * @param catchMeth the method of the catch (a jmethodID), null indicates
- * that the exception was not caught in the frame where it was thrown
- * @param catchLoc the location of the catch (a jlocation), null indicates
- * that the exception was not caught in the frame where it was thrown
- */
- private ExceptionEvent(Thread thr, long throwMeth, long throwLoc,
- Throwable ex, long catchMeth, long catchLoc)
- {
- this._thread = thr;
- this._ex = ex;
- this._throwMeth = throwMeth;
- this._throwLoc = throwLoc;
- this._catchMeth = catchMeth;
- this._catchLoc = catchLoc;
- }
-
- public static void postExceptionEvent(Thread thr, long throwMeth,
- long throwLoc, Throwable ex,
- long catchMeth, long catchLoc)
- {
- // Check to see if there is an entry for this Thread thr in the has map.
- // If not, add the thread to the hash map and send an ExceptionEvent.
- if (_exMap.containsKey(thr))
- {
- // Check to see if we are receiving events for the same exception, or a
- // new one. If it is not the same exception beign rethrown, send a new
- // event.
- if (!(_exMap.get(thr) == ex))
- {
- _exMap.put(thr, ex);
- ExceptionEvent event = new ExceptionEvent(thr, throwMeth,
- throwLoc, ex, catchMeth,
- catchLoc);
- event.sendEvent ();
- }
- }
- else
- {
- _exMap.put(thr, ex);
- ExceptionEvent event = new ExceptionEvent(thr, throwMeth,
- throwLoc, ex, catchMeth,
- catchLoc);
- event.sendEvent();
- }
- }
-
- public native void sendEvent();
-
- public native void checkCatch();
-}
diff --git a/libjava/include/jvmti-int.h b/libjava/include/jvmti-int.h
index f868655..6b09c83 100644
--- a/libjava/include/jvmti-int.h
+++ b/libjava/include/jvmti-int.h
@@ -89,4 +89,6 @@ extern void _Jv_JVMTI_PostEvent (jvmtiEvent type, jthread event_thread, ...)
// Returns the jvmtiEnv used by the JDWP backend
extern jvmtiEnv *_Jv_GetJDWP_JVMTIEnv (void);
+// Reports JVMTI excpetions
+extern void _Jv_ReportJVMTIExceptionThrow (jthrowable);
#endif /* __GCJ_JVMTI_INT_H__ */
diff --git a/libjava/interpret-run.cc b/libjava/interpret-run.cc
index f951981..9be08df 100644
--- a/libjava/interpret-run.cc
+++ b/libjava/interpret-run.cc
@@ -377,7 +377,9 @@ details. */
} \
while (0)
-#else
+#undef INTERP_REPORT_EXCEPTION
+#define INTERP_REPORT_EXCEPTION(Jthrowable) REPORT_EXCEPTION (Jthrowable)
+#else // !DEBUG
#undef NEXT_INSN
#define NEXT_INSN goto *((pc++)->insn)
#define REWRITE_INSN(INSN,SLOT,VALUE) \
@@ -386,7 +388,10 @@ details. */
pc[-1].SLOT = VALUE; \
} \
while (0)
-#endif
+
+#undef INTERP_REPORT_EXCEPTION
+#define INTERP_REPORT_EXCEPTION(Jthrowable) /* not needed when not debugging */
+#endif // !DEBUG
#define INTVAL() ((pc++)->int_val)
#define AVAL() ((pc++)->datum)
@@ -2355,7 +2360,11 @@ details. */
/* VM spec, section 3.11.5 */
if ((klass->getModifiers() & Modifier::ABSTRACT)
|| klass->isInterface())
- throw new java::lang::InstantiationException;
+ {
+ jthrowable t = new java::lang::InstantiationException;
+ INTERP_REPORT_EXCEPTION (t);
+ throw t;
+ }
jobject res = _Jv_AllocObject (klass);
PUSHA (res);
@@ -2422,7 +2431,9 @@ details. */
insn_athrow:
{
jobject value = POPA();
- throw static_cast<jthrowable>(value);
+ jthrowable t = static_cast<jthrowable> (value);
+ INTERP_REPORT_EXCEPTION (t);
+ throw t;
}
NEXT_INSN;
@@ -2639,10 +2650,6 @@ details. */
}
catch (java::lang::Throwable *ex)
{
-#ifdef DEBUG
- // This needs to be done before the pc is changed.
- jlong throw_loc = meth->insn_index (pc);
-#endif
// Check if the exception is handled and, if so, set the pc to the start
// of the appropriate catch block.
if (meth->check_handler (&pc, meth, ex))
@@ -2650,27 +2657,19 @@ details. */
sp = stack;
sp++->o = ex; // Push exception.
#ifdef DEBUG
- if (JVMTI_REQUESTED_EVENT (Exception))
+ if (JVMTI_REQUESTED_EVENT (ExceptionCatch))
{
using namespace gnu::gcj::jvmti;
- jlong throw_meth = reinterpret_cast<jlong> (meth->get_method ());
+ jlong catch_meth = reinterpret_cast<jlong> (meth->get_method ());
jlong catch_loc = meth->insn_index (pc);
- ExceptionEvent::postExceptionEvent (thread, throw_meth,
- throw_loc, ex, throw_meth,
- catch_loc);
+ _Jv_JVMTI_PostEvent (JVMTI_EVENT_EXCEPTION_CATCH, thread,
+ _Jv_GetCurrentJNIEnv (), catch_meth,
+ catch_loc, ex);
}
#endif
NEXT_INSN;
}
-#ifdef DEBUG
- if (JVMTI_REQUESTED_EVENT (Exception))
- {
- using namespace gnu::gcj::jvmti;
- jlong throw_meth = reinterpret_cast<jlong> (meth->get_method ());
- ExceptionEvent::postExceptionEvent (thread, throw_meth, throw_loc,
- ex, NULL, NULL);
- }
-#endif
+
// No handler, so re-throw.
throw ex;
}
diff --git a/libjava/interpret.cc b/libjava/interpret.cc
index ac23b06..9209688 100644
--- a/libjava/interpret.cc
+++ b/libjava/interpret.cc
@@ -40,7 +40,6 @@ details. */
#include <jvmti.h>
#include "jvmti-int.h"
-#include <gnu/classpath/jdwp/Jdwp.h>
#include <gnu/gcj/jvmti/Breakpoint.h>
#include <gnu/gcj/jvmti/BreakpointManager.h>
#include <gnu/gcj/jvmti/ExceptionEvent.h>
@@ -66,6 +65,16 @@ static void throw_class_format_error (jstring msg)
static void throw_class_format_error (const char *msg)
__attribute__ ((__noreturn__));
+static void find_catch_location (jthrowable, jthread, jmethodID *, jlong *);
+
+// A macro to facilitate JVMTI exception reporting
+#define REPORT_EXCEPTION(Jthrowable) \
+ do { \
+ if (JVMTI_REQUESTED_EVENT (Exception)) \
+ _Jv_ReportJVMTIExceptionThrow (Jthrowable); \
+ } \
+ while (0)
+
#ifdef DIRECT_THREADED
// Lock to ensure that methods are not compiled concurrently.
// We could use a finer-grained lock here, however it is not safe to use
@@ -956,19 +965,25 @@ _Jv_InterpMethod::run_debug (void *retp, ffi_raw *args, _Jv_InterpMethod *meth)
static void
throw_internal_error (const char *msg)
{
- throw new java::lang::InternalError (JvNewStringLatin1 (msg));
+ jthrowable t = new java::lang::InternalError (JvNewStringLatin1 (msg));
+ REPORT_EXCEPTION (t);
+ throw t;
}
static void
throw_incompatible_class_change_error (jstring msg)
{
- throw new java::lang::IncompatibleClassChangeError (msg);
+ jthrowable t = new java::lang::IncompatibleClassChangeError (msg);
+ REPORT_EXCEPTION (t);
+ throw t;
}
static void
throw_null_pointer_exception ()
{
- throw new java::lang::NullPointerException;
+ jthrowable t = new java::lang::NullPointerException;
+ REPORT_EXCEPTION (t);
+ throw t;
}
/* Look up source code line number for given bytecode (or direct threaded
@@ -1613,9 +1628,11 @@ _Jv_JNIMethod::ncode (jclass klass)
static void
throw_class_format_error (jstring msg)
{
- throw (msg
+ jthrowable t = (msg
? new java::lang::ClassFormatError (msg)
: new java::lang::ClassFormatError);
+ REPORT_EXCEPTION (t);
+ throw t;
}
static void
@@ -1624,6 +1641,70 @@ throw_class_format_error (const char *msg)
throw_class_format_error (JvNewStringLatin1 (msg));
}
+/* This function finds the method and location where the exception EXC
+ is caught in the stack frame. On return, it sets CATCH_METHOD and
+ CATCH_LOCATION with the method and location where the catch will
+ occur. If the exception is not caught, these are set to 0.
+
+ This function should only be used with the DEBUG interpreter. */
+static void
+find_catch_location (::java::lang::Throwable *exc, jthread thread,
+ jmethodID *catch_method, jlong *catch_loc)
+{
+ *catch_method = 0;
+ *catch_loc = 0;
+
+ _Jv_InterpFrame *frame
+ = reinterpret_cast<_Jv_InterpFrame *> (thread->interp_frame);
+ while (frame != NULL)
+ {
+ pc_t pc = frame->get_pc ();
+ _Jv_InterpMethod *imeth
+ = reinterpret_cast<_Jv_InterpMethod *> (frame->self);
+ if (imeth->check_handler (&pc, imeth, exc))
+ {
+ // This method handles the exception.
+ *catch_method = imeth->get_method ();
+ *catch_loc = imeth->insn_index (pc);
+ return;
+ }
+
+ frame = frame->next_interp;
+ }
+}
+
+/* This method handles JVMTI notifications of thrown exceptions. It
+ calls find_catch_location to figure out where the exception is
+ caught (if it is caught).
+
+ Like find_catch_location, this should only be called with the
+ DEBUG interpreter. Since a few exceptions occur outside the
+ interpreter proper, it is important to not call this function
+ without checking JVMTI_REQUESTED_EVENT(Exception) first. */
+void
+_Jv_ReportJVMTIExceptionThrow (jthrowable ex)
+{
+ jthread thread = ::java::lang::Thread::currentThread ();
+ _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
+ jmethodID throw_meth = frame->self->get_method ();
+ jlocation throw_loc = -1;
+ if (frame->frame_type == frame_interpreter)
+ {
+ _Jv_InterpFrame * iframe
+ = reinterpret_cast<_Jv_InterpFrame *> (frame);
+ _Jv_InterpMethod *imeth
+ = reinterpret_cast<_Jv_InterpMethod *> (frame->self);
+ throw_loc = imeth->insn_index (iframe->get_pc ());
+ }
+
+ jlong catch_loc;
+ jmethodID catch_method;
+ find_catch_location (ex, thread, &catch_method, &catch_loc);
+ _Jv_JVMTI_PostEvent (JVMTI_EVENT_EXCEPTION, thread,
+ _Jv_GetCurrentJNIEnv (), throw_meth, throw_loc,
+ ex, catch_method, catch_loc);
+}
+
void
diff --git a/libjava/jni.cc b/libjava/jni.cc
index 9e33be6..549d4fb 100644
--- a/libjava/jni.cc
+++ b/libjava/jni.cc
@@ -23,6 +23,7 @@ details. */
#include <jvmpi.h>
#endif
#include <jvmti.h>
+#include "jvmti-int.h"
#include <java/lang/Class.h>
#include <java/lang/ClassLoader.h>
@@ -456,6 +457,8 @@ _Jv_JNI_PopSystemFrame (JNIEnv *env)
{
jthrowable t = env->ex;
env->ex = NULL;
+ if (JVMTI_REQUESTED_EVENT (Exception))
+ _Jv_ReportJVMTIExceptionThrow (t);
throw t;
}
}
diff --git a/libjava/sources.am b/libjava/sources.am
index b02dfb7..caba875 100644
--- a/libjava/sources.am
+++ b/libjava/sources.am
@@ -538,7 +538,6 @@ gnu/gcj/io.list: $(gnu_gcj_io_source_files)
gnu_gcj_jvmti_source_files = \
gnu/gcj/jvmti/Breakpoint.java \
gnu/gcj/jvmti/BreakpointManager.java \
-gnu/gcj/jvmti/ExceptionEvent.java \
gnu/gcj/jvmti/Location.java
gnu_gcj_jvmti_header_files = $(patsubst %.java,%.h,$(gnu_gcj_jvmti_source_files))