diff options
author | kgallowa <kgallowa@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-16 00:05:39 +0000 |
---|---|---|
committer | kgallowa <kgallowa@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-16 00:05:39 +0000 |
commit | 721a9630e2f08aeb4f20dd1c133f9ac9a1081d13 (patch) | |
tree | 7b7a9e88310e312e8a488c89edfc65e8dd555cfc /libjava/gnu | |
parent | c2f47e150f3c68a813f92460462c2e70155f2c67 (diff) | |
download | gcc-721a9630e2f08aeb4f20dd1c133f9ac9a1081d13.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122019 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/gnu')
-rw-r--r-- | libjava/gnu/gcj/jvmti/ExceptionEvent.h | 44 | ||||
-rw-r--r-- | libjava/gnu/gcj/jvmti/ExceptionEvent.java | 96 | ||||
-rw-r--r-- | libjava/gnu/gcj/jvmti/natExceptionEvent.cc | 59 |
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 00000000000..825c33951d7 --- /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 00000000000..26ddec213f9 --- /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 00000000000..dfc8e669dd8 --- /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; + } + } +} |