mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 23:49:45 +00:00
[vm, profiler] Don't assume the isolate has a mutator during a 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 Bug: https://github.com/flutter/flutter/issues/134548 Change-Id: I7a6b25dabf930e8480d1a85d7f24c4765fc36b15 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/328380 Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Ben Konyi <bkonyi@google.com>
This commit is contained in:
parent
ebd669a0d4
commit
f36c109471
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue