jvmti-int.h (_Jv_ReportJVMTIExceptionThrow): Declare.
authorKeith Seitz <keiths@redhat.com>
Fri, 4 May 2007 01:04:11 +0000 (01:04 +0000)
committerKeith Seitz <kseitz@gcc.gnu.org>
Fri, 4 May 2007 01:04:11 +0000 (01:04 +0000)
        * 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

libjava/ChangeLog
libjava/Makefile.in
libjava/classpath/lib/gnu/gcj/jvmti/ExceptionEvent.class [deleted file]
libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc
libjava/gnu/gcj/jvmti/ExceptionEvent.h [deleted file]
libjava/gnu/gcj/jvmti/ExceptionEvent.java [deleted file]
libjava/include/jvmti-int.h
libjava/interpret-run.cc
libjava/interpret.cc
libjava/jni.cc
libjava/sources.am

index 9607a3dcd89982d1bc707c7676a15af6d3cd78a8..ccaf00b72381d4a02972e01bf238247ff132270d 100644 (file)
@@ -1,3 +1,32 @@
+2007-05-03  Keith Seitz  <keiths@redhat.com>
+
+       * 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.
+
 2007-05-03  Thomas Fitzsimmons  <fitzsim@redhat.com>
 
        https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=237304
index 369c1913222b7945fe25691a9abddf5d78969537..48ae71b30baca7ad642eea3e595221ff8db8d1c0 100644 (file)
@@ -1349,7 +1349,6 @@ 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))
diff --git a/libjava/classpath/lib/gnu/gcj/jvmti/ExceptionEvent.class b/libjava/classpath/lib/gnu/gcj/jvmti/ExceptionEvent.class
deleted file mode 100644 (file)
index bfdedd0..0000000
Binary files a/libjava/classpath/lib/gnu/gcj/jvmti/ExceptionEvent.class and /dev/null differ
index 1dfc52995e05ec7d49c6e8e08418071c94ccd415..d6edf345437021b7296b2abe80edb79b57950850 100644 (file)
@@ -21,6 +21,7 @@ details. */
 #include <java/lang/String.h>
 #include <java/lang/StringBuilder.h>
 #include <java/lang/Thread.h>
+#include <java/lang/Throwable.h>
 #include <java/nio/ByteBuffer.h>
 #include <java/nio/ByteBufferImpl.h>
 #include <java/util/ArrayList.h>
@@ -37,6 +38,7 @@ details. */
 #include <gnu/classpath/jdwp/VMVirtualMachine.h>
 #include <gnu/classpath/jdwp/event/BreakpointEvent.h>
 #include <gnu/classpath/jdwp/event/ClassPrepareEvent.h>
+#include <gnu/classpath/jdwp/event/ExceptionEvent.h>
 #include <gnu/classpath/jdwp/event/EventManager.h>
 #include <gnu/classpath/jdwp/event/EventRequest.h>
 #include <gnu/classpath/jdwp/event/SingleStepEvent.h>
