Add the "- waiting on"/"- waiting to lock" lines to the SIGQUIT output.

Change-Id: I0a8ab2e9e54c390e0d499ef464d82c2f2c628cbe
diff --git a/src/monitor.cc b/src/monitor.cc
index 7d6cde4..4e71e45 100644
--- a/src/monitor.cc
+++ b/src/monitor.cc
@@ -27,6 +27,7 @@
 #include "mutex.h"
 #include "object.h"
 #include "thread.h"
+#include "thread_list.h"
 
 namespace art {
 
@@ -638,6 +639,7 @@
 
   // Allocate and acquire a new monitor.
   Monitor* m = new Monitor(obj);
+  LOG(INFO) << "created monitor " << m << " for object " << obj;
   // Replace the head of the list with the new monitor.
   do {
     m->next_ = gMonitorList;
@@ -699,6 +701,7 @@
     } else {
       LOG(INFO) << StringPrintf("(%d) spin on lock %p: %#x (%#x) %#x", threadId, thinp, 0, *thinp, thin);
       // The lock is owned by another thread. Notify the VM that we are about to wait.
+      self->monitor_enter_object_ = obj;
       Thread::State oldStatus = self->SetState(Thread::kBlocked);
       // Spin until the thin lock is released or inflated.
       sleepDelayNs = 0;
@@ -736,12 +739,14 @@
           // The thin lock was inflated by another thread. Let the VM know we are no longer
           // waiting and try again.
           LOG(INFO) << "(" << threadId << ") lock " << (void*) thinp << " surprise-fattened";
+          self->monitor_enter_object_ = NULL;
           self->SetState(oldStatus);
           goto retry;
         }
       }
       LOG(INFO) << StringPrintf("(%d) spin on lock done %p: %#x (%#x) %#x", threadId, thinp, 0, *thinp, thin);
       // We have acquired the thin lock. Let the VM know that we are no longer waiting.
+      self->monitor_enter_object_ = NULL;
       self->SetState(oldStatus);
       // Fatten the lock.
       Inflate(self, obj);
@@ -885,4 +890,39 @@
   }
 }
 
+void Monitor::DescribeWait(std::ostream& os, const Thread* thread) {
+  Thread::State state = thread->GetState();
+
+  Object* object = NULL;
+  uint32_t lock_owner = ThreadList::kInvalidId;
+  if (state == Thread::kWaiting || state == Thread::kTimedWaiting) {
+    os << "  - waiting on ";
+    Monitor* monitor = thread->wait_monitor_;
+    if (monitor != NULL) {
+      object = monitor->obj_;
+    }
+    lock_owner = Thread::LockOwnerFromThreadLock(object);
+  } else if (state == Thread::kBlocked) {
+    os << "  - waiting to lock ";
+    object = thread->monitor_enter_object_;
+    if (object != NULL) {
+      lock_owner = object->GetLockOwner();
+    }
+  } else {
+    // We're not waiting on anything.
+    return;
+  }
+  os << "<" << object << ">";
+
+  // - waiting on <0x613f83d8> (a java.lang.ThreadLock) held by thread 5
+  // - waiting on <0x6008c468> (a java.lang.Class<java.lang.ref.ReferenceQueue>)
+  os << " (a " << PrettyTypeOf(object) << ")";
+
+  if (lock_owner != ThreadList::kInvalidId) {
+    os << " held by thread " << lock_owner;
+  }
+
+  os << "\n";
+}
+
 }  // namespace art