This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] [Un]Register single step


Hi,

The attached patch implements the JDWP side of single step event registration (and "unregistration"). Most of what it does is simply massaging data received from the JDWP backend (in classpath) and store it in a more useful form (along with some new data) to facilitate decision making during single stepping. [You get to see how that's done when I submit the related callback function.]

Comments/questions/concerns?

Keith

ChangeLog
2007-02-08  Keith Seitz  <keiths@redhat.com>

        * gnu/classpath/jdwp/VMVirtualMachine.java
        (_stepping_threads): New member.
        * gnu/classpath/jdwp/VMVirtualMachine.class:
        Regenerated.
        * gnu/classpath/jdwp/VMVirtualMachine.h:
        Regenerated.
        * gnu/claspath/jdwp/natVMVirtualMachine.cc
        (get_request_step_filter): New function.
        (DISABLE_EVENT): New macro.
        (initialize): Initialize _stepping_threads.
        (registerEvent): Implement EVENT_SINGLE_STEP.
        (unregisterEvent): Likewise.
Index: gnu/classpath/jdwp/VMVirtualMachine.java
===================================================================
--- gnu/classpath/jdwp/VMVirtualMachine.java	(revision 121716)
+++ gnu/classpath/jdwp/VMVirtualMachine.java	(working copy)
@@ -1,7 +1,7 @@
 /* VMVirtualMachine.java -- A reference implementation of a JDWP virtual
    machine
 
-   Copyright (C) 2005, 2006 Free Software Foundation
+   Copyright (C) 2005, 2006, 2007 Free Software Foundation
 
 This file is part of GNU Classpath.
 
@@ -61,6 +61,9 @@
   // Thread suspension table. Maps Thread to suspend count (Integer)
   private static Hashtable _jdwp_suspend_counts;
 
+  // List of stepping threads: maps Thread -> stepping info
+  static Hashtable _stepping_threads;
+  
   public static native void initialize ();
 
   /**
Index: gnu/classpath/jdwp/natVMVirtualMachine.cc
===================================================================
--- gnu/classpath/jdwp/natVMVirtualMachine.cc	(revision 121716)
+++ gnu/classpath/jdwp/natVMVirtualMachine.cc	(working copy)
@@ -11,6 +11,7 @@
 #include <config.h>
 #include <gcj/cni.h>
 #include <java-assert.h>
+#include <java-interp.h>
 #include <jvm.h>
 #include <jvmti.h>
 
@@ -39,9 +40,11 @@
 #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/event/filters/StepFilter.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/id/ThreadId.h>
 #include <gnu/classpath/jdwp/util/Location.h>
 #include <gnu/classpath/jdwp/util/MethodResult.h>
 #include <gnu/gcj/jvmti/Breakpoint.h>
@@ -51,8 +54,19 @@
 using namespace gnu::classpath::jdwp::event;
 using namespace gnu::classpath::jdwp::util;
 
+// Stepping information
+struct step_info
+{
+  jint size;   // See gnu.classpath.jdwp.JdwpConstants.StepSize
+  jint depth;  // See gnu.classpath.jdwp.JdwpConstants.StepDepth
+  int stack_depth;  // stack depth at start of stepping
+  jmethodID method; // method in which we are stepping
+};
+
 // Forward declarations
 static Location *get_request_location (EventRequest *);
+static gnu::classpath::jdwp::event::filters::StepFilter *
+get_request_step_filter (EventRequest *);
 static void JNICALL jdwpClassPrepareCB (jvmtiEnv *, JNIEnv *, jthread, jclass);
 static void JNICALL jdwpThreadEndCB (jvmtiEnv *, JNIEnv *, jthread);
 static void JNICALL jdwpThreadStartCB (jvmtiEnv *, JNIEnv *, jthread);
@@ -61,6 +75,9 @@
 static void throw_jvmti_error (jvmtiError);
 
 #define DEFINE_CALLBACK(Cb,Event) Cb.Event = jdwp ## Event ## CB
+#define DISABLE_EVENT(Event,Thread)					\
+  _jdwp_jvmtiEnv->SetEventNotificationMode (JVMTI_DISABLE,		\
+					    JVMTI_EVENT_ ## Event, Thread)
 #define ENABLE_EVENT(Event,Thread)					\
   _jdwp_jvmtiEnv->SetEventNotificationMode (JVMTI_ENABLE,		\
 					    JVMTI_EVENT_ ## Event, Thread)
@@ -77,6 +94,8 @@
 gnu::classpath::jdwp::VMVirtualMachine::initialize ()
 {
   _jdwp_suspend_counts = new ::java::util::Hashtable ();
+  _stepping_threads = new ::java::util::Hashtable ();
+
   JavaVM *vm = _Jv_GetJavaVM ();
   vm->GetEnv (reinterpret_cast<void **> (&_jdwp_jvmtiEnv), JVMTI_VERSION_1_0);
 
@@ -196,6 +215,32 @@
   switch (request->getEventKind ())
     {
     case EventRequest::EVENT_SINGLE_STEP:
+      {
+	Thread *thread;
+	filters::StepFilter *filter = get_request_step_filter (request);
+	if (filter == NULL)
+	  {
+	    // No filter specified: report every step in every
+	    // thread.
+	    thread = NULL;
+	  }
+	else
+	  {
+	    // Add stepping information to list of stepping threads
+	    thread = filter->getThread ()->getThread ();
+	    _Jv_InterpFrame *frame
+	      = reinterpret_cast<_Jv_InterpFrame *> (thread->interp_frame);
+	    struct step_info *sinfo
+	      = (struct step_info *) JvAllocBytes (sizeof (struct step_info));
+	    sinfo->size = filter->getSize ();
+	    sinfo->depth = filter->getDepth ();
+	    sinfo->stack_depth = frame->depth ();
+	    sinfo->method = frame->self->get_method ();
+	    _stepping_threads->put (thread, (jobject) sinfo);
+	  }
+
+	ENABLE_EVENT (SINGLE_STEP, thread);
+      }
       break;
 
     case EventRequest::EVENT_BREAKPOINT:
@@ -273,6 +318,19 @@
   switch (request->getEventKind ())
     {
     case EventRequest::EVENT_SINGLE_STEP:
+      {
+	Thread *thread;
+	filters::StepFilter *filter = get_request_step_filter (request);
+	if (filter == NULL)
+	  thread = NULL;
+	else
+	  {
+	    thread = filter->getThread ()->getThread ();
+	    _stepping_threads->remove (thread);
+	  }
+
+	DISABLE_EVENT (SINGLE_STEP, thread);
+      }
       break;
 
     case EventRequest::EVENT_BREAKPOINT:
@@ -482,6 +540,26 @@
   return NULL;
 }
 
+static gnu::classpath::jdwp::event::filters::StepFilter *
+get_request_step_filter (EventRequest *request)
+{
+  ::java::util::Collection *filters = request->getFilters ();
+  ::java::util::Iterator *iter = filters->iterator ();
+  filters::StepFilter *filter = NULL;
+  while (iter->hasNext ())
+    {
+      using namespace gnu::classpath::jdwp::event::filters;
+      IEventFilter *next = (IEventFilter *) iter->next ();
+      if (next->getClass () == &StepFilter::class$)
+	{
+	  filter = reinterpret_cast<StepFilter *> (next);
+	  break;
+	}
+    }
+
+  return filter;
+}
+
 static Location *
 get_request_location (EventRequest *request)
 {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]