summaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authorkseitz <kseitz@138bc75d-0d04-0410-961f-82ee72b054a4>2007-02-05 20:56:47 +0000
committerkseitz <kseitz@138bc75d-0d04-0410-961f-82ee72b054a4>2007-02-05 20:56:47 +0000
commit15b3f4099d549c102dddb15df7fd1261bdbb8e0d (patch)
tree2c5613f6f2c49e3a9f83cfa420f131521a3f640c /libjava
parent2a6b4c77546b2f5d0214730c3247184a3986bde5 (diff)
downloadgcc-15b3f4099d549c102dddb15df7fd1261bdbb8e0d.tar.gz
* gnu/classpath/jdwp/natVMVirtualMachine.cc
(registerEvent): Implement EVENT_BREAKPOINT. (unregisterEvent): Likewise. (get_request_location): New function. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121608 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava')
-rw-r--r--libjava/ChangeLog7
-rw-r--r--libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc95
2 files changed, 101 insertions, 1 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index a28144266dc..f94ac741f3b 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,10 @@
+2007-02-05 Keith Seitz <keiths@redhat.com>
+
+ * gnu/classpath/jdwp/natVMVirtualMachine.cc
+ (registerEvent): Implement EVENT_BREAKPOINT.
+ (unregisterEvent): Likewise.
+ (get_request_location): New function.
+
2007-02-05 Matthias Klose <doko@debian.org>
testsuite/Makefile.am (compile-tests): Fix typo.
diff --git a/libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc b/libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc
index 3966e852fb8..208e689b79d 100644
--- a/libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc
+++ b/libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc
@@ -10,6 +10,7 @@ details. */
#include <config.h>
#include <gcj/cni.h>
+#include <java-assert.h>
#include <jvm.h>
#include <jvmti.h>
@@ -21,6 +22,7 @@ details. */
#include <java/lang/Thread.h>
#include <java/nio/ByteBuffer.h>
#include <java/util/ArrayList.h>
+#include <java/util/Collection.h>
#include <java/util/Hashtable.h>
#include <java/util/Iterator.h>
@@ -29,20 +31,28 @@ details. */
#include <gnu/classpath/jdwp/VMMethod.h>
#include <gnu/classpath/jdwp/VMVirtualMachine.h>
#include <gnu/classpath/jdwp/event/ClassPrepareEvent.h>
+#include <gnu/classpath/jdwp/event/EventManager.h>
#include <gnu/classpath/jdwp/event/EventRequest.h>
#include <gnu/classpath/jdwp/event/ThreadEndEvent.h>
#include <gnu/classpath/jdwp/event/ThreadStartEvent.h>
#include <gnu/classpath/jdwp/event/VmDeathEvent.h>
#include <gnu/classpath/jdwp/event/VmInitEvent.h>
+#include <gnu/classpath/jdwp/event/filters/IEventFilter.h>
+#include <gnu/classpath/jdwp/event/filters/LocationOnlyFilter.h>
+#include <gnu/classpath/jdwp/exception/InvalidLocationException.h>
#include <gnu/classpath/jdwp/exception/InvalidMethodException.h>
#include <gnu/classpath/jdwp/exception/JdwpInternalErrorException.h>
+#include <gnu/classpath/jdwp/util/Location.h>
#include <gnu/classpath/jdwp/util/MethodResult.h>
+#include <gnu/gcj/jvmti/Breakpoint.h>
+#include <gnu/gcj/jvmti/BreakpointManager.h>
using namespace java::lang;
using namespace gnu::classpath::jdwp::event;
using namespace gnu::classpath::jdwp::util;
// Forward declarations
+static Location *get_request_location (EventRequest *);
static void JNICALL jdwpClassPrepareCB (jvmtiEnv *, JNIEnv *, jthread, jclass);
static void JNICALL jdwpThreadEndCB (jvmtiEnv *, JNIEnv *, jthread);
static void JNICALL jdwpThreadStartCB (jvmtiEnv *, JNIEnv *, jthread);
@@ -189,7 +199,29 @@ gnu::classpath::jdwp::VMVirtualMachine::registerEvent (EventRequest *request)
break;
case EventRequest::EVENT_BREAKPOINT:
- break;
+ {
+ using namespace ::gnu::gcj::jvmti;
+ Location *loc = get_request_location (request);
+ if (loc == NULL)
+ {
+ using namespace gnu::classpath::jdwp::exception;
+ throw new InvalidLocationException ();
+ }
+
+ jlong method = loc->getMethod ()->getId ();
+ jlocation index = loc->getIndex ();
+ Breakpoint *bp = BreakpointManager::getBreakpoint (method, index);
+ if (bp == NULL)
+ {
+ // Breakpoint not in interpreter yet
+ bp = BreakpointManager::newBreakpoint (method, index);
+ }
+ else
+ {
+ // Ignore the duplicate
+ }
+ }
+ break;
case EventRequest::EVENT_FRAME_POP:
break;
@@ -244,6 +276,46 @@ gnu::classpath::jdwp::VMVirtualMachine::unregisterEvent (EventRequest *request)
break;
case EventRequest::EVENT_BREAKPOINT:
+ {
+ using namespace gnu::gcj::jvmti;
+ ::java::util::Collection *breakpoints;
+ EventManager *em = EventManager::getDefault ();
+ breakpoints = em->getRequests (EventRequest::EVENT_BREAKPOINT);
+
+ // Check for duplicates
+ int matches = 0;
+ Location *the_location = get_request_location (request);
+
+ // This should not be possible: we REQUIRE a Location
+ // to install a breakpoint
+ JvAssert (the_location != NULL);
+
+ ::java::util::Iterator *iter = breakpoints->iterator ();
+ while (iter->hasNext ())
+ {
+ EventRequest *er
+ = reinterpret_cast<EventRequest *> (iter->next ());
+ Location *loc = get_request_location (er);
+ JvAssert (loc != NULL);
+ if (loc->equals (the_location) && ++matches == 2)
+ {
+ // Short-circuit: already more than one breakpoint
+ return;
+ }
+ }
+
+ if (matches == 0)
+ {
+ using namespace gnu::classpath::jdwp::exception;
+ jstring msg
+ = JvNewStringLatin1 ("attempt to remove unknown breakpoint");
+ throw new JdwpInternalErrorException (msg);
+ }
+
+ jlong methodId = the_location->getMethod ()->getId ();
+ BreakpointManager::deleteBreakpoint (methodId,
+ the_location->getIndex ());
+ }
break;
case EventRequest::EVENT_FRAME_POP:
@@ -410,6 +482,27 @@ getSourceFile (MAYBE_UNUSED jclass clazz)
return NULL;
}
+static Location *
+get_request_location (EventRequest *request)
+{
+ Location *loc = NULL;
+ ::java::util::Collection *filters = request->getFilters ();
+ ::java::util::Iterator *iter = filters->iterator ();
+ while (iter->hasNext ())
+ {
+ using namespace gnu::classpath::jdwp::event::filters;
+ IEventFilter *filter = (IEventFilter *) iter->next ();
+ if (filter->getClass () == &LocationOnlyFilter::class$)
+ {
+ LocationOnlyFilter *lof
+ = reinterpret_cast<LocationOnlyFilter *> (filter);
+ loc = lof->getLocation ();
+ }
+ }
+
+ return loc;
+}
+
static void
throw_jvmti_error (jvmtiError err)
{