interpret.cc (_Jv_InterpMethod::check_handler): New method.

2007-02-15  Kyle Galloway  <kgallowa@redhat.com>
	
	* interpret.cc (_Jv_InterpMethod::check_handler): New method.
    * interpret-run.cc: Change the catch section to report exception
    events and to use the new check_handler method.
    * include/java-interp.h (_Jv_InterpMethod): Add check_handler.
    * gnu/gcj/jvmti/ExceptionEvent.java: New file.
    * gnu/gcj/jvmti/ExceptionEvent.h: New file.
    * gnu/gcj/jvmti/natExceptionEvent.cc: New file.
    * libjava/classpath/lib/gnu/gcj/jvmti/ExceptionEvent.class: New
    file.
    * sources.am: Added ExceptionEvent.java.
    * Makefile.am: Added natExceptionEvent.cc
    * Makefile.in: Regenerated.
    * include/Makefile.in: Regenerated.
    * gcj/Makefile.in: Regenerated.

From-SVN: r122019
This commit is contained in:
Kyle Galloway 2007-02-16 00:05:39 +00:00 committed by Kyle Galloway
parent 5039610b96
commit 7a1bf87c6e
14 changed files with 345 additions and 60 deletions

View File

@ -1,3 +1,20 @@
2007-02-15 Kyle Galloway <kgallowa@redhat.com>
* interpret.cc (_Jv_InterpMethod::check_handler): New method.
* interpret-run.cc: Change the catch section to report exception
events and to use the new check_handler method.
* include/java-interp.h (_Jv_InterpMethod): Add check_handler.
* gnu/gcj/jvmti/ExceptionEvent.java: New file.
* gnu/gcj/jvmti/ExceptionEvent.h: New file.
* gnu/gcj/jvmti/natExceptionEvent.cc: New file.
* libjava/classpath/lib/gnu/gcj/jvmti/ExceptionEvent.class: New
file.
* sources.am: Added ExceptionEvent.java.
* Makefile.am: Added natExceptionEvent.cc
* Makefile.in: Regenerated.
* include/Makefile.in: Regenerated.
* gcj/Makefile.in: Regenerated.
2007-02-15 Johannes Schmidt <jschmidt@avtrex.com>
David Daney <ddaney@avtrex.com>

View File

@ -840,6 +840,7 @@ gnu/gcj/convert/natOutput_SJIS.cc \
gnu/gcj/io/natSimpleSHSStream.cc \
gnu/gcj/io/shs.cc \
gnu/gcj/jvmti/natBreakpoint.cc \
gnu/gcj/jvmti/natExceptionEvent.cc \
gnu/gcj/runtime/natFinalizerThread.cc \
gnu/gcj/runtime/natSharedLibLoader.cc \
gnu/gcj/runtime/natSystemClassLoader.cc \

View File

