Skip to content

Commit 60ce479

Browse files
aamCommit Queue
authored andcommitted
[vm/shared] Ensure mutator thread is registered without possibilty of a race.
Registration of the mutator thread in isolate group should be done as thread is added, under the same atomic operation. Mutator count changes should be done separately as before, under the same mutex used by `ContainsOnlyOneIsolate`. Follow-up to https://dart.googlesource.com/sdk/+/acc4ee0b1e3fc94a25bdf24431e7567e20cc663d Fixes #61459 TEST=isolate_group_bound_init_test Change-Id: I48bf4121bd097d3745915294c04d1eaae3879e0d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/448503 Reviewed-by: Slava Egorov <[email protected]> Commit-Queue: Alexander Aprelev <[email protected]>
1 parent 064339a commit 60ce479

File tree

3 files changed

+27
-14
lines changed

3 files changed

+27
-14
lines changed

runtime/vm/isolate.cc

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -474,18 +474,24 @@ bool IsolateGroup::UnregisterIsolateDecrementCount() {
474474
return isolate_count_ == 0;
475475
}
476476

477-
void IsolateGroup::RegisterIsolateGroupMutator(Thread* mutator) {
477+
void IsolateGroup::IncrementIsolateGroupMutatorCount() {
478478
SafepointWriteRwLocker ml(Thread::Current(), isolates_lock_.get());
479-
mutators_.Append(mutator);
480479
group_mutator_count_++;
481480
}
482481

483-
void IsolateGroup::UnregisterIsolateGroupMutator(Thread* mutator) {
482+
void IsolateGroup::DecrementIsolateGroupMutatorCount() {
484483
SafepointWriteRwLocker ml(Thread::Current(), isolates_lock_.get());
485-
mutators_.Remove(mutator);
486484
group_mutator_count_--;
487485
}
488486

487+
void IsolateGroup::RegisterIsolateGroupMutator(Thread* mutator) {
488+
mutators_.Append(mutator);
489+
}
490+
491+
void IsolateGroup::UnregisterIsolateGroupMutator(Thread* mutator) {
492+
mutators_.Remove(mutator);
493+
}
494+
489495
void IsolateGroup::CreateHeap(bool is_vm_isolate,
490496
bool is_service_or_kernel_isolate) {
491497
Heap::Init(this, is_vm_isolate,

runtime/vm/isolate.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,11 +374,12 @@ class IsolateGroup : public IntrusiveDListEntry<IsolateGroup> {
374374
// Returns `true` if this was the last isolate and the caller is responsible
375375
// for deleting the isolate group.
376376
bool UnregisterIsolateDecrementCount();
377+
void IncrementIsolateGroupMutatorCount();
378+
void DecrementIsolateGroupMutatorCount();
379+
bool ContainsOnlyOneIsolate();
377380
void RegisterIsolateGroupMutator(Thread* mutator);
378381
void UnregisterIsolateGroupMutator(Thread* mutator);
379382

380-
bool ContainsOnlyOneIsolate();
381-
382383
Dart_Port interrupt_port() { return interrupt_port_; }
383384

384385
ThreadRegistry* thread_registry() const { return thread_registry_.get(); }

runtime/vm/thread.cc

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -537,9 +537,9 @@ void Thread::EnterIsolateGroupAsMutator(IsolateGroup* isolate_group,
537537
isolate_group->IncreaseMutatorCount(/*thread=*/nullptr,
538538
/*is_nested_reenter=*/true,
539539
/*was_stolen=*/false);
540+
isolate_group->IncrementIsolateGroupMutatorCount();
540541
Thread* thread = AddActiveThread(isolate_group, /*isolate=*/nullptr,
541542
kMutatorTask, bypass_safepoint);
542-
isolate_group->RegisterIsolateGroupMutator(thread);
543543

544544
RELEASE_ASSERT(thread != nullptr);
545545
// Even if [bypass_safepoint] is true, a thread may need mutator state (e.g.
@@ -583,8 +583,8 @@ void Thread::ExitIsolateGroupAsMutator(bool bypass_safepoint) {
583583
thread->ClearStackLimit();
584584
SuspendThreadInternal(thread, VMTag::kInvalidTagId);
585585
auto group = thread->isolate_group();
586-
group->UnregisterIsolateGroupMutator(thread);
587586
FreeActiveThread(thread, /*isolate=*/nullptr, bypass_safepoint);
587+
group->DecrementIsolateGroupMutatorCount();
588588
group->DecreaseMutatorCount(/*is_nested_exit=*/true);
589589
}
590590

@@ -693,9 +693,12 @@ Thread* Thread::AddActiveThread(IsolateGroup* group,
693693
thread->isolate_ = isolate; // May be nullptr.
694694
thread->isolate_group_ = group;
695695
thread->scheduled_dart_mutator_isolate_ = isolate;
696-
if (isolate != nullptr && task_kind == kMutatorTask) {
697-
ASSERT(thread_registry->threads_lock()->IsOwnedByCurrentThread());
698-
isolate->mutator_thread_ = thread;
696+
if (task_kind == kMutatorTask) {
697+
if (isolate != nullptr) {
698+
isolate->mutator_thread_ = thread;
699+
} else {
700+
group->RegisterIsolateGroupMutator(thread);
701+
}
699702
}
700703

701704
// We start at being at-safepoint (in case any safepoint operation is
@@ -750,9 +753,12 @@ void Thread::FreeActiveThread(Thread* thread,
750753
thread->isolate_ = nullptr;
751754
thread->isolate_group_ = nullptr;
752755
thread->scheduled_dart_mutator_isolate_ = nullptr;
753-
if (isolate != nullptr && thread->task_kind() == kMutatorTask) {
754-
ASSERT(thread_registry->threads_lock()->IsOwnedByCurrentThread());
755-
isolate->mutator_thread_ = nullptr;
756+
if (thread->task_kind() == kMutatorTask) {
757+
if (isolate != nullptr) {
758+
isolate->mutator_thread_ = nullptr;
759+
} else {
760+
group->UnregisterIsolateGroupMutator(thread);
761+
}
756762
}
757763
thread->set_execution_state(Thread::kThreadInNative);
758764
thread->stack_limit_.store(0);

0 commit comments

Comments
 (0)