diff options
author | kseitz <kseitz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-05-04 01:04:11 +0000 |
---|---|---|
committer | kseitz <kseitz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-05-04 01:04:11 +0000 |
commit | 6b971ede6683befb352a8ebd194f89424b49caf2 (patch) | |
tree | a8f4058c8d5dc274f095fb50893c2f74cfe875a2 /libjava/interpret.cc | |
parent | b24655ef32d2caa4129f97dff97e12d308230f2c (diff) | |
download | gcc-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.cc | 91 |
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 |