@ -301,6 +301,7 @@ am__libgcj_la_SOURCES_DIST = prims.cc jni.cc jvmti.cc exception.cc \
gnu/gcj/convert/natOutput_SJIS.cc \
gnu/gcj/io/natSimpleSHSStream.cc gnu/gcj/io/shs.cc \
gnu/gcj/jvmti/natBreakpoint.cc \
gnu/gcj/jvmti/natExceptionEvent.cc \
gnu/gcj/runtime/natFinalizerThread.cc \
gnu/gcj/runtime/natSharedLibLoader.cc \
gnu/gcj/runtime/natSystemClassLoader.cc \
@ -364,6 +365,7 @@ am__objects_2 = gnu/classpath/jdwp/natVMFrame.lo \
gnu/gcj/convert/natOutput_SJIS.lo \
gnu/gcj/io/natSimpleSHSStream.lo gnu/gcj/io/shs.lo \
gnu/gcj/jvmti/natBreakpoint.lo \
gnu/gcj/jvmti/natExceptionEvent.lo \
gnu/gcj/runtime/natFinalizerThread.lo \
gnu/gcj/runtime/natSharedLibLoader.lo \
gnu/gcj/runtime/natSystemClassLoader.lo \
@ -600,6 +602,7 @@ GCSPEC = @GCSPEC@
GCTESTSPEC = @GCTESTSPEC@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GREP = @GREP@
GTK_CFLAGS = @GTK_CFLAGS@
GTK_LIBS = @GTK_LIBS@
HASH_SYNC_SPEC = @HASH_SYNC_SPEC@
@ -703,6 +706,7 @@ USING_WIN32_THREADS_TRUE = @USING_WIN32_THREADS_TRUE@
VERSION = @VERSION@
XLIB_AWT_FALSE = @XLIB_AWT_FALSE@
XLIB_AWT_TRUE = @XLIB_AWT_TRUE@
XMKMF = @XMKMF@
X_AWT_FALSE = @X_AWT_FALSE@
X_AWT_TRUE = @X_AWT_TRUE@
X_CFLAGS = @X_CFLAGS@
@ -714,14 +718,8 @@ ZIP = @ZIP@
ZLIBS = @ZLIBS@
ZLIBSPEC = @ZLIBSPEC@
ZLIBTESTSPEC = @ZLIBTESTSPEC@
ac_ct_AR = @ac_ct_AR@
ac_ct_AS = @ac_ct_AS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_GCJ = @ac_ct_GCJ@
ac_ct_LD = @ac_ct_LD@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
@ -742,7 +740,10 @@ build_os = @build_os@
build_subdir = @build_subdir@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
dbexecdir = @dbexecdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
extra_ldflags_libjava = @extra_ldflags_libjava@ $(am__append_5)
gxx_include_dir = @gxx_include_dir@
@ -754,20 +755,24 @@ host_exeext = @host_exeext@
host_os = @host_os@
host_subdir = @host_subdir@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libstdcxx_incdir = @libstdcxx_incdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
mkinstalldirs = @mkinstalldirs@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
subdirs = @subdirs@
@ -1324,6 +1329,7 @@ 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))
@ -7953,6 +7959,7 @@ gnu/gcj/convert/natOutput_SJIS.cc \
gnu/gcj/io/natSimpleSHSStream.cc \
gnu/gcj/io/shs.cc \
gnu/gcj/jvmti/natBreakpoint.cc \
gnu/gcj/jvmti/natExceptionEvent.cc \
gnu/gcj/runtime/natFinalizerThread.cc \
gnu/gcj/runtime/natSharedLibLoader.cc \
gnu/gcj/runtime/natSystemClassLoader.cc \
@ -8347,6 +8354,8 @@ gnu/gcj/jvmti/$(DEPDIR)/$(am__dirstamp):
@: > gnu/gcj/jvmti/$(DEPDIR)/$(am__dirstamp)
gnu/gcj/jvmti/natBreakpoint.lo: gnu/gcj/jvmti/$(am__dirstamp) \
gnu/gcj/jvmti/$(DEPDIR)/$(am__dirstamp)
gnu/gcj/jvmti/natExceptionEvent.lo: gnu/gcj/jvmti/$(am__dirstamp) \
gnu/gcj/jvmti/$(DEPDIR)/$(am__dirstamp)
gnu/gcj/runtime/$(am__dirstamp):
@$(mkdir_p) gnu/gcj/runtime
@: > gnu/gcj/runtime/$(am__dirstamp)
@ -8830,6 +8839,8 @@ mostlyclean-compile:
-rm -f gnu/gcj/io/shs.lo
-rm -f gnu/gcj/jvmti/natBreakpoint.$(OBJEXT)
-rm -f gnu/gcj/jvmti/natBreakpoint.lo
-rm -f gnu/gcj/jvmti/natExceptionEvent.$(OBJEXT)
-rm -f gnu/gcj/jvmti/natExceptionEvent.lo
-rm -f gnu/gcj/natCore.$(OBJEXT)
-rm -f gnu/gcj/natCore.lo
-rm -f gnu/gcj/runtime/natFinalizerThread.$(OBJEXT)
@ -9048,6 +9059,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@gnu/gcj/io/$(DEPDIR)/natSimpleSHSStream.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gnu/gcj/io/$(DEPDIR)/shs.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gnu/gcj/jvmti/$(DEPDIR)/natBreakpoint.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gnu/gcj/jvmti/$(DEPDIR)/natExceptionEvent.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gnu/gcj/runtime/$(DEPDIR)/natFinalizerThread.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gnu/gcj/runtime/$(DEPDIR)/natSharedLibLoader.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@gnu/gcj/runtime/$(DEPDIR)/natStringBuffer.Plo@am__quote@