@@ -82,6 +84,9 @@ static void handle_single_step (jvmtiEnv *, struct step_info *, jthread,
 static void JNICALL jdwpBreakpointCB (jvmtiEnv *, JNIEnv *, jthread,
                                      jmethodID, jlocation);
 static void JNICALL jdwpClassPrepareCB (jvmtiEnv *, JNIEnv *, jthread, jclass);
+static void JNICALL jdwpExceptionCB (jvmtiEnv *, JNIEnv *jni_env, jthread,
+                                    jmethodID, jlocation, jobject,
+                                    jmethodID, jlocation);
 static void JNICALL jdwpSingleStepCB (jvmtiEnv *, JNIEnv *, jthread,
                                      jmethodID, jlocation);
 static void JNICALL jdwpThreadEndCB (jvmtiEnv *, JNIEnv *, jthread);
@@ -932,6 +937,56 @@ jdwpClassPrepareCB (MAYBE_UNUSED jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env,
   Jdwp::notify (event);
 }
 
+static void JNICALL
+jdwpExceptionCB (jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env, jthread thread,
+                jmethodID method, jlocation location, jobject exception,
+                jmethodID catch_method, jlocation catch_location)
+{
+  using namespace gnu::classpath::jdwp;
+  jclass throw_klass;
+  jvmtiError err = env->GetMethodDeclaringClass (method, &throw_klass);
+  if (err != JVMTI_ERROR_NONE)
+    {
+      fprintf (stderr, "libgcj: internal error: could not find class for ");
+      fprintf (stderr, "method throwing exception -- continuing\n");
+      return;
+    }
+
+  VMMethod *vmmethod = new VMMethod (throw_klass,
+                                    reinterpret_cast<jlong> (method));
+  Location *throw_loc = new Location (vmmethod, location);  
+  Location *catch_loc = NULL;
+  if (catch_method == 0)
+    catch_loc = Location::getEmptyLocation ();
+  else
+    {
+      jclass catch_klass;
+      err = env->GetMethodDeclaringClass (catch_method, &catch_klass);
+      if (err != JVMTI_ERROR_NONE)
+       {
+         fprintf (stderr,
+                  "libgcj: internal error: could not find class for ");
+         fprintf (stderr,
+                  "method catching exception -- ignoring\n");
+       }
+      else
+       {
+         vmmethod = new VMMethod (catch_klass,
+                                  reinterpret_cast<jlong> (catch_method));
+         catch_loc = new Location (vmmethod, catch_location);
+       }
+    }
+
+  _Jv_InterpFrame *iframe
+    = reinterpret_cast<_Jv_InterpFrame *> (thread->interp_frame);
+  jobject instance = (iframe == NULL) ? NULL : iframe->get_this_ptr ();
+  Throwable *throwable = reinterpret_cast<Throwable *> (exception);
+  event::ExceptionEvent *e = new ExceptionEvent (throwable, thread,
+                                                throw_loc, catch_loc,
+                                                throw_klass, instance);
+  Jdwp::notify (e);
+}
+
 static void JNICALL
 jdwpSingleStepCB (jvmtiEnv *env, JNIEnv *jni_env, jthread thread,
                  jmethodID method, jlocation location)
@@ -1034,6 +1089,7 @@ jdwpVMInitCB (MAYBE_UNUSED jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env,
   jvmtiEventCallbacks callbacks;
   DEFINE_CALLBACK (callbacks, Breakpoint);
   DEFINE_CALLBACK (callbacks, ClassPrepare);
+  DEFINE_CALLBACK (callbacks, Exception);
   DEFINE_CALLBACK (callbacks, SingleStep);
   DEFINE_CALLBACK (callbacks, ThreadEnd);
   DEFINE_CALLBACK (callbacks, ThreadStart);
@@ -1043,6 +1099,7 @@ jdwpVMInitCB (MAYBE_UNUSED jvmtiEnv *env, MAYBE_UNUSED JNIEnv *jni_env,
   // Enable callbacks
   ENABLE_EVENT (BREAKPOINT, NULL);
   ENABLE_EVENT (CLASS_PREPARE, NULL);
+  ENABLE_EVENT (EXCEPTION, NULL);
   // SingleStep is enabled only when needed
   ENABLE_EVENT (THREAD_END, NULL);
   ENABLE_EVENT (THREAD_START, NULL);
diff --git a/libjava/gnu/gcj/jvmti/ExceptionEvent.h b/libjava/gnu/gcj/jvmti/ExceptionEvent.h
deleted file mode 100644 (file)
index 825c339..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-
-// 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
deleted file mode 100644 (file)
index 26ddec2..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-// 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();
-}
index f868655734ae3d62065aaccc1e0e29a6d69b828f..6b09c8376591b2a02bab16c62b441eaf0b297033 100644 (file)
@@ -89,4 +89,6 @@ extern void _Jv_JVMTI_PostEvent (jvmtiEvent type, jthread event_thread,                                ...)
 // Returns the jvmtiEnv used by the JDWP backend
 extern jvmtiEnv *_Jv_GetJDWP_JVMTIEnv (void);
 
+// Reports JVMTI excpetions
+extern void _Jv_ReportJVMTIExceptionThrow (jthrowable);
 #endif /* __GCJ_JVMTI_INT_H__ */
index f95198186e734b414a14dddc86cdacb5f08b29d3..9be08df488b42b7d1675e466d7ea1ea0319d82c9 100644 (file)
@@ -377,7 +377,9 @@ details.  */
   }                                                                    \
   while (0)
 
-#else
+#undef INTERP_REPORT_EXCEPTION
+#define INTERP_REPORT_EXCEPTION(Jthrowable) REPORT_EXCEPTION (Jthrowable)
+#else // !DEBUG
 #undef NEXT_INSN
 #define NEXT_INSN goto *((pc++)->insn)
 #define REWRITE_INSN(INSN,SLOT,VALUE)          \
@@ -386,7 +388,10 @@ details.  */
     pc[-1].SLOT = VALUE;                       \
   }                                            \
   while (0)
