aboutsummaryrefslogtreecommitdiff
path: root/libjava/gnu/gcj/jvmti/ExceptionEvent.java
blob: 26ddec213f9b0299c2e1ca5a1dfbc3cd4b318358 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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();
}