24 Timeline::recorder_ =
new T();
34 delete Timeline::recorder_;
35 Timeline::recorder_ = recorder_;
38 T*
recorder() {
return static_cast<T*
>(Timeline::recorder()); }
41 TimelineEventRecorder* recorder_;
51 return recorder.lock_;
56 const char* label =
"fake",
60 TimelineEvent*
event = block->StartEventLocked();
62 event->DurationBegin(label);
73 ASSERT(recorder !=
nullptr);
76 TimelineEvent*
event = recorder->StartEvent();
79 recorder->CompleteEvent(
event);
82 static void FakeBegin(TimelineEventRecorder* recorder,
85 ASSERT(recorder !=
nullptr);
88 TimelineEvent*
event = recorder->StartEvent();
90 event->Begin(label, -1,
start);
91 recorder->CompleteEvent(
event);
94 static void FakeEnd(TimelineEventRecorder* recorder,
97 ASSERT(recorder !=
nullptr);
100 TimelineEvent*
event = recorder->StartEvent();
102 event->End(label,
end);
103 recorder->CompleteEvent(
event);
106 static void FinishBlock(TimelineEventBlock* block) { block->Finish(); }
120 event.Instant(
"hello");
135 event.DurationBegin(
"apple");
137 int64_t current_duration =
event.TimeDuration();
140 EXPECT_GE(
event.TimeDuration(), current_duration);
150 event.DurationBegin(
"apple");
154 event.PrintJSON(&
js);
156 EXPECT_SUBSTRING(
"\"cat\":\"testStream\"",
js.ToCString());
158 EXPECT_SUBSTRING(
"\"name\":\"apple\"",
js.ToCString());
160 EXPECT_SUBSTRING(
"\"ph\":\"X\"",
js.ToCString());
162 EXPECT_SUBSTRING(
"\"ts\":",
js.ToCString());
164 EXPECT_SUBSTRING(
"\"dur\":",
js.ToCString());
169#if defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_LINUX)
171 const intptr_t kBufferLength = 1024;
172 char buffer[kBufferLength];
175 TimelineStream
stream(
"testStream",
"testStream",
false,
true);
182 event.Begin(
"apple", 1, 2);
183 TimelineEventSystraceRecorder::PrintSystrace(&
event, &
buffer[0],
185 EXPECT_SUBSTRING(
"|apple",
buffer);
186 EXPECT_SUBSTRING(
"B|",
buffer);
189 event.End(
"apple", 2, 3);
190 TimelineEventSystraceRecorder::PrintSystrace(&
event, &
buffer[0],
192 EXPECT_STREQ(
"E",
buffer);
196 event.Counter(
"CTR", 1);
198 event.SetNumArguments(2);
200 event.CopyArgument(0,
"cats",
"4");
202 event.CopyArgument(1,
"dogs",
"1");
203 TimelineEventSystraceRecorder::PrintSystrace(&
event, &
buffer[0],
205 EXPECT_SUBSTRING(
"C|",
buffer);
206 EXPECT_SUBSTRING(
"|CTR|4",
buffer);
210 event.Duration(
"DUR", 0, 1);
211 TimelineEventSystraceRecorder::PrintSystrace(&
event, &
buffer[0],
226 event.SetNumArguments(4);
230 event.DurationBegin(
"apple");
231 event.SetNumArguments(2);
232 event.CopyArgument(0,
"arg1",
"value1");
233 event.CopyArgument(1,
"arg2",
"value2");
245 event.DurationBegin(
"apple");
246 event.SetNumArguments(2);
247 event.CopyArgument(0,
"arg1",
"value1");
248 event.CopyArgument(1,
"arg2",
"value2");
254 event.PrintJSON(&
js);
257 EXPECT_SUBSTRING(
"\"arg1\":\"value1\"",
js.ToCString());
258 EXPECT_SUBSTRING(
"\"arg2\":\"value2\"",
js.ToCString());
264 TimelineEventFilter filter;
265 Timeline::recorder()->PrintJSON(&
js, &filter);
267 EXPECT_SUBSTRING(
"\"type\":\"Timeline\"",
js.ToCString());
269 EXPECT_SUBSTRING(
"\"traceEvents\":[",
js.ToCString());
276 for (intptr_t
i = 0;
i < TimelineEvent::kNumEventTypes;
i++) {
286 intptr_t counts_[TimelineEvent::kNumEventTypes];
295 EXPECT_EQ(0,
override.recorder()->CountFor(
302 TimelineEvent*
event =
nullptr;
304 event =
stream.StartEvent();
305 EXPECT_EQ(0,
override.recorder()->CountFor(TimelineEvent::kDuration));
306 event->DurationBegin(
"cabbage");
307 EXPECT_EQ(0,
override.recorder()->CountFor(TimelineEvent::kDuration));
309 EXPECT_EQ(0,
override.recorder()->CountFor(TimelineEvent::kDuration));
311 EXPECT_EQ(1,
override.recorder()->CountFor(TimelineEvent::kDuration));
313 event =
stream.StartEvent();
314 EXPECT_EQ(0,
override.recorder()->CountFor(TimelineEvent::kInstant));
315 event->Instant(
"instantCabbage");
316 EXPECT_EQ(0,
override.recorder()->CountFor(TimelineEvent::kInstant));
318 EXPECT_EQ(1,
override.recorder()->CountFor(TimelineEvent::kInstant));
320 event =
stream.StartEvent();
321 EXPECT_EQ(0,
override.recorder()->CountFor(TimelineEvent::kAsyncBegin));
322 int64_t async_id = thread->GetNextTaskId();
324 event->AsyncBegin(
"asyncBeginCabbage", async_id);
325 EXPECT_EQ(0,
override.recorder()->CountFor(TimelineEvent::kAsyncBegin));
327 EXPECT_EQ(1,
override.recorder()->CountFor(TimelineEvent::kAsyncBegin));
329 event =
stream.StartEvent();
330 EXPECT_EQ(0,
override.recorder()->CountFor(TimelineEvent::kAsyncInstant));
331 event->AsyncInstant(
"asyncInstantCabbage", async_id);
332 EXPECT_EQ(0,
override.recorder()->CountFor(TimelineEvent::kAsyncInstant));
334 EXPECT_EQ(1,
override.recorder()->CountFor(TimelineEvent::kAsyncInstant));
336 event =
stream.StartEvent();
337 EXPECT_EQ(0,
override.recorder()->CountFor(TimelineEvent::kAsyncEnd));
338 event->AsyncEnd(
"asyncEndCabbage", async_id);
339 EXPECT_EQ(0,
override.recorder()->CountFor(TimelineEvent::kAsyncEnd));
341 EXPECT_EQ(1,
override.recorder()->CountFor(TimelineEvent::kAsyncEnd));
347 TimelineEventRingRecorder* recorder =
354 TimelineEventBlock* block_0 = Timeline::recorder()->GetNewBlockLocked();
355 EXPECT(block_0 !=
nullptr);
356 TimelineEventBlock* block_1 = Timeline::recorder()->GetNewBlockLocked();
357 EXPECT(block_1 !=
nullptr);
359 EXPECT(block_0 == Timeline::recorder()->GetNewBlockLocked());
372 TimelineEventFilter filter;
373 Timeline::recorder()->PrintJSON(&
js, &filter);
378 const char* alpha = strstr(
js.ToCString(),
"Alpha");
379 const char* beta = strstr(
js.ToCString(),
"Beta");
384 struct ReportEventsArguments {
385 Monitor& synchronization_monitor;
386 TimelineEventRecorder& recorder;
392 TimelineEventRingRecorder& recorder =
395 Monitor synchronization_monitor;
397 TimelineEventFilter filter;
398 ReportEventsArguments report_events_1_arguments{synchronization_monitor,
400 ReportEventsArguments report_events_2_arguments{synchronization_monitor,
409 [](
uword arguments_ptr) {
410 ReportEventsArguments& arguments =
411 *
reinterpret_cast<ReportEventsArguments*
>(arguments_ptr);
421 reinterpret_cast<uword>(&report_events_1_arguments));
424 [](
uword arguments_ptr) {
425 ReportEventsArguments& arguments =
426 *
reinterpret_cast<ReportEventsArguments*
>(arguments_ptr);
436 reinterpret_cast<uword>(&report_events_2_arguments));
438 recorder.PrintJSON(&
js, &filter);
452#define FAKE_PROCESS_ID 1
453#define FAKE_TRACE_ID 1
456 struct ReportMetadataArguments {
457 Monitor& synchronization_monitor;
458 TimelineEventRecorder& recorder;
462 Monitor synchronization_monitor;
463 TimelineEventRecorder& recorder = *Timeline::recorder();
470 TimelineEventFilter filter;
471 ReportMetadataArguments report_metadata_1_arguments{synchronization_monitor,
473 ReportMetadataArguments report_metadata_2_arguments{synchronization_monitor,
477 [](
uword arguments_ptr) {
478 ReportMetadataArguments& arguments =
479 *
reinterpret_cast<ReportMetadataArguments*
>(arguments_ptr);
480 arguments.recorder.AddTrackMetadataBasedOnThread(
487 reinterpret_cast<uword>(&report_metadata_1_arguments));
490 [](
uword arguments_ptr) {
491 ReportMetadataArguments& arguments =
492 *
reinterpret_cast<ReportMetadataArguments*
>(arguments_ptr);
493 arguments.recorder.AddTrackMetadataBasedOnThread(
500 reinterpret_cast<uword>(&report_metadata_2_arguments));
501 recorder.PrintJSON(&
js, &filter);
512#undef FAKE_PROCESS_ID
517#if defined(SUPPORT_TIMELINE)
521static bool saw_begin;
523static void* expected_isolate_data;
524static void* expected_isolate_group_data;
530 (strcmp(
event->label,
"TestEvent") == 0)) {
532 EXPECT_NE(0,
event->timestamp0);
533 EXPECT_EQ(expected_isolate,
event->isolate);
534 EXPECT_EQ(expected_isolate_group,
event->isolate_group);
535 EXPECT_EQ(expected_isolate_data,
event->isolate_data);
536 EXPECT_EQ(expected_isolate_group_data,
event->isolate_group_data);
537 EXPECT_STREQ(
"Dart",
event->stream);
538 EXPECT_EQ(1,
event->argument_count);
539 EXPECT_STREQ(
"Dart Arguments",
event->arguments[0].name);
540 EXPECT_STREQ(
"{\"key\":\"value\"}",
event->arguments[0].value);
544 (strcmp(
event->label,
"TestEvent") == 0)) {
546 EXPECT_NE(0,
event->timestamp0);
547 EXPECT_EQ(expected_isolate,
event->isolate);
548 EXPECT_EQ(expected_isolate_group,
event->isolate_group);
549 EXPECT_EQ(expected_isolate_data,
event->isolate_data);
550 EXPECT_EQ(expected_isolate_group_data,
event->isolate_group_data);
551 EXPECT_STREQ(
"Dart",
event->stream);
552 EXPECT_EQ(1,
event->argument_count);
553 EXPECT_STREQ(
"Dart Arguments",
event->arguments[0].name);
554 EXPECT_STREQ(
"{\"key\":\"value\"}",
event->arguments[0].value);
560 const char**
argv =
new const char*[argc];
561 for (intptr_t
i = 0;
i < argc - 2;
i++) {
564 argv[argc - 2] =
"--timeline_recorder=callback";
565 argv[argc - 1] =
"--timeline_streams=Dart";
577 params.start_kernel_isolate =
true;
579 int64_t isolate_data = 0;
585 TestIsolateScope scope(
nullptr, &isolate_data);
586 const char* kScriptChars =
587 "import 'dart:developer';\n"
589 " Timeline.startSync('TestEvent', arguments: {'key':'value'});\n"
590 " Timeline.finishSync();\n"
599 expected_isolate_data = &isolate_data;
intptr_t CountFor(TimelineEvent::EventType type)
void OnEvent(TimelineEvent *event)
Monitor::WaitResult Wait(int64_t millis=Monitor::kNoTimeout)
static int Start(const char *name, ThreadStartFunction function, uword parameter)
static ThreadId ThreadIdFromIntPtr(intptr_t id)
static void Join(ThreadJoinId id)
static OSThread * Current()
static ThreadJoinId GetCurrentThreadJoinId(OSThread *thread)
Mutex * timeline_block_lock() const
static const ThreadJoinId kInvalidThreadJoinId
static void Sleep(int64_t millis)
static Dart_Handle LoadTestScript(const char *script, Dart_NativeEntryResolver resolver, const char *lib_uri=RESOLVED_USER_TEST_URI, bool finalize=true, bool allow_compile_errors=false)
static Dart_IsolateShutdownCallback shutdown_callback
static Dart_IsolateGroupCreateCallback create_callback
static const char ** argv
static Dart_IsolateGroupCleanupCallback group_cleanup_callback
static const uint8_t * vm_snapshot_data
~TimelineRecorderOverride()
TimelineRecorderOverride()
TimelineRecorderOverride(T *recorder)
static void FakeThreadEvent(TimelineEventBlock *block, intptr_t ftid, const char *label="fake", TimelineStream *stream=nullptr)
static void FinishBlock(TimelineEventBlock *block)
static void FakeBegin(TimelineEventRecorder *recorder, const char *label, int64_t start)
static Mutex & GetRecorderLock(TimelineEventRecorder &recorder)
static void SetStream(TimelineEvent *event, TimelineStream *stream)
static void FakeDuration(TimelineEventRecorder *recorder, const char *label, int64_t start, int64_t end)
static void FakeEnd(TimelineEventRecorder *recorder, const char *label, int64_t end)
#define DART_INITIALIZE_PARAMS_CURRENT_VERSION
struct _Dart_Handle * Dart_Handle
int64_t Dart_IsolateGroupId
const EmbeddedViewParams * params
std::variant< Lower, Cross, Upper > EventType
DART_EXPORT Dart_Port Dart_GetMainPortId()
UNIT_TEST_CASE(PRIORITY_HEAP_WITH_INDEX__INCREASING)
DART_EXPORT Dart_IsolateGroupId Dart_CurrentIsolateGroupId()
DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, Dart_Handle name, int number_of_arguments, Dart_Handle *arguments)
static constexpr intptr_t kBlockSize
DART_EXPORT char * Dart_Initialize(Dart_InitializeParams *params)
DART_EXPORT char * Dart_Cleanup()
DART_EXPORT void Dart_SetTimelineRecorderCallback(Dart_TimelineRecorderCallback callback)
TEST_CASE(DirectoryCurrent)
Dart_Handle NewString(const char *str)
DART_EXPORT void * Dart_CurrentIsolateGroupData()
DART_EXPORT char * Dart_SetVMFlags(int argc, const char **argv)
DART_EXPORT void * Dart_CurrentIsolateData()
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
#define EXPECT_VALID(handle)