View File

@ -135,6 +135,7 @@ GCSPEC = @GCSPEC@
GCTESTSPEC = @GCTESTSPEC@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GREP = @GREP@
GTK_CFLAGS = @GTK_CFLAGS@
GTK_LIBS = @GTK_LIBS@
HASH_SYNC_SPEC = @HASH_SYNC_SPEC@
@ -238,6 +239,7 @@ USING_WIN32_THREADS_TRUE = @USING_WIN32_THREADS_TRUE@
VERSION = @VERSION@
XLIB_AWT_FALSE = @XLIB_AWT_FALSE@
XLIB_AWT_TRUE = @XLIB_AWT_TRUE@
XMKMF = @XMKMF@
X_AWT_FALSE = @X_AWT_FALSE@
X_AWT_TRUE = @X_AWT_TRUE@
X_CFLAGS = @X_CFLAGS@
@ -249,14 +251,8 @@ ZIP = @ZIP@
ZLIBS = @ZLIBS@
ZLIBSPEC = @ZLIBSPEC@
ZLIBTESTSPEC = @ZLIBTESTSPEC@
ac_ct_AR = @ac_ct_AR@
ac_ct_AS = @ac_ct_AS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_GCJ = @ac_ct_GCJ@
ac_ct_LD = @ac_ct_LD@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
@ -277,7 +273,10 @@ build_os = @build_os@
build_subdir = @build_subdir@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
dbexecdir = @dbexecdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
extra_ldflags_libjava = @extra_ldflags_libjava@
gxx_include_dir = @gxx_include_dir@
@ -289,20 +288,24 @@ host_exeext = @host_exeext@
host_os = @host_os@
host_subdir = @host_subdir@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libstdcxx_incdir = @libstdcxx_incdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
mkinstalldirs = @mkinstalldirs@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
subdirs = @subdirs@

View File

@ -0,0 +1,44 @@
// 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__

View File

@ -0,0 +1,96 @@
// 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();
}

View File

@ -0,0 +1,59 @@
// natExceptionEvent.cc - C++ code for JVMTI Exception events
/* 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. */
#include <config.h>
#include <gcj/cni.h>
#include <gcj/method.h>
#include <java-interp.h>
#include <java-insns.h>
#include <java-assert.h>
#include <jvmti.h>
#include <jvmti-int.h>
#include <gnu/gcj/jvmti/ExceptionEvent.h>
void
gnu::gcj::jvmti::ExceptionEvent::sendEvent ()
{
// Check if the exception is caught somewhere in the interpreted call stack
if (_catchMeth == 0 || _catchLoc == 0)
checkCatch ();
JNIEnv *jni = _Jv_GetCurrentJNIEnv ();
_Jv_JVMTI_PostEvent (JVMTI_EVENT_EXCEPTION, _thread, jni,
reinterpret_cast<jmethodID> (_throwMeth),
static_cast<jlocation> (_throwLoc), _ex,
reinterpret_cast<jmethodID> (_catchMeth),
static_cast<jlocation> (_catchLoc));
}
// This method looks up the interpreted call stack to see if the exception will
// eventually be caught by some java method.
void
gnu::gcj::jvmti::ExceptionEvent::checkCatch ()
{
_Jv_InterpFrame *frame
= reinterpret_cast<_Jv_InterpFrame *> (_thread->interp_frame);
while ((frame = frame->next_interp))
{
_Jv_InterpMethod *meth
= reinterpret_cast<_Jv_InterpMethod *> (frame->self);
pc_t pc = frame->pc;
if (meth->check_handler (&pc, meth, _ex))
{
_catchMeth = reinterpret_cast<jlong> (meth->get_method ());
_catchLoc = meth->insn_index (pc);
break;
}
}
}

