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,
365 void AsyncEnd(
const char* label,
373 void Instant(
const char* label,
376 void Duration(
const char* label, int64_t start_micros, int64_t end_micros);
378 void Begin(
const char* label,
382 void End(
const char* label,
386 void Counter(
const char* label,
389 void FlowBegin(
const char* label,
392 void FlowStep(
const char* label,
395 void FlowEnd(
const char* label,
399 void Metadata(
const char* label,
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;
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 {
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_);
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,
642 intptr_t pid()
const {
return pid_; }
643 intptr_t tid()
const {
return tid_; }
644 const char* track_name()
const {
return track_name_.get(); }
651 void PrintJSON(
const JSONArray& jsarr_events)
const;
652#if defined(SUPPORT_PERFETTO)
657 void PopulateTracePacket(
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,
762 virtual ~TimelineBeginEndScope();
772class TimelineEventBlock :
public MallocAllocated {
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) {
793 return &events_[index];
796 const TimelineEvent* At(intptr_t index)
const {
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();
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,
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,
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
static int64_t GetCurrentMonotonicMicrosForTimeline()
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
Dart_NativeFunction function
std::variant< Lower, Cross, Upper > EventType
static void Finish(Thread *thread)
CAllocUniquePtr< char > CStringUniquePtr
static constexpr const char * kNone
static constexpr intptr_t kBlockSize
void(* callback_)(Dart_Handle)
static void Free(FreeList *free_list, uword address, intptr_t size, bool is_protected)
COMPILE_ASSERT(kUnreachableReference==WeakTable::kNoValue)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
static SkString fmt(SkColor4f c)
bool EMSCRIPTEN_KEEPALIVE IsEmpty(const SkPath &path)
static DecodeResult decode(std::string path)
#define OFFSET_OF(type, field)