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:
Keith Seitz
2007-05-04 01:04:11 +00:00
committed by Keith Seitz
parent 820b51ae16
commit befd756626
11 changed files with 198 additions and 169 deletions
+86 -5
View File
@@ -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