Flutter Engine
The Flutter Engine
timeline_test.cc
Go to the documentation of this file.
1// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include <cstring>
6#include <memory>
7
8#include "platform/assert.h"
9
10#include "vm/dart_api_impl.h"
11#include "vm/dart_api_state.h"
12#include "vm/globals.h"
13#include "vm/timeline.h"
14#include "vm/unit_test.h"
15
16namespace dart {
17
18#ifndef PRODUCT
19
20template <class T>
22 public:
23 TimelineRecorderOverride() : recorder_(Timeline::recorder()) {
24 Timeline::recorder_ = new T();
25 }
26
28 : recorder_(Timeline::recorder()) {
29 Timeline::recorder_ = recorder;
30 }
31
33 Timeline::Clear();
34 delete Timeline::recorder_;
35 Timeline::recorder_ = recorder_;
36 }
37
38 T* recorder() { return static_cast<T*>(Timeline::recorder()); }
39
40 private:
41 TimelineEventRecorder* recorder_;
42};
43
45 public:
46 static void SetStream(TimelineEvent* event, TimelineStream* stream) {
47 event->StreamInit(stream);
48 }
49
50 static Mutex& GetRecorderLock(TimelineEventRecorder& recorder) {
51 return recorder.lock_;
52 }
53
54 static void FakeThreadEvent(TimelineEventBlock* block,
55 intptr_t ftid,
56 const char* label = "fake",
57 TimelineStream* stream = nullptr) {
58 OSThread& current_thread = *OSThread::Current();
59 MutexLocker ml(current_thread.timeline_block_lock());
60 TimelineEvent* event = block->StartEventLocked();
61 ASSERT(event != nullptr);
62 event->DurationBegin(label);
63 event->thread_ = OSThread::ThreadIdFromIntPtr(ftid);
64 if (stream != nullptr) {
65 event->StreamInit(stream);
66 }
67 }
68
69 static void FakeDuration(TimelineEventRecorder* recorder,
70 const char* label,
71 int64_t start,
72 int64_t end) {
73 ASSERT(recorder != nullptr);
74 ASSERT(start < end);
75 ASSERT(label != nullptr);
76 TimelineEvent* event = recorder->StartEvent();
77 ASSERT(event != nullptr);
78 event->Duration(label, start, end);
79 recorder->CompleteEvent(event);
80 }
81
82 static void FakeBegin(TimelineEventRecorder* recorder,
83 const char* label,
84 int64_t start) {
85 ASSERT(recorder != nullptr);
86 ASSERT(label != nullptr);
87 ASSERT(start >= 0);
88 TimelineEvent* event = recorder->StartEvent();
89 ASSERT(event != nullptr);
90 event->Begin(label, /*id=*/-1, start);
91 recorder->CompleteEvent(event);
92 }
93
94 static void FakeEnd(TimelineEventRecorder* recorder,
95 const char* label,
96 int64_t end) {
97 ASSERT(recorder != nullptr);
98 ASSERT(label != nullptr);
99 ASSERT(end >= 0);
100 TimelineEvent* event = recorder->StartEvent();
101 ASSERT(event != nullptr);
102 event->End(label, end);
103 recorder->CompleteEvent(event);
104 }
105
106 static void FinishBlock(TimelineEventBlock* block) { block->Finish(); }
107};
108
109TEST_CASE(TimelineEventIsValid) {
110 // Create a test stream.
111 TimelineStream stream("testStream", "testStream", false, true);
112
113 TimelineEvent event;
115
116 // Starts invalid.
117 EXPECT(!event.IsValid());
118
119 // Becomes valid.
120 event.Instant("hello");
121 EXPECT(event.IsValid());
122
123 // Becomes invalid.
124 event.Reset();
125 EXPECT(!event.IsValid());
126}
127
128TEST_CASE(TimelineEventDuration) {
129 // Create a test stream.
130 TimelineStream stream("testStream", "testStream", false, true);
131
132 // Create a test event.
133 TimelineEvent event;
135 event.DurationBegin("apple");
136 // Measure the duration.
137 int64_t current_duration = event.TimeDuration();
138 event.SetTimeEnd();
139 // Verify that duration is larger.
140 EXPECT_GE(event.TimeDuration(), current_duration);
141}
142
143TEST_CASE(TimelineEventDurationPrintJSON) {
144 // Create a test stream.
145 TimelineStream stream("testStream", "testStream", false, true);
146
147 // Create a test event.
148 TimelineEvent event;
150 event.DurationBegin("apple");
151 {
152 // Test printing to JSON.
154 event.PrintJSON(&js);
155 // Check category
156 EXPECT_SUBSTRING("\"cat\":\"testStream\"", js.ToCString());
157 // Check name.
158 EXPECT_SUBSTRING("\"name\":\"apple\"", js.ToCString());
159 // Check phase.
160 EXPECT_SUBSTRING("\"ph\":\"X\"", js.ToCString());
161 // Check that ts key is present.
162 EXPECT_SUBSTRING("\"ts\":", js.ToCString());
163 // Check that dur key is present.
164 EXPECT_SUBSTRING("\"dur\":", js.ToCString());
165 }
166 event.SetTimeEnd();
167}
168
169#if defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_LINUX)
170TEST_CASE(TimelineEventPrintSystrace) {
171 const intptr_t kBufferLength = 1024;
172 char buffer[kBufferLength];
173
174 // Create a test stream.
175 TimelineStream stream("testStream", "testStream", false, true);
176
177 // Create a test event.
178 TimelineEvent event;
180
181 // Test a Begin event.
182 event.Begin("apple", 1, 2);
183 TimelineEventSystraceRecorder::PrintSystrace(&event, &buffer[0],
184 kBufferLength);
185 EXPECT_SUBSTRING("|apple", buffer);
186 EXPECT_SUBSTRING("B|", buffer);
187
188 // Test an End event.
189 event.End("apple", 2, 3);
190 TimelineEventSystraceRecorder::PrintSystrace(&event, &buffer[0],
191 kBufferLength);
192 EXPECT_STREQ("E", buffer);
193
194 // Test a Counter event. We only report the first counter value (in this case
195 // "4").
196 event.Counter("CTR", 1);
197 // We have two counters.
198 event.SetNumArguments(2);
199 // Set the first counter value.
200 event.CopyArgument(0, "cats", "4");
201 // Set the second counter value.
202 event.CopyArgument(1, "dogs", "1");
203 TimelineEventSystraceRecorder::PrintSystrace(&event, &buffer[0],
204 kBufferLength);
205 EXPECT_SUBSTRING("C|", buffer);
206 EXPECT_SUBSTRING("|CTR|4", buffer);
207
208 // Test a duration event. This event kind is not supported so we should
209 // serialize it to an empty string.
210 event.Duration("DUR", 0, 1);
211 TimelineEventSystraceRecorder::PrintSystrace(&event, &buffer[0],
212 kBufferLength);
213 EXPECT_STREQ("", buffer);
214}
215#endif // defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_LINUX)
216
217TEST_CASE(TimelineEventArguments) {
218 // Create a test stream.
219 TimelineStream stream("testStream", "testStream", false, true);
220
221 // Create a test event.
222 TimelineEvent event;
224
225 // Allocate room for four arguments.
226 event.SetNumArguments(4);
227 // Reset.
228 event.Reset();
229
230 event.DurationBegin("apple");
231 event.SetNumArguments(2);
232 event.CopyArgument(0, "arg1", "value1");
233 event.CopyArgument(1, "arg2", "value2");
234 event.SetTimeEnd();
235}
236
237TEST_CASE(TimelineEventArgumentsPrintJSON) {
238 // Create a test stream.
239 TimelineStream stream("testStream", "testStream", false, true);
240
241 // Create a test event.
242 TimelineEvent event;
244
245 event.DurationBegin("apple");
246 event.SetNumArguments(2);
247 event.CopyArgument(0, "arg1", "value1");
248 event.CopyArgument(1, "arg2", "value2");
249 event.SetTimeEnd();
250
251 {
252 // Test printing to JSON.
254 event.PrintJSON(&js);
255
256 // Check both arguments.
257 EXPECT_SUBSTRING("\"arg1\":\"value1\"", js.ToCString());
258 EXPECT_SUBSTRING("\"arg2\":\"value2\"", js.ToCString());
259 }
260}
261
262TEST_CASE(TimelineEventBufferPrintJSON) {
264 TimelineEventFilter filter;
265 Timeline::recorder()->PrintJSON(&js, &filter);
266 // Check the type.
267 EXPECT_SUBSTRING("\"type\":\"Timeline\"", js.ToCString());
268 // Check that there is a traceEvents array.
269 EXPECT_SUBSTRING("\"traceEvents\":[", js.ToCString());
270}
271
272// Count the number of each event type seen.
273class EventCounterRecorder : public TimelineEventCallbackRecorder {
274 public:
276 for (intptr_t i = 0; i < TimelineEvent::kNumEventTypes; i++) {
277 counts_[i] = 0;
278 }
279 }
280
281 void OnEvent(TimelineEvent* event) { counts_[event->event_type()]++; }
282
283 intptr_t CountFor(TimelineEvent::EventType type) { return counts_[type]; }
284
285 private:
286 intptr_t counts_[TimelineEvent::kNumEventTypes];
287};
288
289TEST_CASE(TimelineEventCallbackRecorderBasic) {
291
292 // Initial counts are all zero.
293 for (intptr_t i = TimelineEvent::kNone + 1; i < TimelineEvent::kNumEventTypes;
294 i++) {
295 EXPECT_EQ(0, override.recorder()->CountFor(
296 static_cast<TimelineEvent::EventType>(i)));
297 }
298
299 // Create a test stream.
300 TimelineStream stream("testStream", "testStream", false, true);
301
302 TimelineEvent* event = nullptr;
303
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));
308 event->SetTimeEnd();
309 EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kDuration));
310 event->Complete();
311 EXPECT_EQ(1, override.recorder()->CountFor(TimelineEvent::kDuration));
312
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));
317 event->Complete();
318 EXPECT_EQ(1, override.recorder()->CountFor(TimelineEvent::kInstant));
319
320 event = stream.StartEvent();
321 EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kAsyncBegin));
322 int64_t async_id = thread->GetNextTaskId();
323 EXPECT(async_id != 0);
324 event->AsyncBegin("asyncBeginCabbage", async_id);
325 EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kAsyncBegin));
326 event->Complete();
327 EXPECT_EQ(1, override.recorder()->CountFor(TimelineEvent::kAsyncBegin));
328
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));
333 event->Complete();
334 EXPECT_EQ(1, override.recorder()->CountFor(TimelineEvent::kAsyncInstant));
335
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));
340 event->Complete();
341 EXPECT_EQ(1, override.recorder()->CountFor(TimelineEvent::kAsyncEnd));
342}
343
344TEST_CASE(TimelineRingRecorderJSONOrder) {
345 TimelineStream stream("testStream", "testStream", false, true);
346
347 TimelineEventRingRecorder* recorder =
348 new TimelineEventRingRecorder(TimelineEventBlock::kBlockSize * 2);
350
351 {
352 Mutex& recorder_lock = TimelineTestHelper::GetRecorderLock(*recorder);
353 MutexLocker ml(&recorder_lock);
354 TimelineEventBlock* block_0 = Timeline::recorder()->GetNewBlockLocked();
355 EXPECT(block_0 != nullptr);
356 TimelineEventBlock* block_1 = Timeline::recorder()->GetNewBlockLocked();
357 EXPECT(block_1 != nullptr);
358 // Test that we wrapped.
359 EXPECT(block_0 == Timeline::recorder()->GetNewBlockLocked());
360
361 // Emit the earlier event into block_1.
362 TimelineTestHelper::FakeThreadEvent(block_1, 2, "Alpha", &stream);
363 OS::Sleep(32);
364 // Emit the later event into block_0.
365 TimelineTestHelper::FakeThreadEvent(block_0, 2, "Beta", &stream);
366
369 }
370
372 TimelineEventFilter filter;
373 Timeline::recorder()->PrintJSON(&js, &filter);
374 // trace-event has a requirement that events for a thread must have
375 // monotonically increasing timestamps.
376 // Verify that "Alpha" comes before "Beta" even though "Beta" is in the first
377 // block.
378 const char* alpha = strstr(js.ToCString(), "Alpha");
379 const char* beta = strstr(js.ToCString(), "Beta");
380 EXPECT(alpha < beta);
381}
382
383TEST_CASE(TimelineRingRecorderRace) {
384 struct ReportEventsArguments {
385 Monitor& synchronization_monitor;
386 TimelineEventRecorder& recorder;
388 };
389
390 // Note that |recorder| will be freed by |TimelineRecorderOverride|'s
391 // destructor.
392 TimelineEventRingRecorder& recorder =
393 *(new TimelineEventRingRecorder(2 * TimelineEventBlock::kBlockSize));
395 Monitor synchronization_monitor;
397 TimelineEventFilter filter;
398 ReportEventsArguments report_events_1_arguments{synchronization_monitor,
399 recorder};
400 ReportEventsArguments report_events_2_arguments{synchronization_monitor,
401 recorder};
402
403 // Try concurrently writing events, serializing them, and clearing the
404 // timeline. It is not possible to assert anything about the outcome, because
405 // of scheduling uncertainty. This test is just used to ensure that TSAN
406 // checks the ring recorder code.
408 "ReportEvents1",
409 [](uword arguments_ptr) {
410 ReportEventsArguments& arguments =
411 *reinterpret_cast<ReportEventsArguments*>(arguments_ptr);
412 for (intptr_t i = 0; i < 2 * TimelineEventBlock::kBlockSize; ++i) {
413 TimelineTestHelper::FakeDuration(&arguments.recorder, "testEvent",
414 /*start=*/0, /*end=*/1);
415 }
416 MonitorLocker ml(&arguments.synchronization_monitor);
417 arguments.join_id =
419 ml.Notify();
420 },
421 reinterpret_cast<uword>(&report_events_1_arguments));
423 "ReportEvents2",
424 [](uword arguments_ptr) {
425 ReportEventsArguments& arguments =
426 *reinterpret_cast<ReportEventsArguments*>(arguments_ptr);
427 for (intptr_t i = 0; i < 2 * TimelineEventBlock::kBlockSize; ++i) {
428 TimelineTestHelper::FakeDuration(&arguments.recorder, "testEvent",
429 /*start=*/0, /*end=*/1);
430 }
431 MonitorLocker ml(&arguments.synchronization_monitor);
432 arguments.join_id =
434 ml.Notify();
435 },
436 reinterpret_cast<uword>(&report_events_2_arguments));
437 Timeline::Clear();
438 recorder.PrintJSON(&js, &filter);
439
440 MonitorLocker ml(&synchronization_monitor);
441 while (report_events_1_arguments.join_id == OSThread::kInvalidThreadJoinId ||
442 report_events_2_arguments.join_id == OSThread::kInvalidThreadJoinId) {
443 ml.Wait();
444 }
445 OSThread::Join(report_events_1_arguments.join_id);
446 OSThread::Join(report_events_2_arguments.join_id);
447}
448
449// |OSThread::Start()| takes in a function pointer, and only lambdas that don't
450// capture can be converted to function pointers. So, we use these macros to
451// avoid needing to capture.
452#define FAKE_PROCESS_ID 1
453#define FAKE_TRACE_ID 1
454
455TEST_CASE(TimelineTrackMetadataRace) {
456 struct ReportMetadataArguments {
457 Monitor& synchronization_monitor;
458 TimelineEventRecorder& recorder;
460 };
461
462 Monitor synchronization_monitor;
463 TimelineEventRecorder& recorder = *Timeline::recorder();
464
465 // Try concurrently reading from / writing to the metadata map. It is not
466 // possible to assert anything about the outcome, because of scheduling
467 // uncertainty. This test is just used to ensure that TSAN checks the metadata
468 // map code.
470 TimelineEventFilter filter;
471 ReportMetadataArguments report_metadata_1_arguments{synchronization_monitor,
472 recorder};
473 ReportMetadataArguments report_metadata_2_arguments{synchronization_monitor,
474 recorder};
476 "ReportMetadata1",
477 [](uword arguments_ptr) {
478 ReportMetadataArguments& arguments =
479 *reinterpret_cast<ReportMetadataArguments*>(arguments_ptr);
480 arguments.recorder.AddTrackMetadataBasedOnThread(
481 FAKE_PROCESS_ID, FAKE_TRACE_ID, "Thread 1");
482 MonitorLocker ml(&arguments.synchronization_monitor);
483 arguments.join_id =
485 ml.Notify();
486 },
487 reinterpret_cast<uword>(&report_metadata_1_arguments));
489 "ReportMetadata2",
490 [](uword arguments_ptr) {
491 ReportMetadataArguments& arguments =
492 *reinterpret_cast<ReportMetadataArguments*>(arguments_ptr);
493 arguments.recorder.AddTrackMetadataBasedOnThread(
494 FAKE_PROCESS_ID, FAKE_TRACE_ID, "Incorrect Name");
495 MonitorLocker ml(&arguments.synchronization_monitor);
496 arguments.join_id =
498 ml.Notify();
499 },
500 reinterpret_cast<uword>(&report_metadata_2_arguments));
501 recorder.PrintJSON(&js, &filter);
502 MonitorLocker ml(&synchronization_monitor);
503 while (
504 report_metadata_1_arguments.join_id == OSThread::kInvalidThreadJoinId ||
505 report_metadata_2_arguments.join_id == OSThread::kInvalidThreadJoinId) {
506 ml.Wait();
507 }
508 OSThread::Join(report_metadata_1_arguments.join_id);
509 OSThread::Join(report_metadata_2_arguments.join_id);
510}
511
512#undef FAKE_PROCESS_ID
513#undef FAKE_TRACE_ID
514
515#endif // !PRODUCT
516
517#if defined(SUPPORT_TIMELINE)
518
519static Dart_Port expected_isolate;
520static Dart_IsolateGroupId expected_isolate_group;
521static bool saw_begin;
522static bool saw_end;
523static void* expected_isolate_data;
524static void* expected_isolate_group_data;
525
526static void TestTimelineRecorderCallback(Dart_TimelineRecorderEvent* event) {
528
529 if ((event->type == Dart_Timeline_Event_Begin) &&
530 (strcmp(event->label, "TestEvent") == 0)) {
531 saw_begin = true;
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);
541 }
542
543 if ((event->type == Dart_Timeline_Event_End) &&
544 (strcmp(event->label, "TestEvent") == 0)) {
545 saw_end = true;
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);
555 }
556}
557
558UNIT_TEST_CASE(DartAPI_SetTimelineRecorderCallback) {
559 int argc = TesterState::argc + 2;
560 const char** argv = new const char*[argc];
561 for (intptr_t i = 0; i < argc - 2; i++) {
563 }
564 argv[argc - 2] = "--timeline_recorder=callback";
565 argv[argc - 1] = "--timeline_streams=Dart";
566
567 Dart_SetTimelineRecorderCallback(TestTimelineRecorderCallback);
568
569 EXPECT(Dart_SetVMFlags(argc, argv) == nullptr);
571 memset(&params, 0, sizeof(Dart_InitializeParams));
573 params.vm_snapshot_data = TesterState::vm_snapshot_data;
575 params.shutdown_isolate = TesterState::shutdown_callback;
577 params.start_kernel_isolate = true;
578
579 int64_t isolate_data = 0;
580
581 EXPECT(Dart_Initialize(&params) == nullptr);
582 {
583 // Note: run_vm_tests will create and attach an instance of
584 // bin::IsolateGroupData to the newly created isolate group.
585 TestIsolateScope scope(/*isolate_group_data=*/nullptr, &isolate_data);
586 const char* kScriptChars =
587 "import 'dart:developer';\n"
588 "main() {\n"
589 " Timeline.startSync('TestEvent', arguments: {'key':'value'});\n"
590 " Timeline.finishSync();\n"
591 "}\n";
592 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, nullptr);
593 EXPECT_VALID(lib);
594
595 expected_isolate = Dart_GetMainPortId();
596 EXPECT_NE(ILLEGAL_PORT, expected_isolate);
597 expected_isolate_group = Dart_CurrentIsolateGroupId();
598 EXPECT_NE(ILLEGAL_PORT, expected_isolate_group);
599 expected_isolate_data = &isolate_data;
600 EXPECT_EQ(expected_isolate_data, Dart_CurrentIsolateData());
601 expected_isolate_group_data = Dart_CurrentIsolateGroupData();
602 saw_begin = false;
603 saw_end = false;
604
605 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, nullptr);
607
608 EXPECT(saw_begin);
609 EXPECT(saw_end);
610 }
611 EXPECT(Dart_Cleanup() == nullptr);
612
614
615 delete[] argv;
616}
617
618#endif // defined(SUPPORT_TIMELINE)
619
620} // namespace dart
#define EXPECT(type, expectedAlignment, expectedSize)
GLenum type
intptr_t CountFor(TimelineEvent::EventType type)
void OnEvent(TimelineEvent *event)
Monitor::WaitResult Wait(int64_t millis=Monitor::kNoTimeout)
Definition: lockers.h:172
static int Start(const char *name, ThreadStartFunction function, uword parameter)
static ThreadId ThreadIdFromIntPtr(intptr_t id)
static void Join(ThreadJoinId id)
static OSThread * Current()
Definition: os_thread.h:179
static ThreadJoinId GetCurrentThreadJoinId(OSThread *thread)
Mutex * timeline_block_lock() const
Definition: os_thread.h:112
static const ThreadJoinId kInvalidThreadJoinId
Definition: os_thread.h:249
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)
Definition: unit_test.cc:436
static Dart_IsolateShutdownCallback shutdown_callback
Definition: unit_test.h:257
static Dart_IsolateGroupCreateCallback create_callback
Definition: unit_test.h:256
static const char ** argv
Definition: unit_test.h:259
static Dart_IsolateGroupCleanupCallback group_cleanup_callback
Definition: unit_test.h:258
static int argc
Definition: unit_test.h:260
static const uint8_t * vm_snapshot_data
Definition: unit_test.h:255
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
Definition: dart_api.h:840
#define ILLEGAL_PORT
Definition: dart_api.h:1535
int64_t Dart_Port
Definition: dart_api.h:1525
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
int64_t Dart_IsolateGroupId
Definition: dart_api.h:1209
#define DART_TIMELINE_RECORDER_CURRENT_VERSION
@ Dart_Timeline_Event_Begin
@ Dart_Timeline_Event_End
const EmbeddedViewParams * params
#define ASSERT(E)
glong glong end
FlKeyEvent * event
GAsyncResult * result
char ** argv
Definition: library.h:9
std::variant< Lower, Cross, Upper > EventType
Definition: EventQueue.h:47
Definition: dart_vm.cc:33
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)
pthread_t ThreadJoinId
static constexpr intptr_t kBlockSize
Definition: page.h:33
DART_EXPORT char * Dart_Initialize(Dart_InitializeParams *params)
uintptr_t uword
Definition: globals.h:501
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()
@ kNone
Definition: layer.h:53
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
Definition: switches.h:126
#define T
Definition: precompiler.cc:65
#define FAKE_TRACE_ID
#define FAKE_PROCESS_ID
#define EXPECT_VALID(handle)
Definition: unit_test.h:643