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
This commit is contained in:
+86
-5
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user