View File

@ -134,6 +134,7 @@ GCSPEC = @GCSPEC@
GCTESTSPEC = @GCTESTSPEC@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GREP = @GREP@
GTK_CFLAGS = @GTK_CFLAGS@
GTK_LIBS = @GTK_LIBS@
HASH_SYNC_SPEC = @HASH_SYNC_SPEC@
@ -237,6 +238,7 @@ USING_WIN32_THREADS_TRUE = @USING_WIN32_THREADS_TRUE@
VERSION = @VERSION@
XLIB_AWT_FALSE = @XLIB_AWT_FALSE@
XLIB_AWT_TRUE = @XLIB_AWT_TRUE@
XMKMF = @XMKMF@
X_AWT_FALSE = @X_AWT_FALSE@
X_AWT_TRUE = @X_AWT_TRUE@
X_CFLAGS = @X_CFLAGS@
@ -248,14 +250,8 @@ ZIP = @ZIP@
ZLIBS = @ZLIBS@
ZLIBSPEC = @ZLIBSPEC@
ZLIBTESTSPEC = @ZLIBTESTSPEC@
ac_ct_AR = @ac_ct_AR@
ac_ct_AS = @ac_ct_AS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_GCJ = @ac_ct_GCJ@
ac_ct_LD = @ac_ct_LD@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
@ -276,7 +272,10 @@ build_os = @build_os@
build_subdir = @build_subdir@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
dbexecdir = @dbexecdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
extra_ldflags_libjava = @extra_ldflags_libjava@
gxx_include_dir = @gxx_include_dir@
@ -288,20 +287,24 @@ host_exeext = @host_exeext@
host_os = @host_os@
host_subdir = @host_subdir@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libstdcxx_incdir = @libstdcxx_incdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
mkinstalldirs = @mkinstalldirs@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
subdirs = @subdirs@

View File

@ -229,6 +229,11 @@ class _Jv_InterpMethod : public _Jv_MethodBase
// Convenience function for indexing bytecode PC/insn slots in
// line tables for JDWP
jlong insn_index (pc_t pc);
// Helper function used to check if there is a handler for an exception
// present at this code index
jboolean check_handler (pc_t *pc, _Jv_InterpMethod *meth,
java::lang::Throwable *ex);
/* Get the line table for this method.
* start is the lowest index in the method

View File

@ -2540,43 +2540,38 @@ details. */
}
catch (java::lang::Throwable *ex)
{
#ifdef DIRECT_THREADED
void *logical_pc = (void *) ((insn_slot *) pc - 1);
#else
int logical_pc = pc - 1 - meth->bytecode ();
#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))
{
sp = stack;
sp++->o = ex; // Push exception.
#ifdef DEBUG
if (JVMTI_REQUESTED_EVENT (Exception))
{
using namespace gnu::gcj::jvmti;
jlong throw_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);
}
#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
_Jv_InterpException *exc = meth->exceptions ();
jclass exc_class = ex->getClass ();
for (int i = 0; i < meth->exc_count; i++)
{
if (PCVAL (exc[i].start_pc) <= logical_pc
&& logical_pc < PCVAL (exc[i].end_pc))
{
#ifdef DIRECT_THREADED
jclass handler = (jclass) exc[i].handler_type.p;
#else
jclass handler = NULL;
if (exc[i].handler_type.i != 0)
handler = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
exc[i].handler_type.i)).clazz;
#endif /* DIRECT_THREADED */
if (handler == NULL || handler->isAssignableFrom (exc_class))
{
#ifdef DIRECT_THREADED
pc = (insn_slot *) exc[i].handler_pc.p;
#else
pc = meth->bytecode () + exc[i].handler_pc.i;
#endif /* DIRECT_THREADED */
sp = stack;
sp++->o = ex; // Push exception.
NEXT_INSN;
}
}
}
// No handler, so re-throw.
throw ex;
}

