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_;
47 event->StreamInit(stream);
51 return recorder.lock_;
56 const char* label =
"fake",
60 TimelineEvent*
event = block->StartEventLocked();
62 event->DurationBegin(label);
64 if (stream !=
nullptr) {
65 event->StreamInit(stream);
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];
293 for (intptr_t i = TimelineEvent::kNone + 1; i < TimelineEvent::kNumEventTypes;
295 EXPECT_EQ(0,
override.recorder()->CountFor(
296 static_cast<TimelineEvent::EventType
>(i)));
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 =
348 new TimelineEventRingRecorder(TimelineEventBlock::kBlockSize * 2);
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 =
393 *(
new TimelineEventRingRecorder(2 * TimelineEventBlock::kBlockSize));
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);
412 for (intptr_t i = 0; i < 2 * TimelineEventBlock::kBlockSize; ++i) {
421 reinterpret_cast<uword>(&report_events_1_arguments));
424 [](
uword arguments_ptr) {
425 ReportEventsArguments& arguments =
426 *
reinterpret_cast<ReportEventsArguments*
>(arguments_ptr);
427 for (intptr_t i = 0; i < 2 * TimelineEventBlock::kBlockSize; ++i) {
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 UNIT_TEST_CASE(name)
#define DART_INITIALIZE_PARAMS_CURRENT_VERSION
struct _Dart_Handle * Dart_Handle
int64_t Dart_IsolateGroupId
const EmbeddedViewParams * params
static const uint8_t buffer[]
DART_EXPORT Dart_Port Dart_GetMainPortId()
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)
DART_EXPORT char * Dart_Initialize(Dart_InitializeParams *params)
DART_EXPORT char * Dart_Cleanup()
DART_EXPORT void Dart_SetTimelineRecorderCallback(Dart_TimelineRecorderCallback callback)
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()
#define EXPECT_VALID(handle)