Implement ThreadReference.OwnedMonitorsStackDepthInfo.

Change-Id: I5e1ac7b2aeef7b1eac9518eba14a8f6555acd712
diff --git a/src/debugger.cc b/src/debugger.cc
index 8724327..1ddb525 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -669,7 +669,9 @@
   return JDWP::ERR_NONE;
 }
 
-JDWP::JdwpError Dbg::GetOwnedMonitors(JDWP::ObjectId thread_id, std::vector<JDWP::ObjectId>& monitors)
+JDWP::JdwpError Dbg::GetOwnedMonitors(JDWP::ObjectId thread_id,
+                                      std::vector<JDWP::ObjectId>& monitors,
+                                      std::vector<uint32_t>& stack_depths)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   ScopedObjectAccessUnchecked soa(Thread::Current());
   MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
@@ -686,28 +688,34 @@
     OwnedMonitorVisitor(const ManagedStack* stack,
                         const std::deque<InstrumentationStackFrame>* instrumentation_stack)
         SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-        : StackVisitor(stack, instrumentation_stack, NULL) {}
+        : StackVisitor(stack, instrumentation_stack, NULL), current_stack_depth(0) {}
 
     // TODO: Enable annotalysis. We know lock is held in constructor, but abstraction confuses
     // annotalysis.
     bool VisitFrame() NO_THREAD_SAFETY_ANALYSIS {
       if (!GetMethod()->IsRuntimeMethod()) {
         Monitor::VisitLocks(this, AppendOwnedMonitors, this);
+        ++current_stack_depth;
       }
       return true;
     }
 
     static void AppendOwnedMonitors(Object* owned_monitor, void* context) {
-      reinterpret_cast<OwnedMonitorVisitor*>(context)->monitors.push_back(owned_monitor);
+      OwnedMonitorVisitor* visitor = reinterpret_cast<OwnedMonitorVisitor*>(context);
+      visitor->monitors.push_back(owned_monitor);
+      visitor->stack_depths.push_back(visitor->current_stack_depth);
     }
 
+    size_t current_stack_depth;
     std::vector<Object*> monitors;
+    std::vector<uint32_t> stack_depths;
   };
   OwnedMonitorVisitor visitor(thread->GetManagedStack(), thread->GetInstrumentationStack());
   visitor.WalkStack();
 
   for (size_t i = 0; i < visitor.monitors.size(); ++i) {
     monitors.push_back(gRegistry->Add(visitor.monitors[i]));
+    stack_depths.push_back(visitor.stack_depths[i]);
   }
 
   return JDWP::ERR_NONE;
diff --git a/src/debugger.h b/src/debugger.h
index b033ace..1acd09b 100644
--- a/src/debugger.h
+++ b/src/debugger.h
@@ -153,7 +153,9 @@
 
   static JDWP::JdwpError GetMonitorInfo(JDWP::ObjectId object_id, JDWP::ExpandBuf* reply)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  static JDWP::JdwpError GetOwnedMonitors(JDWP::ObjectId thread_id, std::vector<JDWP::ObjectId>& monitors)
+  static JDWP::JdwpError GetOwnedMonitors(JDWP::ObjectId thread_id,
+                                          std::vector<JDWP::ObjectId>& monitors,
+                                          std::vector<uint32_t>& stack_depths)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static JDWP::JdwpError GetContendedMonitor(JDWP::ObjectId thread_id, JDWP::ObjectId& contended_monitor)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/src/jdwp/jdwp_handler.cc b/src/jdwp/jdwp_handler.cc
index f0bb0b8..94aff1c 100644
--- a/src/jdwp/jdwp_handler.cc
+++ b/src/jdwp/jdwp_handler.cc
@@ -395,7 +395,7 @@
   expandBufAdd1(reply, false);   // canSetDefaultStratum
   expandBufAdd1(reply, false);   // 1.6: canGetInstanceInfo
   expandBufAdd1(reply, false);   // 1.6: canRequestMonitorEvents
-  expandBufAdd1(reply, false);   // 1.6: canGetMonitorFrameInfo
+  expandBufAdd1(reply, true);    // 1.6: canGetMonitorFrameInfo
   expandBufAdd1(reply, false);   // 1.6: canUseSourceNameFilters
   expandBufAdd1(reply, false);   // 1.6: canGetConstantPool
   expandBufAdd1(reply, false);   // 1.6: canForceEarlyReturn
