Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Static Public Member Functions | Friends | List of all members
dart::Profiler Class Reference

#include <profiler.h>

Inheritance diagram for dart::Profiler:
dart::AllStatic

Static Public Member Functions

static void Init ()
 
static void Cleanup ()
 
static void SetSampleDepth (intptr_t depth)
 
static void SetSamplePeriod (intptr_t period)
 
static void UpdateSamplePeriod ()
 
static void UpdateRunningState ()
 
static SampleBlockBuffersample_block_buffer ()
 
static void set_sample_block_buffer (SampleBlockBuffer *buffer)
 
static void DumpStackTrace (void *context)
 
static void DumpStackTrace (bool for_crash=true)
 
static void SampleAllocation (Thread *thread, intptr_t cid, uint32_t identity_hash)
 
static void SampleThread (Thread *thread, const InterruptedThreadState &state)
 
static ProfilerCounters counters ()
 
static intptr_t Size ()
 
static void ProcessCompletedBlocks (Isolate *isolate)
 
static void IsolateShutdown (Thread *thread)
 

Friends

class Thread
 

Detailed Description

Definition at line 53 of file profiler.h.

Member Function Documentation

◆ Cleanup()

void dart::Profiler::Cleanup ( )
static

Definition at line 599 of file profiler.cc.

599 {
600 if (!FLAG_profiler) {
601 return;
602 }
603 ASSERT(initialized_);
606 SampleBlockCleanupVisitor visitor;
607 Isolate::VisitIsolates(&visitor);
608 initialized_ = false;
609}
static void VisitIsolates(IsolateVisitor *visitor)
Definition isolate.cc:3485
#define ASSERT(E)

◆ counters()

static ProfilerCounters dart::Profiler::counters ( )
inlinestatic

Definition at line 91 of file profiler.h.

91 {
92 // Copies the counter values.
93 return counters_;
94 }

◆ DumpStackTrace() [1/2]

void dart::Profiler::DumpStackTrace ( bool  for_crash = true)
static

Definition at line 450 of file profiler.cc.

450 {
451 uintptr_t sp = OSThread::GetCurrentStackPointer();
452 uintptr_t fp = 0;
453 uintptr_t pc = OS::GetProgramCounter();
454
456
457 DumpStackTrace(sp, fp, pc, for_crash);
458}
static uword GetCurrentStackPointer()
Definition os_thread.cc:132
static uintptr_t GetProgramCounter()
static void DumpStackTrace(void *context)
Definition profiler.cc:409
const uint32_t fp
#define COPY_FP_REGISTER(fp)
Definition globals.h:200

◆ DumpStackTrace() [2/2]

void dart::Profiler::DumpStackTrace ( void *  context)
static

Definition at line 409 of file profiler.cc.

409 {
410 if (context == nullptr) {
411 DumpStackTrace(/*for_crash=*/true);
412 return;
413 }
414#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_MACOS) || \
415 defined(DART_HOST_OS_ANDROID)
416 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
417 mcontext_t mcontext = ucontext->uc_mcontext;
421 DumpStackTrace(sp, fp, pc, /*for_crash=*/true);
422#elif defined(DART_HOST_OS_WINDOWS)
423 CONTEXT* ctx = reinterpret_cast<CONTEXT*>(context);
424#if defined(HOST_ARCH_IA32)
425 uword pc = static_cast<uword>(ctx->Eip);
426 uword fp = static_cast<uword>(ctx->Ebp);
427 uword sp = static_cast<uword>(ctx->Esp);
428#elif defined(HOST_ARCH_X64)
429 uword pc = static_cast<uword>(ctx->Rip);
430 uword fp = static_cast<uword>(ctx->Rbp);
431 uword sp = static_cast<uword>(ctx->Rsp);
432#elif defined(HOST_ARCH_ARM)
433 uword pc = static_cast<uword>(ctx->Pc);
434 uword fp = static_cast<uword>(ctx->R11);
435 uword sp = static_cast<uword>(ctx->Sp);
436#elif defined(HOST_ARCH_ARM64)
437 uword pc = static_cast<uword>(ctx->Pc);
438 uword fp = static_cast<uword>(ctx->Fp);
439 uword sp = static_cast<uword>(ctx->Sp);
440#else
441#error Unsupported architecture.
442#endif
443 DumpStackTrace(sp, fp, pc, /*for_crash=*/true);
444#else
445// TODO(fschneider): Add support for more platforms.
446// Do nothing on unsupported platforms.
447#endif
448}
static uintptr_t GetCStackPointer(const mcontext_t &mcontext)
static uintptr_t GetFramePointer(const mcontext_t &mcontext)
static uintptr_t GetProgramCounter(const mcontext_t &mcontext)
uintptr_t uword
Definition globals.h:501