View File

@ -43,6 +43,7 @@ details. */
#include <gnu/classpath/jdwp/Jdwp.h>
#include <gnu/gcj/jvmti/Breakpoint.h>
#include <gnu/gcj/jvmti/BreakpointManager.h>
#include <gnu/gcj/jvmti/ExceptionEvent.h>
#ifdef INTERPRETER
@ -1366,6 +1367,51 @@ _Jv_InterpMethod::insn_index (pc_t pc)
return -1;
}
// Method to check if an exception is caught at some location in a method
// (meth). Returns true if this method (meth) contains a catch block for the
// exception (ex). False otherwise. If there is a catch block, it sets the pc
// to the location of the beginning of the catch block.
jboolean
_Jv_InterpMethod::check_handler (pc_t *pc, _Jv_InterpMethod *meth,
java::lang::Throwable *ex)
{
#ifdef DIRECT_THREADED
void *logical_pc = (void *) ((insn_slot *) (*pc) - 1);
#else
int logical_pc = (*pc) - 1 - meth->bytecode ();
#endif
_Jv_InterpException *exc = meth->exceptions ();
jclass exc_class = ex->getClass ();
for (int i = 0; i < meth->exc_count; i++)
{
if (PCVAL (exc[i].start_pc) <= logical_pc
&& logical_pc < PCVAL (exc[i].end_pc))
{
#ifdef DIRECT_THREADED
jclass handler = (jclass) exc[i].handler_type.p;
#else
jclass handler = NULL;
if (exc[i].handler_type.i != 0)
handler
= (_Jv_Linker::resolve_pool_entry (meth->defining_class,
ex$
#endif /* DIRECT_THREADED */
if (handler == NULL || handler->isAssignableFrom (exc_class))
{
#ifdef DIRECT_THREADED
(*pc) = (insn_slot *) exc[i].handler_pc.p;
#else
(*pc) = meth->bytecode () + exc[i].handler_pc.i;
#endif /* DIRECT_THREADED */
return true;
}
}
}
return false;
}
void
_Jv_InterpMethod::get_line_table (jlong& start, jlong& end,
jintArray& line_numbers,

View File

@ -509,6 +509,7 @@ 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))

View File

@ -123,6 +123,7 @@ GCSPEC = @GCSPEC@
GCTESTSPEC = @GCTESTSPEC@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GREP = @GREP@
GTK_CFLAGS = @GTK_CFLAGS@
GTK_LIBS = @GTK_LIBS@
HASH_SYNC_SPEC = @HASH_SYNC_SPEC@
@ -226,6 +227,7 @@ USING_WIN32_THREADS_TRUE = @USING_WIN32_THREADS_TRUE@
VERSION = @VERSION@
XLIB_AWT_FALSE = @XLIB_AWT_FALSE@
XLIB_AWT_TRUE = @XLIB_AWT_TRUE@
XMKMF = @XMKMF@
X_AWT_FALSE = @X_AWT_FALSE@
X_AWT_TRUE = @X_AWT_TRUE@
X_CFLAGS = @X_CFLAGS@
@ -237,14 +239,8 @@ ZIP = @ZIP@
ZLIBS = @ZLIBS@
ZLIBSPEC = @ZLIBSPEC@
ZLIBTESTSPEC = @ZLIBTESTSPEC@
ac_ct_AR = @ac_ct_AR@
ac_ct_AS = @ac_ct_AS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_GCJ = @ac_ct_GCJ@
ac_ct_LD = @ac_ct_LD@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
@ -265,7 +261,10 @@ build_os = @build_os@
build_subdir = @build_subdir@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
dbexecdir = @dbexecdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
extra_ldflags_libjava = @extra_ldflags_libjava@
gxx_include_dir = @gxx_include_dir@
@ -277,20 +276,24 @@ host_exeext = @host_exeext@
host_os = @host_os@
host_subdir = @host_subdir@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libstdcxx_incdir = @libstdcxx_incdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
mkinstalldirs = @mkinstalldirs@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
subdirs = @subdirs@