[vm/shared] Remove "single mutator" fastpath from RunWithStoppedMutators.

In presence of isolate-less mutators, the check for "single mutator"-scenario is not-trivial, acquiring active_mutator_count mutex results in circular mutex dependencies.

BUG=https://github.com/dart-lang/sdk/issues/60857
BUG=https://github.com/dart-lang/sdk/issues/60953
TEST=ci

Change-Id: I5a12f9b8d4bc54042137012668ed1afee7c7739f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/435241
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
diff --git a/runtime/lib/concurrent.cc b/runtime/lib/concurrent.cc
index b92fc34..e4aebe0 100644
--- a/runtime/lib/concurrent.cc
+++ b/runtime/lib/concurrent.cc
@@ -145,8 +145,8 @@
   Thread::EnterIsolate(saved_isolate);
 
   Thread* T = Thread::Current();
-  T->EnterSafepointToNative();
   T->set_execution_state(Thread::kThreadInNative);
+  T->EnterSafepoint();
 
   Dart_Handle local_handle = Dart_HandleFromPersistent(persistent_result);
   Dart_DeletePersistentHandle(persistent_result);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 219f433..1b7e716 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1554,8 +1554,8 @@
   // TransitionXXX scope objects as the reverse transition happens
   // outside this scope in Dart_ExitIsolate/Dart_ShutdownIsolate.
   Thread* T = Thread::Current();
-  T->EnterSafepointToNative();
   T->set_execution_state(Thread::kThreadInNative);
+  T->EnterSafepointToNative();
 }
 
 DART_EXPORT void Dart_StartProfiling() {
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index c3571cd..0f806a2 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -2909,37 +2909,27 @@
   return isolates_.IsEmpty() ? nullptr : isolates_.First();
 }
 
-void IsolateGroup::RunWithStoppedMutatorsCallable(
-    Callable* single_current_mutator,
-    Callable* otherwise,
-    bool use_force_growth_in_otherwise) {
+void IsolateGroup::RunWithStoppedMutatorsCallable(Callable* callable,
+                                                  bool use_force_growth) {
   auto thread = Thread::Current();
   StoppedMutatorsScope stopped_mutators_scope(thread);
 
   if (thread->OwnsSafepoint()) {
     RELEASE_ASSERT(thread->OwnsSafepoint());
-    single_current_mutator->Call();
+    callable->Call();
     return;
   }
 
-  {
-    SafepointReadRwLocker ml(thread, isolates_lock_.get());
-    if (thread->IsDartMutatorThread() && ContainsOnlyOneIsolate()) {
-      single_current_mutator->Call();
-      return;
-    }
-  }
-
   // We use the more strict safepoint operation scope here (which ensures that
   // all other threads, including auxiliary threads are at a safepoint), even
   // though we only need to ensure that the mutator threads are stopped.
-  if (use_force_growth_in_otherwise) {
+  if (use_force_growth) {
     ForceGrowthSafepointOperationScope safepoint_scope(
         thread, SafepointLevel::kGCAndDeopt);
-    otherwise->Call();
+    callable->Call();
   } else {
     DeoptSafepointOperationScope safepoint_scope(thread);
-    otherwise->Call();
+    callable->Call();
   }
 }
 
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 772d927..cc3045d 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -61,7 +61,6 @@
 class Log;
 class Message;
 class MessageHandler;
-class MonitorLocker;
 class Mutex;
 class Object;
 class ObjectIdRing;
@@ -599,32 +598,20 @@
   // Ensures mutators are stopped during execution of the provided function.
   //
   // If the current thread is the only mutator in the isolate group,
-  // [single_current_mutator] will be called. Otherwise [otherwise] will be
+  // [callable] will be called directly. Otherwise [callable] will be
   // called inside a [SafepointOperationsScope] (or
-  // [ForceGrowthSafepointOperationScope] if [use_force_growth_in_otherwise]
+  // [ForceGrowthSafepointOperationScope] if [use_force_growth]
   // is set).
   //
   // During the duration of this function, no new isolates can be added to the
   // isolate group.
-  void RunWithStoppedMutatorsCallable(
-      Callable* single_current_mutator,
-      Callable* otherwise,
-      bool use_force_growth_in_otherwise = false);
-
-  template <typename T, typename S>
-  void RunWithStoppedMutators(T single_current_mutator,
-                              S otherwise,
-                              bool use_force_growth_in_otherwise = false) {
-    LambdaCallable<T> single_callable(single_current_mutator);
-    LambdaCallable<S> otherwise_callable(otherwise);
-    RunWithStoppedMutatorsCallable(&single_callable, &otherwise_callable,
-                                   use_force_growth_in_otherwise);
-  }
+  void RunWithStoppedMutatorsCallable(Callable* callable,
+                                      bool use_force_growth = false);
 
   template <typename T>
   void RunWithStoppedMutators(T function, bool use_force_growth = false) {
     LambdaCallable<T> callable(function);
-    RunWithStoppedMutatorsCallable(&callable, &callable, use_force_growth);
+    RunWithStoppedMutatorsCallable(&callable, use_force_growth);
   }
 
 #ifndef PRODUCT
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 1d5b2d7..1157ca8 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -520,6 +520,10 @@
 
 void Thread::EnterIsolateGroupAsMutator(IsolateGroup* isolate_group,
                                         bool bypass_safepoint) {
+  isolate_group->IncreaseMutatorCount(/*thread=*/nullptr,
+                                      /*is_nested_reenter=*/true,
+                                      /*was_stolen=*/false);
+
   Thread* thread = AddActiveThread(isolate_group, /*isolate=*/nullptr,
                                    kMutatorTask, bypass_safepoint);
   RELEASE_ASSERT(thread != nullptr);
@@ -542,10 +546,6 @@
   thread->SetStackLimit(OSThread::Current()->overflow_stack_limit());
 #endif
 
-  isolate_group->IncreaseMutatorCount(/*thread=*/thread,
-                                      /*is_nested_reenter=*/false,
-                                      /*was_stolen=*/true);
-
   thread->AssertDartMutatorInvariants();
 }
 
@@ -559,8 +559,9 @@
   thread->ResetMutatorState();
   thread->ClearStackLimit();
   SuspendThreadInternal(thread, VMTag::kInvalidTagId);
-  thread->isolate_group()->DecreaseMutatorCount(/*is_nested_exit=*/true);
+  auto group = thread->isolate_group();
   FreeActiveThread(thread, /*isolate=*/nullptr, bypass_safepoint);
+  group->DecreaseMutatorCount(/*is_nested_exit=*/true);
 }
 
 void Thread::EnterIsolateGroupAsNonMutator(IsolateGroup* isolate_group,