5#ifndef RUNTIME_VM_TIMELINE_H_
6#define RUNTIME_VM_TIMELINE_H_
23#if defined(SUPPORT_TIMELINE) && defined(SUPPORT_PERFETTO) && !defined(PRODUCT)
24#include "perfetto/protozero/scattered_heap_buffer.h"
29#if defined(FUCHSIA_SDK) || defined(DART_HOST_OS_FUCHSIA)
30#include <lib/trace-engine/context.h>
31#include <lib/trace-engine/instrumentation.h>
32#elif defined(DART_HOST_OS_MACOS)
33#include <os/signpost.h>
38#if !defined(SUPPORT_TIMELINE)
39#define TIMELINE_DURATION(thread, stream, name)
40#define TIMELINE_FUNCTION_COMPILATION_DURATION(thread, name, function)
41#define TIMELINE_FUNCTION_GC_DURATION(thread, name)
45class JSONBase64String;
50class ObjectPointerVisitor;
54class TimelineEventBlock;
55class TimelineEventRecorder;
60#if defined(SUPPORT_TIMELINE)
61#define CALLBACK_RECORDER_NAME "Callback"
62#define ENDLESS_RECORDER_NAME "Endless"
63#define FILE_RECORDER_NAME "File"
64#define FUCHSIA_RECORDER_NAME "Fuchsia"
65#define MACOS_RECORDER_NAME "Macos"
66#define PERFETTO_FILE_RECORDER_NAME "Perfettofile"
67#define RING_RECORDER_NAME "Ring"
68#define STARTUP_RECORDER_NAME "Startup"
69#define SYSTRACE_RECORDER_NAME "Systrace"
72#define TIMELINE_STREAM_LIST(V) \
73 V(API, "dart:api", true) \
74 V(Compiler, "dart:compiler", true) \
75 V(CompilerVerbose, "dart:compiler.verbose", true) \
76 V(Dart, "dart:dart", false) \
77 V(Debugger, "dart:debugger", true) \
78 V(Embedder, "dart:embedder", true) \
79 V(GC, "dart:gc", true) \
80 V(Isolate, "dart:isolate", true) \
81 V(VM, "dart:vm", true)
93 const char*
name()
const {
return name_; }
97#if defined(DART_HOST_OS_FUCHSIA)
99 return trace_is_category_enabled(fuchsia_name_);
101 return trace_is_category_enabled(fuchsia_name_) || enabled_ != 0;
104 return enabled_ != 0;
118#if defined(DART_HOST_OS_FUCHSIA)
119 trace_site_t* trace_site() {
return &trace_site_; }
120#elif defined(DART_HOST_OS_MACOS)
121 os_log_t macos_log()
const {
return macos_log_; }
122 bool has_static_labels()
const {
return has_static_labels_; }
126 const char*
const name_;
127 const char*
const fuchsia_name_;
133#if defined(DART_HOST_OS_FUCHSIA)
134 trace_site_t trace_site_ = {};
135#elif defined(DART_HOST_OS_MACOS)
136 os_log_t macos_log_ = {};
137 bool has_static_labels_ =
false;
141#if defined(SUPPORT_TIMELINE)
142class RecorderSynchronizationLock :
public AllStatic {
145 recorder_state_.store(kActive, std::memory_order_release);
146 outstanding_event_writes_.store(0);
149 static void EnterLock() {
150 outstanding_event_writes_.fetch_add(1, std::memory_order_acquire);
153 static void ExitLock() {
155 outstanding_event_writes_.fetch_sub(1, std::memory_order_release);
159 static bool IsUninitialized() {
160 return (recorder_state_.load(std::memory_order_acquire) == kUninitialized);
163 static bool IsActive() {
164 return (recorder_state_.load(std::memory_order_acquire) == kActive);
167 static bool IsShuttingDown() {
168 return (recorder_state_.load(std::memory_order_acquire) == kShuttingDown);
171 static void WaitForShutdown() {
172 recorder_state_.store(kShuttingDown, std::memory_order_release);
174 while (outstanding_event_writes_.load(std::memory_order_relaxed) > 0) {
179 typedef enum {
kUninitialized = 0, kActive, kShuttingDown } RecorderState;
180 static std::atomic<RecorderState> recorder_state_;
181 static std::atomic<intptr_t> outstanding_event_writes_;
189class RecorderSynchronizationLockScope {
191 RecorderSynchronizationLockScope() {
192 RecorderSynchronizationLock::EnterLock();
195 ~RecorderSynchronizationLockScope() {
196 RecorderSynchronizationLock::ExitLock();
199 bool IsUninitialized()
const {
200 return RecorderSynchronizationLock::IsUninitialized();
203 bool IsActive()
const {
return RecorderSynchronizationLock::IsActive(); }
205 bool IsShuttingDown()
const {
206 return RecorderSynchronizationLock::IsShuttingDown();
213class Timeline :
public AllStatic {
222 static TimelineEventRecorder* recorder() {
return recorder_; }
224 static bool recorder_discards_clock_values() {
225 return recorder_discards_clock_values_;
227 static void set_recorder_discards_clock_values(
bool value) {
228 recorder_discards_clock_values_ =
value;
237 static void ReclaimCachedBlocksFromThreads();
243 static void PrintFlagsToJSON(JSONStream* json);
246 static void PrintFlagsToJSONArray(JSONArray* arr);
249#define TIMELINE_STREAM_ACCESSOR(name, ...) \
250 static TimelineStream* Get##name##Stream() { return &stream_##name##_; }
251 TIMELINE_STREAM_LIST(TIMELINE_STREAM_ACCESSOR)
252#undef TIMELINE_STREAM_ACCESSOR
254#define TIMELINE_STREAM_FLAGS(name, ...) \
255 static void SetStream##name##Enabled(bool enabled) { \
256 stream_##name##_.set_enabled(enabled); \
258 TIMELINE_STREAM_LIST(TIMELINE_STREAM_FLAGS)
259#undef TIMELINE_STREAM_FLAGS
262 static TimelineEventRecorder* recorder_;
264 static MallocGrowableArray<char*>* enabled_streams_;
265 static bool recorder_discards_clock_values_;
267#define TIMELINE_STREAM_DECLARE(name, ...) \
268 static TimelineStream stream_##name##_;
269 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DECLARE)
270#undef TIMELINE_STREAM_DECLARE
273 friend class TimelineRecorderOverride;
274 friend class ReclaimBlocksIsolateVisitor;
277struct TimelineEventArgument {
282class TimelineEventArguments {
284 TimelineEventArguments() : buffer_(nullptr), length_(0) {}
285 ~TimelineEventArguments() { Free(); }
287 void SetNumArguments(intptr_t
length);
289 void SetArgument(intptr_t i,
const char*
name,
char* argument);
291 void CopyArgument(intptr_t i,
const char*
name,
const char* argument);
293 void FormatArgument(intptr_t i,
298 void StealArguments(TimelineEventArguments* arguments);
300 TimelineEventArgument*
buffer()
const {
return buffer_; }
302 intptr_t
length()
const {
return length_; }
306 TimelineEventArgument& operator[](intptr_t index)
const {
307 return buffer_[index];
310 bool IsEmpty() {
return length_ == 0; }
312 bool IsNotEmpty() {
return length_ != 0; }
315 TimelineEventArgument* buffer_;
344 static const int64_t kNoFlowId = -1;
351 bool IsValid()
const {
356 void AsyncBegin(
const char* label,
358 int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
363 int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
365 void AsyncEnd(
const char* label,
367 int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
371 int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
373 void Instant(
const char* label,
374 int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
376 void Duration(
const char* label, int64_t start_micros, int64_t end_micros);
378 void Begin(
const char* label,
380 int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
382 void End(
const char* label,
384 int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
386 void Counter(
const char* label,
387 int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
389 void FlowBegin(
const char* label,
391 int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
392 void FlowStep(
const char* label,
394 int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
395 void FlowEnd(
const char* label,
397 int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
399 void Metadata(
const char* label,
400 int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline());
402 void CompleteWithPreSerializedArgs(
char* args_json);
405 intptr_t GetNumArguments()
const {
return arguments_.length(); }
406 void SetNumArguments(intptr_t
length) { arguments_.SetNumArguments(
length); }
408 void SetArgument(intptr_t i,
const char*
name,
char* argument) {
409 arguments_.SetArgument(i,
name, argument);
412 void CopyArgument(intptr_t i,
const char*
name,
const char* argument) {
413 arguments_.CopyArgument(i,
name, argument);
416 void FormatArgument(intptr_t i,
const char*
name,
const char*
fmt, ...)
419 void StealArguments(TimelineEventArguments* arguments) {
420 arguments_.StealArguments(arguments);
427 TimelineStream*
stream()
const {
return stream_; }
429 int64_t TimeOrigin()
const {
return timestamp0_; }
433 return timestamp1_or_id_;
435 int64_t TimeDuration()
const;
436 void SetTimeEnd(int64_t micros = OS::GetCurrentMonotonicMicrosForTimeline()) {
438 ASSERT(timestamp1_or_id_ == 0);
439 set_timestamp1_or_id(micros);
441 int64_t TimeEnd()
const {
442 ASSERT(IsFinishedDuration());
443 return timestamp1_or_id_;
446 int64_t timestamp0()
const {
return timestamp0_; }
447 int64_t timestamp1_or_id()
const {
return timestamp1_or_id_; }
449 void SetFlowIds(intptr_t flow_id_count,
450 std::unique_ptr<
const int64_t[]>& flow_ids) {
451 flow_id_count_ = flow_id_count;
452 flow_ids_.swap(flow_ids);
454 intptr_t flow_id_count()
const {
return flow_id_count_; }
455 const int64_t* FlowIds()
const {
return flow_ids_.get(); }
457 bool HasIsolateId()
const;
458 bool HasIsolateGroupId()
const;
459 std::unique_ptr<const char[]> GetFormattedIsolateId()
const;
460 std::unique_ptr<const char[]> GetFormattedIsolateGroupId()
const;
463 int64_t LowTime()
const;
465 int64_t HighTime()
const;
468 void PrintJSON(JSONStream* stream)
const;
470 void PrintJSON(JSONWriter* writer)
const;
471#if defined(SUPPORT_PERFETTO) && !defined(PRODUCT)
472 bool CanBeRepresentedByPerfettoTracePacket()
const;
479 ThreadId thread()
const {
return thread_; }
481 void set_thread(ThreadId tid) { thread_ = tid; }
483 Dart_Port isolate_id()
const {
return isolate_id_; }
485 uint64_t isolate_group_id()
const {
return isolate_group_id_; }
487 void* isolate_data()
const {
return isolate_data_; }
489 void* isolate_group_data()
const {
return isolate_group_data_; }
491 const char* label()
const {
return label_; }
494 bool DurationFinishedBefore(int64_t micros)
const {
495 return TimeEnd() <= micros;
498 bool IsDuration()
const {
return (
event_type() == kDuration); }
500 bool IsBegin()
const {
return (
event_type() == kBegin); }
502 bool IsEnd()
const {
return (
event_type() == kEnd); }
505 bool IsBeginOrEnd()
const {
return IsBegin() || IsEnd(); }
508 bool DurationContains(TimelineEvent* other)
const {
509 ASSERT(IsFinishedDuration());
510 if (other->IsBegin()) {
511 if (other->TimeOrigin() < TimeOrigin()) {
514 if (other->TimeOrigin() > TimeEnd()) {
519 ASSERT(other->IsFinishedDuration());
520 if (other->TimeOrigin() < TimeOrigin()) {
523 if (other->TimeEnd() < TimeOrigin()) {
526 if (other->TimeOrigin() > TimeEnd()) {
529 if (other->TimeEnd() > TimeEnd()) {
536 bool Within(int64_t time_origin_micros, int64_t time_extent_micros);
538 void set_owns_label(
bool owns_label) {
539 state_ = OwnsLabelBit::update(owns_label, state_);
542 TimelineEventArgument* arguments()
const {
return arguments_.buffer(); }
544 intptr_t arguments_length()
const {
return arguments_.length(); }
546 bool ArgsArePreSerialized()
const {
547 return PreSerializedArgsBit::decode(state_);
550 TimelineEvent*
next()
const {
return next_; }
551 void set_next(TimelineEvent*
next) { next_ =
next; }
554 void StreamInit(TimelineStream* stream) { stream_ =
stream; }
560 state_ = EventTypeField::update(
event_type, state_);
563 void set_timestamp0(int64_t value) {
567 void set_timestamp1_or_id(int64_t value) {
568 ASSERT(timestamp1_or_id_ == 0);
569 timestamp1_or_id_ =
value;
572 bool IsFinishedDuration()
const {
573 return (
event_type() == kDuration) && (timestamp1_or_id_ > timestamp0_);
576 void set_pre_serialized_args(
bool pre_serialized_args) {
577 state_ = PreSerializedArgsBit::update(pre_serialized_args, state_);
580 bool owns_label()
const {
return OwnsLabelBit::decode(state_); }
584 kPreSerializedArgsBit = 4,
589 class EventTypeField :
public BitField<uword, EventType, kEventTypeBit, 4> {};
590 class PreSerializedArgsBit
591 :
public BitField<uword, bool, kPreSerializedArgsBit, 1> {};
592 class OwnsLabelBit :
public BitField<uword, bool, kOwnsLabelBit, 1> {};
600 int64_t timestamp1_or_id_;
601 intptr_t flow_id_count_;
610 std::unique_ptr<const int64_t[]> flow_ids_;
611 TimelineEventArguments arguments_;
614 TimelineStream* stream_;
617 uint64_t isolate_group_id_;
619 void* isolate_group_data_;
620 TimelineEvent* next_;
622 friend class TimelineEventRecorder;
623 friend class TimelineEventEndlessRecorder;
624 friend class TimelineEventRingRecorder;
625 friend class TimelineEventStartupRecorder;
626 friend class TimelineEventPlatformRecorder;
627 friend class TimelineEventFuchsiaRecorder;
628 friend class TimelineEventMacosRecorder;
629#if defined(SUPPORT_PERFETTO) && !defined(PRODUCT)
630 friend class TimelineEventPerfettoFileRecorder;
632 friend class TimelineStream;
633 friend class TimelineTestHelper;
637class TimelineTrackMetadata {
639 TimelineTrackMetadata(intptr_t pid,
641 Utils::CStringUniquePtr&& track_name);
642 intptr_t pid()
const {
return pid_; }
643 intptr_t tid()
const {
return tid_; }
644 const char* track_name()
const {
return track_name_.get(); }
645 inline void set_track_name(Utils::CStringUniquePtr&& track_name);
651 void PrintJSON(
const JSONArray& jsarr_events)
const;
652#if defined(SUPPORT_PERFETTO)
657 void PopulateTracePacket(
668 Utils::CStringUniquePtr track_name_;
671class AsyncTimelineTrackMetadata {
673 AsyncTimelineTrackMetadata(intptr_t pid, intptr_t async_id);
674 intptr_t pid()
const {
return pid_; }
675 intptr_t async_id()
const {
return async_id_; }
676#if defined(SUPPORT_PERFETTO) && !defined(PRODUCT)
681 void PopulateTracePacket(
692#define TIMELINE_DURATION(thread, stream, name) \
693 TimelineBeginEndScope tbes(thread, Timeline::Get##stream##Stream(), name);
694#define TIMELINE_FUNCTION_COMPILATION_DURATION(thread, name, function) \
695 TimelineBeginEndScope tbes(thread, Timeline::GetCompilerStream(), name); \
696 if (tbes.enabled()) { \
697 tbes.SetNumArguments(1); \
698 tbes.CopyArgument(0, "function", function.ToQualifiedCString()); \
701#define TIMELINE_FUNCTION_GC_DURATION(thread, name) \
702 TimelineBeginEndScope tbes(thread, Timeline::GetGCStream(), name);
705class TimelineEventScope :
public StackResource {
707 bool enabled()
const {
return enabled_; }
709 intptr_t GetNumArguments() {
return arguments_.length(); }
710 void SetNumArguments(intptr_t
length);
712 void SetArgument(intptr_t i,
const char*
name,
char* argument);
714 void CopyArgument(intptr_t i,
const char*
name,
const char* argument);
716 void FormatArgument(intptr_t i,
const char*
name,
const char*
fmt, ...)
720 TimelineEventScope(TimelineStream* stream, const
char* label);
722 TimelineEventScope(Thread* thread, TimelineStream* stream, const
char* label);
724 bool ShouldEmitEvent()
const {
return enabled_; }
726 void set_enabled(
bool enabled) { enabled_ = enabled; }
728 const char* label()
const {
return label_; }
730 int64_t
id()
const {
return id_; }
732 TimelineEventArgument* arguments()
const {
return arguments_.buffer(); }
734 intptr_t arguments_length()
const {
return arguments_.length(); }
736 TimelineStream*
stream()
const {
return stream_; }
738 virtual ~TimelineEventScope();
740 void StealArguments(TimelineEvent*
event);
745 TimelineStream* stream_;
748 TimelineEventArguments arguments_;
754class TimelineBeginEndScope :
public TimelineEventScope {
756 TimelineBeginEndScope(TimelineStream* stream,
const char* label);
758 TimelineBeginEndScope(Thread* thread,
759 TimelineStream* stream,
762 virtual ~TimelineBeginEndScope();
772class TimelineEventBlock :
public MallocAllocated {
774 static constexpr intptr_t kBlockSize = 64;
776 explicit TimelineEventBlock(intptr_t index);
777 ~TimelineEventBlock();
779 TimelineEventBlock*
next()
const {
return next_; }
780 void set_next(TimelineEventBlock*
next) { next_ =
next; }
782 intptr_t
length()
const {
return length_; }
784 intptr_t block_index()
const {
return block_index_; }
786 bool IsEmpty()
const {
return length_ == 0; }
788 bool IsFull()
const {
return length_ == kBlockSize; }
790 TimelineEvent* At(intptr_t index) {
792 ASSERT(index < kBlockSize);
793 return &events_[index];
796 const TimelineEvent* At(intptr_t index)
const {
798 ASSERT(index < kBlockSize);
799 return &events_[index];
803 int64_t LowerTimeBound()
const;
809 inline bool InUseLocked()
const;
812 inline bool ContainsEventsThatCanBeSerializedLocked()
const;
816 void PrintJSON(JSONStream* stream)
const;
821 TimelineEvent* StartEventLocked();
823 TimelineEvent events_[kBlockSize];
824 TimelineEventBlock* next_;
826 intptr_t block_index_;
829 OSThread* current_owner_;
835 friend class TimelineEventRecorder;
836 friend class TimelineEventEndlessRecorder;
837 friend class TimelineEventRingRecorder;
838 friend class TimelineEventStartupRecorder;
839 friend class TimelineEventPlatformRecorder;
840 friend class TimelineTestHelper;
841 friend class JSONStream;
849class TimelineEventFilter :
public ValueObject {
851 TimelineEventFilter(int64_t time_origin_micros = -1,
852 int64_t time_extent_micros = -1);
854 virtual ~TimelineEventFilter();
856 virtual bool IncludeEvent(TimelineEvent*
event)
const {
857 if (
event ==
nullptr) {
860 return event->IsValid();
863 int64_t time_origin_micros()
const {
return time_origin_micros_; }
865 int64_t time_extent_micros()
const {
return time_extent_micros_; }
868 int64_t time_origin_micros_;
869 int64_t time_extent_micros_;
872class IsolateTimelineEventFilter :
public TimelineEventFilter {
874 explicit IsolateTimelineEventFilter(
Dart_Port isolate_id,
875 int64_t time_origin_micros = -1,
876 int64_t time_extent_micros = -1);
878 bool IncludeEvent(TimelineEvent*
event)
const final {
879 return event->IsValid() && (
event->isolate_id() == isolate_id_);
887class TimelineEventRecorder :
public MallocAllocated {
889 TimelineEventRecorder();
890 virtual ~TimelineEventRecorder();
894 virtual void PrintJSON(JSONStream* js, TimelineEventFilter* filter) = 0;
895#if defined(SUPPORT_PERFETTO)
899 virtual void PrintPerfettoTimeline(JSONStream* js,
900 const TimelineEventFilter& filter) = 0;
902 virtual void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter) = 0;
904 virtual const char*
name()
const = 0;
905 virtual intptr_t
Size() = 0;
907 virtual TimelineEventBlock* GetNewBlockLocked() = 0;
908 void FinishBlock(TimelineEventBlock* block);
911 void AddTrackMetadataBasedOnThread(
const intptr_t process_id,
912 const intptr_t trace_id,
913 const char* thread_name);
914 void AddAsyncTrackMetadataBasedOnEvent(
const TimelineEvent&
event);
917 SimpleHashMap& track_uuid_to_track_metadata() {
918 return track_uuid_to_track_metadata_;
920 SimpleHashMap& async_track_uuid_to_track_metadata() {
921 return async_track_uuid_to_track_metadata_;
923#if defined(SUPPORT_PERFETTO) && !defined(PRODUCT)
924 protozero::HeapBuffered<perfetto::protos::pbzero::TracePacket>& packet() {
930 void WriteTo(
const char* directory);
934 virtual TimelineEvent* StartEvent() = 0;
935 virtual void CompleteEvent(TimelineEvent*
event) = 0;
937 virtual TimelineEventBlock* GetHeadBlockLocked() = 0;
939 virtual void ClearLocked() = 0;
943 void PrintJSONMeta(
const JSONArray& jsarr_events);
944#if defined(SUPPORT_PERFETTO)
949 void PrintPerfettoMeta(JSONBase64String* jsonBase64String);
952 TimelineEvent* ThreadBlockStartEvent();
953 void ThreadBlockCompleteEvent(TimelineEvent*
event);
955 void ResetTimeTracking();
956 void ReportTime(int64_t micros);
957 int64_t TimeOriginMicros()
const;
958 int64_t TimeExtentMicros()
const;
961 int64_t time_low_micros_;
962 int64_t time_high_micros_;
964 friend class TimelineEvent;
965 friend class TimelineEventBlock;
966 friend class TimelineStream;
967 friend class TimelineTestHelper;
968 friend class Timeline;
969 friend class OSThread;
972 static constexpr intptr_t kTrackUuidToTrackMetadataInitialCapacity = 1 << 4;
973 Mutex track_uuid_to_track_metadata_lock_;
974 SimpleHashMap track_uuid_to_track_metadata_;
975 Mutex async_track_uuid_to_track_metadata_lock_;
976 SimpleHashMap async_track_uuid_to_track_metadata_;
977#if defined(SUPPORT_PERFETTO) && !defined(PRODUCT)
981 protozero::HeapBuffered<perfetto::protos::pbzero::TracePacket> packet_;
988class TimelineEventFixedBufferRecorder :
public TimelineEventRecorder {
990 static constexpr intptr_t kDefaultCapacity = 32 *
KB;
992 explicit TimelineEventFixedBufferRecorder(intptr_t capacity);
993 virtual ~TimelineEventFixedBufferRecorder();
996 void PrintJSON(JSONStream* js, TimelineEventFilter* filter)
final;
997#if defined(SUPPORT_PERFETTO)
998 void PrintPerfettoTimeline(JSONStream* js,
999 const TimelineEventFilter& filter)
final;
1001 void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter)
final;
1007 TimelineEvent* StartEvent();
1008 void CompleteEvent(TimelineEvent*
event);
1009 TimelineEventBlock* GetHeadBlockLocked();
1011 intptr_t FindOldestBlockIndexLocked()
const;
1015 void PrintJSONEvents(
const JSONArray& array,
1016 const TimelineEventFilter& filter);
1017#if defined(SUPPORT_PERFETTO)
1018 void PrintPerfettoEvents(JSONBase64String* jsonBase64String,
1019 const TimelineEventFilter& filter);
1023 VirtualMemory* memory_;
1024 TimelineEventBlock* blocks_;
1026 intptr_t num_blocks_;
1027 intptr_t block_cursor_;
1030#if !defined(PRODUCT)
1031 inline void PrintEventsCommon(
1032 const TimelineEventFilter& filter,
1033 std::function<
void(
const TimelineEvent&)>&& print_impl);
1039class TimelineEventRingRecorder :
public TimelineEventFixedBufferRecorder {
1041 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity)
1042 : TimelineEventFixedBufferRecorder(capacity) {}
1043 virtual ~TimelineEventRingRecorder() {}
1045 const char*
name()
const {
return RING_RECORDER_NAME; }
1048 TimelineEventBlock* GetNewBlockLocked();
1053class TimelineEventStartupRecorder :
public TimelineEventFixedBufferRecorder {
1055 explicit TimelineEventStartupRecorder(intptr_t capacity = kDefaultCapacity)
1056 : TimelineEventFixedBufferRecorder(capacity) {}
1057 virtual ~TimelineEventStartupRecorder() {}
1059 const char*
name()
const {
return STARTUP_RECORDER_NAME; }
1062 TimelineEventBlock* GetNewBlockLocked();
1067class TimelineEventCallbackRecorder :
public TimelineEventRecorder {
1069 TimelineEventCallbackRecorder();
1070 virtual ~TimelineEventCallbackRecorder();
1073 void PrintJSON(JSONStream* js, TimelineEventFilter* filter)
final;
1074#if defined(SUPPORT_PERFETTO)
1075 void PrintPerfettoTimeline(JSONStream* js,
1076 const TimelineEventFilter& filter)
final;
1078 void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter)
final;
1083 virtual void OnEvent(TimelineEvent*
event) = 0;
1085 const char*
name()
const {
return CALLBACK_RECORDER_NAME; }
1086 intptr_t
Size() {
return 0; }
1089 TimelineEventBlock* GetNewBlockLocked() {
UNREACHABLE(); }
1090 TimelineEventBlock* GetHeadBlockLocked() {
UNREACHABLE(); }
1091 void ClearLocked() {
ASSERT(lock_.IsOwnedByCurrentThread()); }
1092 TimelineEvent* StartEvent();
1093 void CompleteEvent(TimelineEvent*
event);
1098class TimelineEventEmbedderCallbackRecorder
1099 :
public TimelineEventCallbackRecorder {
1101 TimelineEventEmbedderCallbackRecorder() {}
1102 virtual ~TimelineEventEmbedderCallbackRecorder() {}
1104 virtual void OnEvent(TimelineEvent*
event);
1108class TimelineEventNopRecorder :
public TimelineEventCallbackRecorder {
1110 TimelineEventNopRecorder() {}
1111 virtual ~TimelineEventNopRecorder() {}
1113 virtual void OnEvent(TimelineEvent*
event);
1119class TimelineEventEndlessRecorder :
public TimelineEventRecorder {
1121 TimelineEventEndlessRecorder();
1122 virtual ~TimelineEventEndlessRecorder();
1125 void PrintJSON(JSONStream* js, TimelineEventFilter* filter)
final;
1126#if defined(SUPPORT_PERFETTO)
1127 void PrintPerfettoTimeline(JSONStream* js,
1128 const TimelineEventFilter& filter)
final;
1130 void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter)
final;
1133 const char*
name()
const {
return ENDLESS_RECORDER_NAME; }
1134 intptr_t
Size() {
return block_index_ *
sizeof(TimelineEventBlock); }
1137 TimelineEvent* StartEvent();
1138 void CompleteEvent(TimelineEvent*
event);
1139 TimelineEventBlock* GetNewBlockLocked();
1140 TimelineEventBlock* GetHeadBlockLocked();
1144 void PrintJSONEvents(
const JSONArray& array,
1145 const TimelineEventFilter& filter);
1146#if defined(SUPPORT_PERFETTO)
1147 void PrintPerfettoEvents(JSONBase64String* jsonBase64String,
1148 const TimelineEventFilter& filter);
1152 TimelineEventBlock* head_;
1153 TimelineEventBlock* tail_;
1154 intptr_t block_index_;
1157#if !defined(PRODUCT)
1158 inline void PrintEventsCommon(
1159 const TimelineEventFilter& filter,
1160 std::function<
void(
const TimelineEvent&)>&& print_impl);
1163 friend class TimelineTestHelper;
1169class TimelineEventPlatformRecorder :
public TimelineEventRecorder {
1171 TimelineEventPlatformRecorder();
1172 virtual ~TimelineEventPlatformRecorder();
1175 void PrintJSON(JSONStream* js, TimelineEventFilter* filter)
final;
1176#if defined(SUPPORT_PERFETTO)
1177 void PrintPerfettoTimeline(JSONStream* js,
1178 const TimelineEventFilter& filter)
final;
1180 void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter)
final;
1185 virtual void OnEvent(TimelineEvent*
event) = 0;
1187 virtual const char*
name()
const = 0;
1190 TimelineEventBlock* GetNewBlockLocked() {
UNREACHABLE(); }
1191 TimelineEventBlock* GetHeadBlockLocked() {
UNREACHABLE(); }
1192 void ClearLocked() {
ASSERT(lock_.IsOwnedByCurrentThread()); }
1193 TimelineEvent* StartEvent();
1194 void CompleteEvent(TimelineEvent*
event);
1197#if defined(DART_HOST_OS_FUCHSIA)
1199class TimelineEventFuchsiaRecorder :
public TimelineEventPlatformRecorder {
1201 TimelineEventFuchsiaRecorder() {}
1202 virtual ~TimelineEventFuchsiaRecorder() {}
1204 const char*
name()
const {
return FUCHSIA_RECORDER_NAME; }
1205 intptr_t
Size() {
return 0; }
1208 void OnEvent(TimelineEvent*
event);
1212#if defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_LINUX)
1216class TimelineEventSystraceRecorder :
public TimelineEventPlatformRecorder {
1218 TimelineEventSystraceRecorder();
1219 virtual ~TimelineEventSystraceRecorder();
1221 static intptr_t PrintSystrace(TimelineEvent*
event,
1225 const char*
name()
const {
return SYSTRACE_RECORDER_NAME; }
1226 intptr_t
Size() {
return 0; }
1229 void OnEvent(TimelineEvent*
event);
1235#if defined(DART_HOST_OS_MACOS)
1238class TimelineEventMacosRecorder :
public TimelineEventPlatformRecorder {
1240 TimelineEventMacosRecorder();
1241 virtual ~TimelineEventMacosRecorder();
1243 const char*
name()
const {
return MACOS_RECORDER_NAME; }
1244 intptr_t
Size() {
return 0; }
1247 void OnEvent(TimelineEvent*
event);
1251class TimelineEventFileRecorderBase :
public TimelineEventPlatformRecorder {
1253 explicit TimelineEventFileRecorderBase(
const char* path);
1254 virtual ~TimelineEventFileRecorderBase();
1256 intptr_t
Size() final {
return 0; }
1261 void Write(
const char*
buffer, intptr_t len)
const;
1263 void CompleteEvent(TimelineEvent*
event)
final;
1267 virtual void DrainImpl(
const TimelineEvent&
event) = 0;
1270 TimelineEvent* head_;
1271 TimelineEvent* tail_;
1273 bool shutting_down_;
1278class TimelineEventFileRecorder :
public TimelineEventFileRecorderBase {
1280 explicit TimelineEventFileRecorder(
const char* path);
1281 virtual ~TimelineEventFileRecorder();
1283 const char*
name() const final {
return FILE_RECORDER_NAME; }
1286 void DrainImpl(
const TimelineEvent&
event)
final;
1291#if defined(SUPPORT_PERFETTO) && !defined(PRODUCT)
1292class TimelineEventPerfettoFileRecorder :
public TimelineEventFileRecorderBase {
1294 explicit TimelineEventPerfettoFileRecorder(
const char* path);
1295 virtual ~TimelineEventPerfettoFileRecorder();
1297 const char*
name() const final {
return PERFETTO_FILE_RECORDER_NAME; }
1301 protozero::HeapBuffered<perfetto::protos::pbzero::TracePacket>* packet)
1303 void DrainImpl(
const TimelineEvent&
event)
final;
1307class DartTimelineEventHelpers :
public AllStatic {
1316 static void ReportTaskEvent(TimelineEvent*
event,
1318 intptr_t flow_id_count,
1319 std::unique_ptr<
const int64_t[]>& flow_ids,
static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment)
static float next(float f)
ax::mojom::Event event_type
#define COMPILE_ASSERT(expr)
const char * name() const
static intptr_t enabled_offset()
TimelineEvent * StartEvent()
void set_enabled(bool enabled)
TimelineStream(const char *name, const char *fuchsia_name, bool static_labels, bool enabled)
const char * fuchsia_name() const
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
static const uint8_t buffer[]
std::variant< Lower, Cross, Upper > EventType
static SkString fmt(SkColor4f c)
#define OFFSET_OF(type, field)