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
+44
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__
+96
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();
}
@@ -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;
}
}
}