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" },