Do less work holding thread list lock

Avoid doing stuff that requires access java heap like PrettyMethod.
Fixes lock violation.

Bug: 28268478

(cherry picked from commit dee19e3caaeb5666055842d656dc0516b901f30c)

Change-Id: Ie090879690df7a6db15a9c8b7e82f3809450d653
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index ed6a8e4..3680c78 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -215,20 +215,18 @@
   obj_ = GcRoot<mirror::Object>(object);
 }
 
-std::string Monitor::PrettyContentionInfo(Thread* owner,
+std::string Monitor::PrettyContentionInfo(const std::string& owner_name,
+                                          pid_t owner_tid,
                                           ArtMethod* owners_method,
                                           uint32_t owners_dex_pc,
                                           size_t num_waiters) {
-  DCHECK(owner != nullptr);
   const char* owners_filename;
   int32_t owners_line_number = 0;
-  std::string name;
-  owner->GetThreadName(name);
   if (owners_method != nullptr) {
     TranslateLocation(owners_method, owners_dex_pc, &owners_filename, &owners_line_number);
   }
   std::ostringstream oss;
-  oss << "monitor contention with owner " << name << " (" << owner->GetTid() << ")";
+  oss << "monitor contention with owner " << owner_name << " (" << owner_tid << ")";
   if (owners_method != nullptr) {
     oss << " owner method=" << PrettyMethod(owners_method);
     oss << " from " << owners_filename << ":" << owners_line_number;
@@ -273,7 +271,13 @@
           original_owner_thread_id = owner_->GetThreadId();
           if (ATRACE_ENABLED()) {
             std::ostringstream oss;
-            oss << PrettyContentionInfo(owner_, owners_method, owners_dex_pc, num_waiters);
+            std::string name;
+            owner_->GetThreadName(name);
+            oss << PrettyContentionInfo(name,
+                                        owner_->GetTid(),
+                                        owners_method,
+                                        owners_dex_pc,
+                                        num_waiters);
             // Add info for contending thread.
             uint32_t pc;
             ArtMethod* m = self->GetCurrentMethod(&pc);
@@ -290,11 +294,21 @@
       if (original_owner_thread_id != 0u) {
         // Woken from contention.
         if (log_contention) {
-          MutexLock mu2(Thread::Current(), *Locks::thread_list_lock_);
-          // Re-find the owner in case the thread got killed.
-          Thread* original_owner = Runtime::Current()->GetThreadList()->FindThreadByThreadId(
-              original_owner_thread_id);
-          if (original_owner != nullptr) {
+          uint32_t original_owner_tid = 0;
+          std::string original_owner_name;
+          {
+            MutexLock mu2(Thread::Current(), *Locks::thread_list_lock_);
+            // Re-find the owner in case the thread got killed.
+            Thread* original_owner = Runtime::Current()->GetThreadList()->FindThreadByThreadId(
+                original_owner_thread_id);
+            // Do not do any work that requires the mutator lock.
+            if (original_owner != nullptr) {
+              original_owner_tid = original_owner->GetTid();
+              original_owner->GetThreadName(original_owner_name);
+            }
+          }
+
+          if (original_owner_tid != 0u) {
             uint64_t wait_ms = MilliTime() - wait_start_ms;
             uint32_t sample_percent;
             if (wait_ms >= lock_profiling_threshold_) {
@@ -306,7 +320,8 @@
               if (wait_ms > kLongWaitMs && owners_method != nullptr) {
                 // TODO: We should maybe check that original_owner is still a live thread.
                 LOG(WARNING) << "Long "
-                    << PrettyContentionInfo(original_owner,
+                    << PrettyContentionInfo(original_owner_name,
+                                            original_owner_tid,
                                             owners_method,
                                             owners_dex_pc,
                                             num_waiters)
@@ -433,11 +448,13 @@
 
 bool Monitor::Unlock(Thread* self) {
   DCHECK(self != nullptr);
-  uint32_t owner_thread_id;
+  uint32_t owner_thread_id = 0u;
   {
     MutexLock mu(self, monitor_lock_);
     Thread* owner = owner_;
-    owner_thread_id = owner->GetThreadId();
+    if (owner != nullptr) {
+      owner_thread_id = owner->GetThreadId();
+    }
     if (owner == self) {
       // We own the monitor, so nobody else can be in here.
       if (lock_count_ == 0) {
diff --git a/runtime/monitor.h b/runtime/monitor.h
index 3d9d10a..8c7496b 100644
--- a/runtime/monitor.h
+++ b/runtime/monitor.h
@@ -211,10 +211,12 @@
       REQUIRES(!monitor_lock_)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
-  static std::string PrettyContentionInfo(Thread* owner,
+  static std::string PrettyContentionInfo(const std::string& owner_name,
+                                          pid_t owner_tid,
                                           ArtMethod* owners_method,
                                           uint32_t owners_dex_pc,
                                           size_t num_waiters)
+      REQUIRES(!Locks::thread_list_lock_)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Wait on a monitor until timeout, interrupt, or notification.  Used for Object.wait() and