ART: Fix systrace monitor logging deadlock

Move the method logging earlier to avoid a deadlock due to re-acquiring
the mutator lock.

Bug: 34990215
Test: m
Test: Test on device
Change-Id: Id8069b133d1408a659afadd7e265d5027ac55a39
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index 0ceb23a..a32003e 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -356,40 +356,44 @@
     // Do this before releasing the lock so that we don't get deflated.
     size_t num_waiters = num_waiters_;
     ++num_waiters_;
+
+    // If systrace logging is enabled, first look at the lock owner. Acquiring the monitor's
+    // lock and then re-acquiring the mutator lock can deadlock.
+    bool started_trace = false;
+    if (ATRACE_ENABLED()) {
+      if (owner_ != nullptr) {  // Did the owner_ give the lock up?
+        std::ostringstream oss;
+        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);
+        const char* filename;
+        int32_t line_number;
+        TranslateLocation(m, pc, &filename, &line_number);
+        oss << " blocking from "
+            << ArtMethod::PrettyMethod(m) << "(" << (filename != nullptr ? filename : "null")
+            << ":" << line_number << ")";
+        ATRACE_BEGIN(oss.str().c_str());
+        started_trace = true;
+      }
+    }
+
     monitor_lock_.Unlock(self);  // Let go of locks in order.
     self->SetMonitorEnterObject(GetObject());
     {
-      uint32_t original_owner_thread_id = 0u;
       ScopedThreadSuspension tsc(self, kBlocked);  // Change to blocked and give up mutator_lock_.
+      uint32_t original_owner_thread_id = 0u;
       {
         // Reacquire monitor_lock_ without mutator_lock_ for Wait.
         MutexLock mu2(self, monitor_lock_);
         if (owner_ != nullptr) {  // Did the owner_ give the lock up?
           original_owner_thread_id = owner_->GetThreadId();
-          if (ATRACE_ENABLED()) {
-            std::ostringstream oss;
-            {
-              // Reacquire mutator_lock_ for getting the location info.
-              ScopedObjectAccess soa(self);
-              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);
-              const char* filename;
-              int32_t line_number;
-              TranslateLocation(m, pc, &filename, &line_number);
-              oss << " blocking from "
-                  << ArtMethod::PrettyMethod(m) << "(" << (filename != nullptr ? filename : "null")
-                  << ":" << line_number << ")";
-            }
-            ATRACE_BEGIN(oss.str().c_str());
-          }
           monitor_contenders_.Wait(self);  // Still contended so wait.
         }
       }
@@ -448,9 +452,11 @@
             }
           }
         }
-        ATRACE_END();
       }
     }
+    if (started_trace) {
+      ATRACE_END();
+    }
     self->SetMonitorEnterObject(nullptr);
     monitor_lock_.Lock(self);  // Reacquire locks in order.
     --num_waiters_;