Fix issue with RawMonitors around thread suspension.

Investigation of real-world JVMTI agents revealed that some rely on
the RawMonitorEnter function acting as a Java suspend point. If it
fails to act as one the agent could end up deadlocked.

Test: ./test.py --host -j50
Bug: 62821960
Bug: 34415266

Change-Id: I3daf5c49c1c9870e1f69eebfd4c6f2ad15224510
diff --git a/openjdkjvmti/ti_thread.cc b/openjdkjvmti/ti_thread.cc
index b0a1a85..27d01ea 100644
--- a/openjdkjvmti/ti_thread.cc
+++ b/openjdkjvmti/ti_thread.cc
@@ -85,7 +85,8 @@
         if (name != "JDWP" &&
             name != "Signal Catcher" &&
             !android::base::StartsWith(name, "Jit thread pool")) {
-          LOG(FATAL) << "Unexpected thread before start: " << name;
+          LOG(FATAL) << "Unexpected thread before start: " << name << " id: "
+                     << self->GetThreadId();
         }
       }
       return;
@@ -413,13 +414,24 @@
 }
 
 // Suspends the current thread if it has any suspend requests on it.
-static void SuspendCheck(art::Thread* self)
-    REQUIRES(!art::Locks::mutator_lock_, !art::Locks::user_code_suspension_lock_) {
+void ThreadUtil::SuspendCheck(art::Thread* self) {
   art::ScopedObjectAccess soa(self);
   // Really this is only needed if we are in FastJNI and actually have the mutator_lock_ already.
   self->FullSuspendCheck();
 }
 
+bool ThreadUtil::WouldSuspendForUserCodeLocked(art::Thread* self) {
+  DCHECK(self == art::Thread::Current());
+  art::MutexLock tscl_mu(self, *art::Locks::thread_suspend_count_lock_);
+  return self->GetUserCodeSuspendCount() != 0;
+}
+
+bool ThreadUtil::WouldSuspendForUserCode(art::Thread* self) {
+  DCHECK(self == art::Thread::Current());
+  art::MutexLock ucsl_mu(self, *art::Locks::user_code_suspension_lock_);
+  return WouldSuspendForUserCodeLocked(self);
+}
+
 jvmtiError ThreadUtil::GetThreadState(jvmtiEnv* env ATTRIBUTE_UNUSED,
                                       jthread thread,
                                       jint* thread_state_ptr) {
@@ -435,13 +447,10 @@
   do {
     SuspendCheck(self);
     art::MutexLock ucsl_mu(self, *art::Locks::user_code_suspension_lock_);
-    {
-      art::MutexLock tscl_mu(self, *art::Locks::thread_suspend_count_lock_);
-      if (self->GetUserCodeSuspendCount() != 0) {
-        // Make sure we won't be suspended in the middle of holding the thread_suspend_count_lock_
-        // by a user-code suspension. We retry and do another SuspendCheck to clear this.
-        continue;
-      }
+    if (WouldSuspendForUserCodeLocked(self)) {
+      // Make sure we won't be suspended in the middle of holding the thread_suspend_count_lock_ by
+      // a user-code suspension. We retry and do another SuspendCheck to clear this.
+      continue;
     }
     art::ScopedObjectAccess soa(self);
     art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
@@ -657,6 +666,9 @@
                                       jvmtiStartFunction proc,
                                       const void* arg,
                                       jint priority) {
+  if (!PhaseUtil::IsLivePhase()) {
+    return ERR(WRONG_PHASE);
+  }
   if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) {
     return ERR(INVALID_PRIORITY);
   }
@@ -703,15 +715,12 @@
     // before continuing.
     SuspendCheck(self);
     art::MutexLock mu(self, *art::Locks::user_code_suspension_lock_);
-    {
-      art::MutexLock thread_suspend_count_mu(self, *art::Locks::thread_suspend_count_lock_);
+    if (WouldSuspendForUserCodeLocked(self)) {
       // Make sure we won't be suspended in the middle of holding the thread_suspend_count_lock_ by
       // a user-code suspension. We retry and do another SuspendCheck to clear this.
-      if (self->GetUserCodeSuspendCount() != 0) {
-        continue;
-      }
-      // We are not going to be suspended by user code from now on.
+      continue;
     }
+    // We are not going to be suspended by user code from now on.
     {
       art::ScopedObjectAccess soa(self);
       art::MutexLock thread_list_mu(self, *art::Locks::thread_list_lock_);
@@ -798,13 +807,10 @@
   do {
     SuspendCheck(self);
     art::MutexLock ucsl_mu(self, *art::Locks::user_code_suspension_lock_);
-    {
-      art::MutexLock tscl_mu(self, *art::Locks::thread_suspend_count_lock_);
+    if (WouldSuspendForUserCodeLocked(self)) {
       // Make sure we won't be suspended in the middle of holding the thread_suspend_count_lock_ by
       // a user-code suspension. We retry and do another SuspendCheck to clear this.
-      if (self->GetUserCodeSuspendCount() != 0) {
-        continue;
-      }
+      continue;
     }
     // From now on we know we cannot get suspended by user-code.
     {