◆ Init()

void dart::Profiler::Init ( )
static

Definition at line 567 of file profiler.cc.

567 {
568 // Place some sane restrictions on user controlled flags.
569 SetSampleDepth(FLAG_max_profile_depth);
570 if (!FLAG_profiler) {
571 return;
572 }
573 ASSERT(!initialized_);
574 SetSamplePeriod(FLAG_profile_period);
575 // The profiler may have been shutdown previously, in which case the sample
576 // buffer will have already been initialized.
577 if (sample_block_buffer_ == nullptr) {
578 intptr_t num_blocks = CalculateSampleBufferCapacity();
579 sample_block_buffer_ = new SampleBlockBuffer(num_blocks);
580 }
585 initialized_ = true;
586}
static void SetSampleDepth(intptr_t depth)
Definition profiler.cc:619
static void SetSamplePeriod(intptr_t period)
Definition profiler.cc:650

◆ IsolateShutdown()

void dart::Profiler::IsolateShutdown ( Thread thread)
static

Definition at line 1848 of file profiler.cc.

1848 {
1849 FlushSampleBlocks(thread->isolate());
1850 ProcessCompletedBlocks(thread->isolate());
1851}
static void ProcessCompletedBlocks(Isolate *isolate)
Definition profiler.cc:1831
static void FlushSampleBlocks(Isolate *isolate)
Definition profiler.cc:739

◆ ProcessCompletedBlocks()

void dart::Profiler::ProcessCompletedBlocks ( Isolate isolate)
static

Definition at line 1831 of file profiler.cc.

1831 {
1832 if (!Service::profiler_stream.enabled()) return;
1833 auto thread = Thread::Current();
1834 if (Isolate::IsSystemIsolate(isolate)) return;
1835
1836 TIMELINE_DURATION(thread, Isolate, "Profiler::ProcessCompletedBlocks")
1837 DisableThreadInterruptsScope dtis(thread);
1838 StackZone zone(thread);
1839 HandleScope handle_scope(thread);
1840 StreamableSampleFilter filter(isolate->main_port(), isolate);
1841 Profile profile;
1842 profile.Build(thread, isolate, &filter, Profiler::sample_block_buffer());
1843 ServiceEvent event(isolate, ServiceEvent::kCpuSamples);
1844 event.set_cpu_profile(&profile);
1845 Service::HandleEvent(&event);
1846}
static bool IsSystemIsolate(const Isolate *isolate)
Definition isolate.h:1398
static SampleBlockBuffer * sample_block_buffer()
Definition profiler.h:67
static StreamInfo profiler_stream
Definition service.h:188
static Thread * Current()
Definition thread.h:361
FlKeyEvent * event
#define TIMELINE_DURATION(thread, stream, name)
Definition timeline.h:39

◆ sample_block_buffer()

static SampleBlockBuffer * dart::Profiler::sample_block_buffer ( )
inlinestatic

Definition at line 67 of file profiler.h.

67 {
68 return sample_block_buffer_;
69 }

◆ SampleAllocation()

void dart::Profiler::SampleAllocation ( Thread thread,
intptr_t  cid,
uint32_t  identity_hash 
)
static

Definition at line 1265 of file profiler.cc.