@@ -1059,12 +1059,13 @@
   return ERR_NONE;
 }
 
-static JdwpError TR_OwnedMonitors(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
+static JdwpError TR_OwnedMonitors(const uint8_t* buf, ExpandBuf* reply, bool with_stack_depths)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   ObjectId thread_id = ReadObjectId(&buf);
 
   std::vector<ObjectId> monitors;
-  JdwpError rc = Dbg::GetOwnedMonitors(thread_id, monitors);
+  std::vector<uint32_t> stack_depths;
+  JdwpError rc = Dbg::GetOwnedMonitors(thread_id, monitors, stack_depths);
   if (rc != ERR_NONE) {
     return rc;
   }
@@ -1075,10 +1076,23 @@
     if (rc != ERR_NONE) {
       return rc;
     }
+    if (with_stack_depths) {
+      expandBufAdd4BE(reply, stack_depths[i]);
+    }
   }
   return ERR_NONE;
 }
 
+static JdwpError TR_OwnedMonitors(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  return TR_OwnedMonitors(buf, reply, false);
+}
+
+static JdwpError TR_OwnedMonitorsStackDepthInfo(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  return TR_OwnedMonitors(buf, reply, true);
+}
+
 static JdwpError TR_CurrentContendedMonitor(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   ObjectId thread_id = ReadObjectId(&buf);
@@ -1618,20 +1632,20 @@
   { 10,   1,  SR_Value,         "StringReference.Value" },
 
   /* ThreadReference command set (11) */
-  { 11,   1,  TR_Name,                    "ThreadReference.Name" },
-  { 11,   2,  TR_Suspend,                 "ThreadReference.Suspend" },
-  { 11,   3,  TR_Resume,                  "ThreadReference.Resume" },
-  { 11,   4,  TR_Status,                  "ThreadReference.Status" },
-  { 11,   5,  TR_ThreadGroup,             "ThreadReference.ThreadGroup" },
-  { 11,   6,  TR_Frames,                  "ThreadReference.Frames" },
-  { 11,   7,  TR_FrameCount,              "ThreadReference.FrameCount" },
-  { 11,   8,  TR_OwnedMonitors,           "ThreadReference.OwnedMonitors" },
-  { 11,   9,  TR_CurrentContendedMonitor, "ThreadReference.CurrentContendedMonitor" },
-  { 11,   10, NULL,                       "ThreadReference.Stop" },
-  { 11,   11, TR_Interrupt,               "ThreadReference.Interrupt" },
-  { 11,   12, TR_DebugSuspendCount,       "ThreadReference.SuspendCount" },
-  { 11,   13, NULL,                       "ThreadReference.OwnedMonitorsStackDepthInfo" },
-  { 11,   14, NULL,                       "ThreadReference.ForceEarlyReturn" },
+  { 11,   1,  TR_Name,                        "ThreadReference.Name" },
+  { 11,   2,  TR_Suspend,                     "ThreadReference.Suspend" },
+  { 11,   3,  TR_Resume,                      "ThreadReference.Resume" },
+  { 11,   4,  TR_Status,                      "ThreadReference.Status" },
+  { 11,   5,  TR_ThreadGroup,                 "ThreadReference.ThreadGroup" },
+  { 11,   6,  TR_Frames,                      "ThreadReference.Frames" },
+  { 11,   7,  TR_FrameCount,                  "ThreadReference.FrameCount" },
+  { 11,   8,  TR_OwnedMonitors,               "ThreadReference.OwnedMonitors" },
+  { 11,   9,  TR_CurrentContendedMonitor,     "ThreadReference.CurrentContendedMonitor" },
+  { 11,   10, NULL,                           "ThreadReference.Stop" },
+  { 11,   11, TR_Interrupt,                   "ThreadReference.Interrupt" },
+  { 11,   12, TR_DebugSuspendCount,           "ThreadReference.SuspendCount" },
+  { 11,   13, TR_OwnedMonitorsStackDepthInfo, "ThreadReference.OwnedMonitorsStackDepthInfo" },
+  { 11,   14, NULL,                           "ThreadReference.ForceEarlyReturn" },
 
   /* ThreadGroupReference command set (12) */
   { 12,   1,  TGR_Name,         "ThreadGroupReference.Name" },