Print mutexes held in Thread::Dump.

Should help finding and fixing thread suspend timeout issues.

Bug: 15328839
Change-Id: I30a10529cec0716c7571a0318e9f66be54734fd8
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index a962f06..45db4a6 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -2452,7 +2452,7 @@
 }
 
 size_t Heap::GetPercentFree() {
-  return static_cast<size_t>(100.0f * static_cast<float>(GetFreeMemory()) / GetTotalMemory());
+  return static_cast<size_t>(100.0f * static_cast<float>(GetFreeMemory()) / GetMaxMemory());
 }
 
 void Heap::SetIdealFootprint(size_t max_allowed_footprint) {
diff --git a/runtime/thread.cc b/runtime/thread.cc
index f89fada..3bfdc3f 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -824,6 +824,26 @@
     os << "  | stack=" << reinterpret_cast<void*>(thread->tlsPtr_.stack_begin) << "-"
         << reinterpret_cast<void*>(thread->tlsPtr_.stack_end) << " stackSize="
         << PrettySize(thread->tlsPtr_.stack_size) << "\n";
+    // Dump the held mutexes.
+    os << "  | held mutexes=";
+    for (size_t i = 0; i < kLockLevelCount; ++i) {
+      if (i != kMonitorLock) {
+        BaseMutex* mutex = thread->GetHeldMutex(static_cast<LockLevel>(i));
+        if (mutex != nullptr) {
+          os << " \"" << mutex->GetName() << "\"";
+          if (mutex->IsReaderWriterMutex()) {
+            ReaderWriterMutex* rw_mutex = down_cast<ReaderWriterMutex*>(mutex);
+            if (rw_mutex->IsExclusiveHeld(thread)) {
+              os << "(exclusive held)";
+            } else {
+              CHECK(rw_mutex->IsSharedHeld(thread));
+              os << "(shared held)";
+            }
+          }
+        }
+      }
+    }
+    os << "\n";
   }
 }
 
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index 388c9b4..d20a459 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -158,8 +158,6 @@
   Runtime* runtime = Runtime::Current();
   std::ostringstream ss;
   ss << "Thread suspend timeout\n";
-  runtime->DumpLockHolders(ss);
-  ss << "\n";
   runtime->GetThreadList()->DumpLocked(ss);
   LOG(FATAL) << ss.str();
   exit(0);