1267 {
1268 ASSERT(thread != nullptr);
1269 OSThread* os_thread = thread->os_thread();
1270 ASSERT(os_thread != nullptr);
1271 Isolate* isolate = thread->isolate();
1272 if (!CheckIsolate(isolate)) {
1273 return;
1274 }
1275 const bool exited_dart_code = thread->HasExitedDartCode();
1276
1277 SampleBlockBuffer* buffer = Profiler::sample_block_buffer();
1278 if (buffer == nullptr) {
1279 // Profiler not initialized.
1280 return;
1281 }
1282
1283 uintptr_t sp = OSThread::GetCurrentStackPointer();
1284 uintptr_t fp = 0;
1285 uintptr_t pc = OS::GetProgramCounter();
1286 uintptr_t lr = 0;
1287
1289
1290 uword stack_lower = 0;
1291 uword stack_upper = 0;
1292
1293 if (!GetAndValidateThreadStackBounds(os_thread, thread, fp, sp, &stack_lower,
1294 &stack_upper)) {
1295 // Could not get stack boundary.
1296 return;
1297 }
1298
1299 Sample* sample =
1300 SetupSample(thread, /*allocation_block*/ true, os_thread->trace_id());
1301 if (sample == nullptr) {
1302 // We were unable to assign a sample for this allocation.
1303 counters_.sample_allocation_failure++;
1304 return;
1305 }
1306 sample->SetAllocationCid(cid);
1307 sample->set_allocation_identity_hash(identity_hash);
1308
1309 if (FLAG_profile_vm_allocation) {
1310 ProfilerNativeStackWalker native_stack_walker(
1311 &counters_, (isolate != nullptr) ? isolate->main_port() : ILLEGAL_PORT,
1312 sample, isolate->current_allocation_sample_block(), stack_lower,
1313 stack_upper, pc, fp, sp);
1314 native_stack_walker.walk();
1315 } else if (exited_dart_code) {
1316 ProfilerDartStackWalker dart_exit_stack_walker(
1317 thread, sample, isolate->current_allocation_sample_block(), pc, fp, sp,
1318 lr, /* allocation_sample*/ true);
1319 dart_exit_stack_walker.walk();
1320 } else {
1321 // Fall back.
1322 uintptr_t pc = OS::GetProgramCounter();
1323 sample->SetAt(0, pc);
1324 }
1325}
#define ILLEGAL_PORT
Definition dart_api.h:1530
static const uint8_t buffer[]
static Sample * SetupSample(Thread *thread, bool allocation_sample, ThreadId tid)
Definition profiler.cc:1229
static bool CheckIsolate(Isolate *isolate)
Definition profiler.cc:1257
const intptr_t cid
static bool GetAndValidateThreadStackBounds(OSThread *os_thread, Thread *thread, uintptr_t fp, uintptr_t sp, uword *stack_lower, uword *stack_upper)
Definition profiler.cc:368

◆ SampleThread()

void dart::Profiler::SampleThread ( Thread thread,
const InterruptedThreadState state 
)
static

Definition at line 1348 of file profiler.cc.

1349 {
1350 ASSERT(thread != nullptr);
1351 OSThread* os_thread = thread->os_thread();
1352 ASSERT(os_thread != nullptr);
1353 Isolate* isolate = thread->isolate();
1354
1355 // Thread is not doing VM work.
1356 if (thread->task_kind() == Thread::kUnknownTask) {
1357 counters_.bail_out_unknown_task.fetch_add(1);
1358 return;
1359 }
1360
1362 // The JumpToFrame stub manually adjusts the stack pointer, frame
1363 // pointer, and some isolate state. It is not safe to walk the
1364 // stack when executing this stub.
1365 counters_.bail_out_jump_to_exception_handler.fetch_add(1);
1366 return;
1367 }
1368
1369 const bool in_dart_code = thread->IsExecutingDartCode();
1370
1371 uintptr_t sp = 0;
1372 uintptr_t fp = state.fp;
1373 uintptr_t pc = state.pc;
1374 uintptr_t lr = state.lr;
1375#if defined(USING_SIMULATOR)
1376 Simulator* simulator = nullptr;
1377#endif
1378
1379 if (in_dart_code) {
1380// If we're in Dart code, use the Dart stack pointer.
1381#if defined(USING_SIMULATOR)
1382 simulator = isolate->simulator();
1383 sp = simulator->get_register(SPREG);
1384 fp = simulator->get_register(FPREG);
1385 pc = simulator->get_pc();
1386 lr = simulator->get_lr();
1387#else
1388 sp = state.dsp;
1389#endif
1390 } else {
1391 // If we're in runtime code, use the C stack pointer.
1392 sp = state.csp;
1393 }
1394
1395 if (!CheckIsolate(isolate)) {
1396 counters_.bail_out_check_isolate.fetch_add(1);
1397 return;
1398 }
1399
1401 if (sample_block_buffer == nullptr) {
1402 // Profiler not initialized.
1403 return;
1404 }
1405
1406 // Setup sample.
1407 Sample* sample =
1408 SetupSample(thread, /*allocation_block*/ false, os_thread->trace_id());
1409 if (sample == nullptr) {
1410 // We were unable to assign a sample for this profiler tick.
1411 counters_.sample_allocation_failure++;
1412 return;
1413 }
1414
1415 if (thread->IsDartMutatorThread()) {
1416 if (isolate->IsDeoptimizing()) {
1417 counters_.single_frame_sample_deoptimizing.fetch_add(1);
1418 SampleThreadSingleFrame(thread, sample, pc);
1419 return;
1420 }
1421 }
1422
1423 uword stack_lower = 0;
1424 uword stack_upper = 0;
1425 if (!GetAndValidateThreadStackBounds(os_thread, thread, fp, sp, &stack_lower,
1426 &stack_upper)) {
1427 counters_.single_frame_sample_get_and_validate_stack_bounds.fetch_add(1);
1428 // Could not get stack boundary.
1429 SampleThreadSingleFrame(thread, sample, pc);
1430 return;
1431 }
1432
1433 // At this point we have a valid stack boundary for this isolate and
1434 // know that our initial stack and frame pointers are within the boundary.
1435
1436 // Increment counter for vm tag.
1437 VMTagCounters* counters = isolate->vm_tag_counters();
1438 ASSERT(counters != nullptr);
1439 if (thread->IsDartMutatorThread()) {
1440 counters->Increment(sample->vm_tag());
1441 }
1442
1443 ProfilerNativeStackWalker native_stack_walker(
1444 &counters_, (isolate != nullptr) ? isolate->main_port() : ILLEGAL_PORT,
1445 sample, isolate->current_sample_block(), stack_lower, stack_upper, pc, fp,
1446 sp);
1447 const bool exited_dart_code = thread->HasExitedDartCode();
1448 ProfilerDartStackWalker dart_stack_walker(
1449 thread, sample, isolate->current_sample_block(), pc, fp, sp, lr,
1450 /* allocation_sample*/ false);
1451
1452 // All memory access is done inside CollectSample.
1453 CollectSample(isolate, exited_dart_code, in_dart_code, sample,
1454 &native_stack_walker, &dart_stack_walker, pc, fp, sp,
1455 &counters_);
1456}
static ProfilerCounters counters()
Definition profiler.h:91
static bool HasBeenInitialized()
Definition stub_code.h:41
static bool InJumpToFrameStub(uword pc)
Definition stub_code.cc:139
AtkStateType state
static void CollectSample(Isolate *isolate, bool exited_dart_code, bool in_dart_code, Sample *sample, ProfilerNativeStackWalker *native_stack_walker, ProfilerDartStackWalker *dart_stack_walker, uword pc, uword fp, uword sp, ProfilerCounters *counters)
Definition profiler.cc:1169
const Register FPREG
const Register SPREG

