summaryrefslogtreecommitdiff
path: root/libjava/interpret.cc
diff options
context:
space:
mode:
authorkseitz <kseitz@138bc75d-0d04-0410-961f-82ee72b054a4>2007-05-04 01:04:11 +0000
committerkseitz <kseitz@138bc75d-0d04-0410-961f-82ee72b054a4>2007-05-04 01:04:11 +0000
commit6b971ede6683befb352a8ebd194f89424b49caf2 (patch)
treea8f4058c8d5dc274f095fb50893c2f74cfe875a2 /libjava/interpret.cc
parentb24655ef32d2caa4129f97dff97e12d308230f2c (diff)
downloadgcc-6b971ede6683befb352a8ebd194f89424b49caf2.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124406 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/interpret.cc')
-rw-r--r--libjava/interpret.cc91
1 files changed, 86 insertions, 5 deletions
diff --git a/libjava/interpret.cc b/libjava/interpret.cc
index ac23b060240..9209688d252 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