Skip to content

Commit

Permalink
[beta][vm, profiler] Don't assume the isolate has a mutator during a …
Browse files Browse the repository at this point in the history
…profile sample.

A sample can be taken when Thread::Current() and Thread::Current()->isolate() are non-NULL. When a thread is entering or exiting an isolate, the is a brief window between the TLS being set/cleared and Isolate::mutator_thread_ being set/cleared.

TEST=vm/cc/Profiler_EnterExitIsolate

Fixes: flutter/flutter#134548
Cherry-pick-request: #53713
Cherry-pick: https://dart-review.googlesource.com/c/sdk/+/328380
Change-Id: Ic8c0aecd65101a882a8ff6a9ec02c4a9ea1d1cfe
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/329804
Commit-Queue: Siva Annamalai <asiva@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
  • Loading branch information
a-siva authored and Commit Queue committed Oct 12, 2023
1 parent 620c172 commit 6a2fa7a
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
10 changes: 7 additions & 3 deletions runtime/vm/profiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -820,9 +820,13 @@ Sample* SampleBlockBuffer::ReserveSampleImpl(Isolate* isolate,
}
if (block != nullptr) {
block->MarkCompleted();
if (!Isolate::IsSystemIsolate(isolate) &&
isolate->TrySetHasCompletedBlocks()) {
isolate->mutator_thread()->ScheduleInterrupts(Thread::kVMInterrupt);
if (!Isolate::IsSystemIsolate(isolate)) {
Thread* mutator = isolate->mutator_thread();
// The mutator thread might be NULL if we sample in the middle of
// Thread::Enter/ExitIsolate.
if ((mutator != nullptr) && isolate->TrySetHasCompletedBlocks()) {
mutator->ScheduleInterrupts(Thread::kVMInterrupt);
}
}
}
return next->ReserveSample();
Expand Down
17 changes: 17 additions & 0 deletions runtime/vm/profiler_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2430,6 +2430,23 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ProfileCodeTableTest) {
EXPECT_EQ(table->FindCodeForPC(50), code1);
}

// Try to hit any races in related to setting TLS and Isolate::mutator_thread_.
// https://github.com/flutter/flutter/issues/134548
ISOLATE_UNIT_TEST_CASE(Profiler_EnterExitIsolate) {
EnableProfiler();
Profiler::SetSamplePeriod(50); // Microseconds.

const char* kScript = "main() => null;\n";
const Library& root_library = Library::Handle(LoadTestScript(kScript));

Isolate* isolate = Isolate::Current();
for (intptr_t i = 0; i < 100000; i++) {
Thread::ExitIsolate();
Thread::EnterIsolate(isolate);
Invoke(root_library, "main");
}
}

#endif // !PRODUCT

} // namespace dart

0 comments on commit 6a2fa7a

Please sign in to comment.