Avoid accessing the heap without mutator lock in Monitor::Lock.

ScopedThreadStateTransition doesn't do annotations and we are
accidentally accessing the heap without holding the mutator lock in
Monitor::PrettyContentionInfo. Use ScopedThreadSuspension instead.

Bug: 34674595
Test: test-art-host

Change-Id: If3ec86429ff99405ab14b3588f192ab1c0472cc8
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index 071b0e2..0ceb23a 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -303,6 +303,7 @@
                                           ArtMethod* owners_method,
                                           uint32_t owners_dex_pc,
                                           size_t num_waiters) {
+  Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
   const char* owners_filename;
   int32_t owners_line_number = 0;
   if (owners_method != nullptr) {
@@ -359,7 +360,7 @@
     self->SetMonitorEnterObject(GetObject());
     {
       uint32_t original_owner_thread_id = 0u;
-      ScopedThreadStateChange tsc(self, kBlocked);  // Change to blocked and give up mutator_lock_.
+      ScopedThreadSuspension tsc(self, kBlocked);  // Change to blocked and give up mutator_lock_.
       {
         // Reacquire monitor_lock_ without mutator_lock_ for Wait.
         MutexLock mu2(self, monitor_lock_);
@@ -367,22 +368,26 @@
           original_owner_thread_id = owner_->GetThreadId();
           if (ATRACE_ENABLED()) {
             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 << ")";
+            {
+              // 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.
@@ -414,6 +419,8 @@
               sample_percent = 100 * wait_ms / lock_profiling_threshold_;
             }
             if (sample_percent != 0 && (static_cast<uint32_t>(rand() % 100) < sample_percent)) {
+              // Reacquire mutator_lock_ for logging.
+              ScopedObjectAccess soa(self);
               if (wait_ms > kLongWaitMs && owners_method != nullptr) {
                 uint32_t pc;
                 ArtMethod* m = self->GetCurrentMethod(&pc);