* gnu/classpath/jdwp/VMVirtualMachine.java
authorKeith Seitz <keiths@redhat.com>
Fri, 9 Feb 2007 18:43:21 +0000 (18:43 +0000)
committerKeith Seitz <kseitz@gcc.gnu.org>
Fri, 9 Feb 2007 18:43:21 +0000 (18:43 +0000)
        (_stepping_threads): New member.
        * classpath/lib/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.

From-SVN: r121769

libjava/ChangeLog
libjava/classpath/lib/gnu/classpath/jdwp/VMVirtualMachine.class
libjava/gnu/classpath/jdwp/VMVirtualMachine.h
libjava/gnu/classpath/jdwp/VMVirtualMachine.java
libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc

index 5c228fb9073eb1789e1cfb05c6c7bb0633cdedf5..c403efbb7a872308e83b3483c28586bb53e9f1c9 100644 (file)
@@ -1,3 +1,18 @@
+2007-02-09  Keith Seitz  <keiths@redhat.com>
+
+       * gnu/classpath/jdwp/VMVirtualMachine.java
+       (_stepping_threads): New member.
+       * classpath/lib/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.
+
 2007-02-08  Keith Seitz  <keiths@redhat.com>
 
        * sources.am: Regenerate.
index 526d30b221bf829075c7ce6745eeab2fa424dbf7..f48b6eb890ad060e4b41d8b0cbef1ab7dafd0ad8 100644 (file)
Binary files a/libjava/classpath/lib/gnu/classpath/jdwp/VMVirtualMachine.class and b/libjava/classpath/lib/gnu/classpath/jdwp/VMVirtualMachine.class differ
index b90b476c04bc673867851266cc1a75def2d9e41d..456053a6565f207e51df25f0124b4506fc5d6f4e 100644 (file)
@@ -59,6 +59,8 @@ public:
   static void clearEvents (jbyte);
 private:
   static ::java::util::Hashtable *_jdwp_suspend_counts;
+public: // actually package-private
+  static ::java::util::Hashtable * _stepping_threads;
 public:
 
   static ::java::lang::Class class$;
index 1b0f7f6fa3c4d67fe7496937f21094441d71a8f2..da0fef28c10287ea94589a08dfeeb95a67d64556 100644 (file)
@@ -61,6 +61,9 @@ public class VMVirtualMachine
   // 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 ab11b3ed299bfb916ea6f86460a2274aa1cc19b9..e06daa7bb24285592589706cc1dce6f95ee06d33 100644 (file)
@@ -11,6 +11,7 @@ details. */
 #include <config.h>
 #include <gcj/cni.h>
 #include <java-assert.h>
+#include <java-interp.h>
 #include <jvm.h>
 #include <jvmti.h>
 
@@ -42,10 +43,12 @@ details. */
 #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/InvalidFrameException.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>
@@ -55,8 +58,19 @@ using namespace java::lang;
 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);
@@ -65,6 +79,9 @@ static void JNICALL jdwpVMInitCB (jvmtiEnv *, JNIEnv *, jthread);
 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)
@@ -81,6 +98,8 @@ void
 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);
 
@@ -200,6 +219,32 @@ gnu::classpath::jdwp::VMVirtualMachine::registerEvent (EventRequest *request)
   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:
@@ -225,7 +270,7 @@ gnu::classpath::jdwp::VMVirtualMachine::registerEvent (EventRequest *request)
            // Ignore the duplicate
          }
       }
-     break;
+      break;
 
     case EventRequest::EVENT_FRAME_POP:
       break;
@@ -277,6 +322,19 @@ gnu::classpath::jdwp::VMVirtualMachine::unregisterEvent (EventRequest *request)
   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:
@@ -527,6 +585,26 @@ getSourceFile (MAYBE_UNUSED jclass clazz)
   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)
 {