aboutsummaryrefslogtreecommitdiff
path: root/libjava/gnu
diff options
context:
space:
mode:
authorKyle Galloway <kgallowa@redhat.com>2007-02-16 00:05:39 +0000
committerKyle Galloway <kgallowa@gcc.gnu.org>2007-02-16 00:05:39 +0000
commit7a1bf87c6e856bbccc6b771834588803f518cd54 (patch)
tree7b7a9e88310e312e8a488c89edfc65e8dd555cfc /libjava/gnu
parent5039610b9630459799b24f64fb9ffdd810b8eee9 (diff)
downloadgcc-7a1bf87c6e856bbccc6b771834588803f518cd54.zip
gcc-7a1bf87c6e856bbccc6b771834588803f518cd54.tar.gz
gcc-7a1bf87c6e856bbccc6b771834588803f518cd54.tar.bz2
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
Diffstat (limited to 'libjava/gnu')
-rw-r--r--libjava/gnu/gcj/jvmti/ExceptionEvent.h44
-rw-r--r--libjava/gnu/gcj/jvmti/ExceptionEvent.java96
-rw-r--r--libjava/gnu/gcj/jvmti/natExceptionEvent.cc59
3 files changed, 199 insertions, 0 deletions
diff --git a/libjava/gnu/gcj/jvmti/ExceptionEvent.h b/libjava/gnu/gcj/jvmti/ExceptionEvent.h
new file mode 100644
index 0000000..825c339
--- /dev/null
+++ b/libjava/gnu/gcj/jvmti/ExceptionEvent.h
@@ -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__
diff --git a/libjava/gnu/gcj/jvmti/ExceptionEvent.java b/libjava/gnu/gcj/jvmti/ExceptionEvent.java
new file mode 100644
index 0000000..26ddec2
--- /dev/null
+++ b/libjava/gnu/gcj/jvmti/ExceptionEvent.java
@@ -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();
+}
diff --git a/libjava/gnu/gcj/jvmti/natExceptionEvent.cc b/libjava/gnu/gcj/jvmti/natExceptionEvent.cc
new file mode 100644
index 0000000..dfc8e66
--- /dev/null
+++ b/libjava/gnu/gcj/jvmti/natExceptionEvent.cc
@@ -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;
+ }
+ }
+}