@@ -794,15 +794,14 @@ void SampleBlockBuffer::FreeCompletedBlocks() {
794794static void FlushSampleBlocks (Isolate* isolate) {
795795 ASSERT (isolate != nullptr );
796796
797- SampleBlock* block = isolate->current_sample_block ( );
797+ SampleBlock* block = isolate->exchange_current_sample_block ( nullptr );
798798 if (block != nullptr ) {
799- isolate->set_current_sample_block (nullptr );
800799 block->MarkCompleted ();
801800 }
802801
803- block = isolate->current_allocation_sample_block ( );
802+ block = isolate->exchange_current_allocation_sample_block ( nullptr );
804803 if (block != nullptr ) {
805- isolate-> set_current_allocation_sample_block ( nullptr );
804+ // Allocation samples are collected synchronously.
806805 block->MarkCompleted ();
807806 }
808807}
@@ -1416,6 +1415,25 @@ void Profiler::SampleThreadSingleFrame(Thread* thread,
14161415 sample->SetAt (0 , pc);
14171416}
14181417
1418+ void ReleaseToCurrentBlock (Isolate* isolate) {
1419+ #if defined(DART_HOST_OS_MACOS) || defined(DART_HOST_OS_WINDOWS) || \
1420+ defined (DART_HOST_OS_FUCHSIA)
1421+ // The sample is collected by a different thread. The sample appears all at
1422+ // once from the profiled thread's point of view. Establish the isolate
1423+ // flushing its own current block happens-after the most recent sample
1424+ // written in that block by dumping a dependency through the current block.
1425+ // TSAN doesn't otherwise know this is already true because it doesn't have
1426+ // special treatment for thread_suspend/resume.
1427+ SampleBlock* block = isolate->current_sample_block ();
1428+ isolate->exchange_current_sample_block (block);
1429+ #elif defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
1430+ // The sample is collected by a signal handler on the same thread being
1431+ // sampled.
1432+ #else
1433+ #error What kind of sampler?
1434+ #endif
1435+ }
1436+
14191437void Profiler::SampleThread (Thread* thread,
14201438 const InterruptedThreadState& state) {
14211439 ASSERT (thread != nullptr );
@@ -1494,6 +1512,7 @@ void Profiler::SampleThread(Thread* thread,
14941512 if (thread->IGNORE_RACE2 (IsDeoptimizing)()) {
14951513 counters_.single_frame_sample_deoptimizing .fetch_add (1 );
14961514 SampleThreadSingleFrame (thread, sample, pc);
1515+ ReleaseToCurrentBlock (isolate);
14971516 return ;
14981517 }
14991518 }
@@ -1505,6 +1524,7 @@ void Profiler::SampleThread(Thread* thread,
15051524 counters_.single_frame_sample_get_and_validate_stack_bounds .fetch_add (1 );
15061525 // Could not get stack boundary.
15071526 SampleThreadSingleFrame (thread, sample, pc);
1527+ ReleaseToCurrentBlock (isolate);
15081528 return ;
15091529 }
15101530
@@ -1531,6 +1551,7 @@ void Profiler::SampleThread(Thread* thread,
15311551 CollectSample (isolate, exited_dart_code, in_dart_code, sample,
15321552 &native_stack_walker, &dart_stack_walker, pc, fp, sp,
15331553 &counters_);
1554+ ReleaseToCurrentBlock (isolate);
15341555}
15351556
15361557CodeDescriptor::CodeDescriptor (const AbstractCode code) : code_ (code) {}
0 commit comments