libcorkscrew native stacks, mutex ranking, and better ScopedThreadListLock.

This change uses libcorkscrew to show native stacks for threads in kNative or,
unlike dalvikvm, kVmWait --- working on the runtime directly I've found it
somewhat useful to be able to see _which_ internal resource we're waiting on.
We can always take that back out (or make it oatexecd-only) if it turns out to
be too noisy/confusing for app developers.

This change also lets us rank mutexes and enforce -- in oatexecd -- that you
take locks in a specific order.

Both of these helped me test the third novelty: removing the heap locking from
ScopedThreadListLock. I've manually inspected all the callers and added a
ScopedHeapLock where I think one is necessary. In manual testing, this makes
jdb a lot less prone to locking us up. There still seems to be a problem with
the JDWP VirtualMachine.Resume command, but I'll look at that separately. This
is a big enough and potentially disruptive enough change already.

Change-Id: Iad974358919d0e00674662dc8a69cc65878cfb5c
diff --git a/src/thread.cc b/src/thread.cc
index 74107d5..1c521c1 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -404,6 +404,7 @@
     }
     os << GetState()
        << ",Thread*=" << this
+       << ",peer=" << peer_
        << ",\"" << *name_ << "\""
        << "]";
   }
@@ -438,6 +439,10 @@
   return (peer_ != NULL) ? reinterpret_cast<String*>(gThread_name->GetObject(peer_)) : NULL;
 }
 
+void Thread::GetThreadName(std::string& name) const {
+  name.assign(*name_);
+}
+
 void Thread::DumpState(std::ostream& os) const {
   std::string group_name;
   int priority;
@@ -586,6 +591,10 @@
 };
 
 void Thread::DumpStack(std::ostream& os) const {
+  // If we're currently in native code, dump that stack before dumping the managed stack.
+  if (GetState() == Thread::kNative || GetState() == Thread::kVmWait) {
+    DumpNativeStack(os);
+  }
   StackDumpVisitor dumper(os, this);
   WalkStack(&dumper);
 }
@@ -681,7 +690,7 @@
 static void ReportThreadSuspendTimeout(Thread* waiting_thread) {
   Runtime* runtime = Runtime::Current();
   std::ostringstream ss;
-  ss << "Thread suspend timeout; waiting thread=" << *waiting_thread << "\n";
+  ss << "Thread suspend timeout waiting for thread " << *waiting_thread << "\n";
   runtime->DumpLockHolders(ss);
   ss << "\n";
   runtime->GetThreadList()->DumpLocked(ss);
@@ -841,6 +850,7 @@
       trace_stack_(new std::vector<TraceStackFrame>),
       name_(new std::string("<native thread without managed peer>")) {
   CHECK_EQ((sizeof(Thread) % 4), 0U) << sizeof(Thread);
+  memset(&held_mutexes_[0], 0, sizeof(held_mutexes_));
 }
 
 void MonitorExitVisitor(const Object* object, void*) {
@@ -1664,4 +1674,23 @@
   return os;
 }
 
+void Thread::CheckRank(MutexRank rank, bool is_locking) {
+  if (is_locking) {
+    if (held_mutexes_[rank] == 0) {
+      bool bad_mutexes_held = false;
+      for (int i = kMaxMutexRank; i > rank; --i) {
+        if (held_mutexes_[i] != 0) {
+          LOG(ERROR) << "holding " << static_cast<MutexRank>(i) << " while " << (is_locking ? "locking" : "unlocking") << " " << rank;
+          bad_mutexes_held = true;
+        }
+      }
+      CHECK(!bad_mutexes_held);
+    }
+    ++held_mutexes_[rank];
+  } else {
+    CHECK_GT(held_mutexes_[rank], 0U);
+    --held_mutexes_[rank];
+  }
+}
+
 }  // namespace art