-#endif
+
+#undef INTERP_REPORT_EXCEPTION
+#define INTERP_REPORT_EXCEPTION(Jthrowable) /* not needed when not debugging */
+#endif // !DEBUG
 
 #define INTVAL() ((pc++)->int_val)
 #define AVAL() ((pc++)->datum)
@@ -2355,7 +2360,11 @@ details.  */
        /* VM spec, section 3.11.5 */
        if ((klass->getModifiers() & Modifier::ABSTRACT)
            || klass->isInterface())
-         throw new java::lang::InstantiationException;
+         {
+           jthrowable t = new java::lang::InstantiationException;
+           INTERP_REPORT_EXCEPTION (t);
+           throw t;
+         }
        jobject res = _Jv_AllocObject (klass);
        PUSHA (res);
 
@@ -2422,7 +2431,9 @@ details.  */
     insn_athrow:
       {
        jobject value = POPA();
-       throw static_cast<jthrowable>(value);
+       jthrowable t = static_cast<jthrowable> (value);
+       INTERP_REPORT_EXCEPTION (t);
+       throw t;
       }
       NEXT_INSN;
 
@@ -2639,10 +2650,6 @@ details.  */
     }
   catch (java::lang::Throwable *ex)
     {
-#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))
@@ -2650,27 +2657,19 @@ details.  */
           sp = stack;
           sp++->o = ex; // Push exception.
 #ifdef DEBUG
-          if (JVMTI_REQUESTED_EVENT (Exception))
+          if (JVMTI_REQUESTED_EVENT (ExceptionCatch))
             {
               using namespace gnu::gcj::jvmti;
-              jlong throw_meth = reinterpret_cast<jlong> (meth->get_method ());
+              jlong catch_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);
+             _Jv_JVMTI_PostEvent (JVMTI_EVENT_EXCEPTION_CATCH, thread,
+                                  _Jv_GetCurrentJNIEnv (), catch_meth,
+                                  catch_loc, ex);
             }
 #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
+
       // No handler, so re-throw.
       throw ex;
     }
index ac23b060240ef020c950743eaecfeea6a53ee1f7..9209688d25216654fdfe34799cc1fd1e62b0ac88 100644 (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);
+}
+
 \f
 
 void
index 9e33be6e69f925a21c0fbcd7ee81caa2685795c7..549d4fb06d397d46d1f04db09be2f95e1593c062 100644 (file)
@@ -23,6 +23,7 @@ details.  */
 #include <jvmpi.h>
 #endif
 #include <jvmti.h>
+#include "jvmti-int.h"
 
 #include <java/lang/Class.h>
 #include <java/lang/ClassLoader.h>
@@ -456,6 +457,8 @@ _Jv_JNI_PopSystemFrame (JNIEnv *env)
     {
       jthrowable t = env->ex;
       env->ex = NULL;
+      if (JVMTI_REQUESTED_EVENT (Exception))
+       _Jv_ReportJVMTIExceptionThrow (t);
       throw t;
     }
 }
index b02dfb709dc8d4c748f9c1baee5a2ffe7f50142f..caba875f87ee7947c8d536bdf2aac5dffd379e63 100644 (file)
@@ -538,7 +538,6 @@ 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))