◆ set_sample_block_buffer()

static void dart::Profiler::set_sample_block_buffer ( SampleBlockBuffer buffer)
inlinestatic

Definition at line 70 of file profiler.h.

70 {
71 sample_block_buffer_ = buffer;
72 }

◆ SetSampleDepth()

void dart::Profiler::SetSampleDepth ( intptr_t  depth)
static

Definition at line 619 of file profiler.cc.

619 {
620 const int kMinimumDepth = 2;
621 const int kMaximumDepth = 255;
622 if (depth < kMinimumDepth) {
623 FLAG_max_profile_depth = kMinimumDepth;
624 } else if (depth > kMaximumDepth) {
625 FLAG_max_profile_depth = kMaximumDepth;
626 } else {
627 FLAG_max_profile_depth = depth;
628 }
629}

◆ SetSamplePeriod()

void dart::Profiler::SetSamplePeriod ( intptr_t  period)
static

Definition at line 650 of file profiler.cc.

650 {
651 const int kMinimumProfilePeriod = 50;
652 if (period < kMinimumProfilePeriod) {
653 FLAG_profile_period = kMinimumProfilePeriod;
654 } else {
655 FLAG_profile_period = period;
656 }
657 ThreadInterrupter::SetInterruptPeriod(FLAG_profile_period);
658}
static void SetInterruptPeriod(intptr_t period)

◆ Size()

intptr_t dart::Profiler::Size ( )
inlinestatic

Definition at line 794 of file profiler.h.

794 {
795 intptr_t size = 0;
796 if (sample_block_buffer_ != nullptr) {
797 size += sample_block_buffer_->Size();
798 }
799 return size;
800}
intptr_t Size() const
Definition profiler.h:768
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259

◆ UpdateRunningState()

void dart::Profiler::UpdateRunningState ( )
static

Definition at line 611 of file profiler.cc.

611 {
612 if (!FLAG_profiler && initialized_) {
613 Cleanup();
614 } else if (FLAG_profiler && !initialized_) {
615 Init();
616 }
617}
static void Cleanup()
Definition profiler.cc:599
static void Init()
Definition profiler.cc:567

◆ UpdateSamplePeriod()

void dart::Profiler::UpdateSamplePeriod ( )
static

Definition at line 660 of file profiler.cc.

660 {
661 SetSamplePeriod(FLAG_profile_period);
662}

Friends And Related Symbol Documentation

◆ Thread

friend class Thread
friend

Definition at line 120 of file profiler.h.


The documentation for this class was generated from the following files: