[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,