aboutsummaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authorKeith Seitz <keiths@redhat.com>2006-11-01 18:20:19 +0000
committerKeith Seitz <kseitz@gcc.gnu.org>2006-11-01 18:20:19 +0000
commit444dd946c86cf87a35e1cc6f1350182f339871a6 (patch)
tree643906a19a9e931c1606a2d77b09af272b5296de /libjava
parent5812d1e465a56fdf5caf31cbde5356a832d69d44 (diff)
downloadgcc-444dd946c86cf87a35e1cc6f1350182f339871a6.zip
gcc-444dd946c86cf87a35e1cc6f1350182f339871a6.tar.gz
gcc-444dd946c86cf87a35e1cc6f1350182f339871a6.tar.bz2
Location.java: New file.
* gnu/gcj/jvmti/Location.java: New file. * gnu/gcj/jvmti/BreakpointManager.java: New file. * jvmti.cc (_Jv_JVMTI_SetBreakpoint): New function. (_Jv_JVMTI_ClearBreakpoint): New function. (_Jv_JVMTI_Interface): Define SetBreakpoint and ClearBreakpoint. * sources.am: Regenerated. * Makefile.in: Regenerated. From-SVN: r118391
Diffstat (limited to 'libjava')
-rw-r--r--libjava/ChangeLog10
-rw-r--r--libjava/Makefile.in4
-rw-r--r--libjava/gnu/gcj/jvmti/BreakpointManager.java76
-rw-r--r--libjava/gnu/gcj/jvmti/Location.java60
-rw-r--r--libjava/jvmti.cc74
-rw-r--r--libjava/sources.am4
6 files changed, 224 insertions, 4 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 2ab86a2..8c3d985 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,13 @@
+2006-11-01 Keith Seitz <keiths@redhat.com>
+
+ * gnu/gcj/jvmti/Location.java: New file.
+ * gnu/gcj/jvmti/BreakpointManager.java: New file.
+ * jvmti.cc (_Jv_JVMTI_SetBreakpoint): New function.
+ (_Jv_JVMTI_ClearBreakpoint): New function.
+ (_Jv_JVMTI_Interface): Define SetBreakpoint and ClearBreakpoint.
+ * sources.am: Regenerated.
+ * Makefile.in: Regenerated.
+
2006-10-28 Keith Seitz <keiths@redhat.com>
* Makefile.am (nat_source_files): Add natBreakpoint.cc.
diff --git a/libjava/Makefile.in b/libjava/Makefile.in
index b3d6cbc..d7692ac 100644
--- a/libjava/Makefile.in
+++ b/libjava/Makefile.in
@@ -1216,7 +1216,9 @@ gnu/gcj/io/SimpleSHSStream.java
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/Breakpoint.java \
+gnu/gcj/jvmti/BreakpointManager.java \
+gnu/gcj/jvmti/Location.java
gnu_gcj_jvmti_header_files = $(patsubst %.java,%.h,$(gnu_gcj_jvmti_source_files))
gnu_gcj_runtime_source_files = \
diff --git a/libjava/gnu/gcj/jvmti/BreakpointManager.java b/libjava/gnu/gcj/jvmti/BreakpointManager.java
new file mode 100644
index 0000000..205bf6d
--- /dev/null
+++ b/libjava/gnu/gcj/jvmti/BreakpointManager.java
@@ -0,0 +1,76 @@
+// BreakpointManager.java - A convenience class for dealing with breakpoints
+
+/* Copyright (C) 2006 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.Hashtable;
+
+/**
+ * A class which manages breakpoints in the VM interpreter engine.
+ *
+ * BreakpointManager is a location manager that the interpreter
+ * uses to lookup the original instruction for any given installed
+ * breakpoint. JVMTI does not allow multiple breakpoints to be set
+ * at any given location.
+ *
+ * @author Keith Seitz (keiths@redhat.com)
+ */
+public class BreakpointManager
+{
+ private static BreakpointManager _instance = new BreakpointManager ();
+
+ // List of breakpoints indexed by Location
+ private Hashtable _breakpoints;
+
+ private BreakpointManager ()
+ {
+ _breakpoints = new Hashtable ();
+ }
+
+ /**
+ * Creates a new breakpoint. SetBreakpoint will verify the validity
+ * of the arguments.
+ *
+ * @param method method in which to set breakpoint (a jmethodID)
+ * @param location index where the breakpoint is to be set (a jlocation)
+ */
+ public static Breakpoint newBreakpoint (long method, long location)
+ {
+ Breakpoint bp = new Breakpoint (method, location);
+ Location loc = new Location (method, location);
+ _instance._breakpoints.put (loc, bp);
+ return bp;
+ }
+
+ /**
+ * Deletes the breakpoint at the given Location
+ *
+ * @param method method in which to clear breakpoint
+ * @param location index of breakpoint in method
+ */
+ public static void deleteBreakpoint (long method, long location)
+ {
+ Location loc = new Location (method, location);
+ _instance._breakpoints.remove (loc);
+ }
+
+ /**
+ * Returns the breakpoint at the given location or null if none installed
+ * at location
+ *
+ * @param method the jmethodID of the breakpoint location
+ * @param location the index in the method
+ */
+ public static Breakpoint getBreakpoint (long method, long location)
+ {
+ Location loc = new Location (method, location);
+ return (Breakpoint) _instance._breakpoints.get (loc);
+ }
+}
diff --git a/libjava/gnu/gcj/jvmti/Location.java b/libjava/gnu/gcj/jvmti/Location.java
new file mode 100644
index 0000000..8fae4dd
--- /dev/null
+++ b/libjava/gnu/gcj/jvmti/Location.java
@@ -0,0 +1,60 @@
+// Location.java - a wrapper class for breakpoint locations in JVMTI
+
+/* Copyright (C) 2006 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.lang.Long;
+
+/**
+ * This class represents a breakpoint location (pair<jmethodID,jlocation>).
+ * BreakpointManager uses this class as a key in the Map of installed
+ * breakpoints.
+ *
+ * @author Keith Seitz (keiths@redhat.com)
+ */
+public class Location
+{
+ // method (a jmethodID in JVMTI)
+ private long method;
+
+ // index (a jlocation in JVMTI)
+ private long location;
+
+ /**
+ * Constructor
+ *
+ * @param method the method defined by this location (a jmethodID)
+ * @param location the integer index of the insn in the method (a jlocation)
+ */
+ public Location (long method, long location)
+ {
+ this.method = method;
+ this.location = location;
+ }
+
+ public int hashCode ()
+ {
+ return toString ().hashCode ();
+ }
+
+ public boolean equals (Object obj)
+ {
+ Location loc = (Location) obj;
+ return (loc.method == method && loc.location == location);
+ }
+
+ /**
+ * Converts the Location to a String
+ */
+ public String toString ()
+ {
+ return Long.toHexString (method) + "." + Long.toString (location);
+ }
+}
diff --git a/libjava/jvmti.cc b/libjava/jvmti.cc
index c1bdc78..5569551 100644
--- a/libjava/jvmti.cc
+++ b/libjava/jvmti.cc
@@ -14,6 +14,7 @@ details. */
#include <jvm.h>
#include <java-threads.h>
#include <java-gc.h>
+#include <java-interp.h>
#include <jvmti.h>
#include "jvmti-int.h"
@@ -21,6 +22,9 @@ details. */
#include <gnu/classpath/SystemProperties.h>
#include <gnu/gcj/runtime/BootClassLoader.h>
+#include <gnu/gcj/jvmti/Breakpoint.h>
+#include <gnu/gcj/jvmti/BreakpointManager.h>
+
#include <java/lang/Class.h>
#include <java/lang/ClassLoader.h>
#include <java/lang/Object.h>
@@ -280,6 +284,72 @@ _Jv_JVMTI_RawMonitorNotifyAll (MAYBE_UNUSED jvmtiEnv *env,
}
static jvmtiError JNICALL
+_Jv_JVMTI_SetBreakpoint (jvmtiEnv *env, jmethodID method, jlocation location)
+{
+ REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
+
+ using namespace gnu::gcj::jvmti;
+ Breakpoint *bp
+ = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
+ location);
+ if (bp == NULL)
+ {
+ jclass klass;
+ jvmtiError err = env->GetMethodDeclaringClass (method, &klass);
+ if (err != JVMTI_ERROR_NONE)
+ return err;
+
+ if (!_Jv_IsInterpretedClass (klass))
+ return JVMTI_ERROR_INVALID_CLASS;
+
+ _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
+ if (base == NULL)
+ return JVMTI_ERROR_INVALID_METHODID;
+
+ jint flags;
+ err = env->GetMethodModifiers (method, &flags);
+ if (err != JVMTI_ERROR_NONE)
+ return err;
+
+ if (flags & java::lang::reflect::Modifier::NATIVE)
+ return JVMTI_ERROR_NATIVE_METHOD;
+
+ _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> (base);
+ if (imeth->get_insn (location) == NULL)
+ return JVMTI_ERROR_INVALID_LOCATION;
+
+ // Now the breakpoint can be safely installed
+ bp = BreakpointManager::newBreakpoint (reinterpret_cast<jlong> (method),
+ location);
+ }
+ else
+ {
+ // Duplicate breakpoints are not permitted by JVMTI
+ return JVMTI_ERROR_DUPLICATE;
+ }
+
+ return JVMTI_ERROR_NONE;
+}
+
+static jvmtiError JNICALL
+_Jv_JVMTI_ClearBreakpoint (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
+ jlocation location)
+{
+ REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
+
+ using namespace gnu::gcj::jvmti;
+
+ Breakpoint *bp
+ = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
+ location);
+ if (bp == NULL)
+ return JVMTI_ERROR_NOT_FOUND;
+
+ BreakpointManager::deleteBreakpoint (reinterpret_cast<jlong> (method), location);
+ return JVMTI_ERROR_NONE;
+}
+
+static jvmtiError JNICALL
_Jv_JVMTI_Allocate (MAYBE_UNUSED jvmtiEnv *env, jlong size,
unsigned char **result)
{
@@ -1278,8 +1348,8 @@ struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
_Jv_JVMTI_RawMonitorWait, // RawMonitorWait
_Jv_JVMTI_RawMonitorNotify, // RawMonitorNotify
_Jv_JVMTI_RawMonitorNotifyAll, // RawMonitorNotifyAll
- UNIMPLEMENTED, // SetBreakpoint
- UNIMPLEMENTED, // ClearBreakpoint
+ _Jv_JVMTI_SetBreakpoint, // SetBreakpoint
+ _Jv_JVMTI_ClearBreakpoint, // ClearBreakpoint
RESERVED, // reserved40
UNIMPLEMENTED, // SetFieldAccessWatch
UNIMPLEMENTED, // ClearFieldAccessWatch
diff --git a/libjava/sources.am b/libjava/sources.am
index f23a0bd..7cd9e26 100644
--- a/libjava/sources.am
+++ b/libjava/sources.am
@@ -566,7 +566,9 @@ gnu/gcj/io.list: $(gnu_gcj_io_source_files)
gnu_gcj_jvmti_source_files = \
-gnu/gcj/jvmti/Breakpoint.java
+gnu/gcj/jvmti/Breakpoint.java \
+gnu/gcj/jvmti/BreakpointManager.java \
+gnu/gcj/jvmti/Location.java
gnu_gcj_jvmti_header_files = $(patsubst %.java,%.h,$(gnu_gcj_jvmti_source_files))