Flutter Engine
The Flutter Engine
dart_vm.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/runtime/dart_vm.h"
6
7#include <sys/stat.h>
8
9#include <sstream>
10#include <vector>
11
12#include "flutter/common/settings.h"
13#include "flutter/fml/compiler_specific.h"
14#include "flutter/fml/cpu_affinity.h"
15#include "flutter/fml/logging.h"
16#include "flutter/fml/mapping.h"
17#include "flutter/fml/size.h"
18#include "flutter/fml/time/time_delta.h"
19#include "flutter/fml/trace_event.h"
20#include "flutter/lib/ui/dart_ui.h"
21#include "flutter/runtime/dart_isolate.h"
22#include "flutter/runtime/dart_vm_initializer.h"
23#include "flutter/runtime/ptrace_check.h"
24#include "third_party/dart/runtime/include/bin/dart_io_api.h"
32
33namespace dart {
34namespace observatory {
35
36#if !OS_FUCHSIA && !FLUTTER_RELEASE
37
38// These two symbols are defined in |observatory_archive.cc| which is generated
39// by the |//third_party/dart/runtime/observatory:archive_observatory| rule.
40// Both of these symbols will be part of the data segment and therefore are read
41// only.
42extern unsigned int observatory_assets_archive_len;
43extern const uint8_t* observatory_assets_archive;
44
45#endif // !OS_FUCHSIA && !FLUTTER_RELEASE
46
47} // namespace observatory
48} // namespace dart
49
50namespace flutter {
51
52// Arguments passed to the Dart VM in all configurations.
53static const char* kDartAllConfigsArgs[] = {
54 // clang-format off
55 "--enable_mirrors=false",
56 "--background_compilation",
57 // 'mark_when_idle' appears to cause a regression, turning off for now.
58 // "--mark_when_idle",
59 // clang-format on
60};
61
62static const char* kDartPrecompilationArgs[] = {"--precompilation"};
63
64static const char* kSerialGCArgs[] = {
65 // clang-format off
66 "--concurrent_mark=false",
67 "--concurrent_sweep=false",
68 "--compactor_tasks=1",
69 "--scavenger_tasks=0",
70 "--marker_tasks=0",
71 // clang-format on
72};
73
75static const char* kDartWriteProtectCodeArgs[] = {
76 "--no_write_protect_code",
77};
78
80static const char* kDartDisableIntegerDivisionArgs[] = {
81 "--no_use_integer_division",
82};
83
84static const char* kDartAssertArgs[] = {
85 // clang-format off
86 "--enable_asserts",
87 // clang-format on
88};
89
90static const char* kDartStartPausedArgs[]{
91 "--pause_isolates_on_start",
92};
93
94static const char* kDartEndlessTraceBufferArgs[]{
95 "--timeline_recorder=endless",
96};
97
98static const char* kDartSystraceTraceBufferArgs[] = {
99 "--timeline_recorder=systrace",
100};
101
102static std::string DartFileRecorderArgs(const std::string& path) {
103 std::ostringstream oss;
104 oss << "--timeline_recorder=perfettofile:" << path;
105 return oss.str();
106}
107
109static const char* kDartDefaultTraceStreamsArgs[]{
110 "--timeline_streams=Dart,Embedder,GC",
111};
112
113static const char* kDartStartupTraceStreamsArgs[]{
114 "--timeline_streams=Compiler,Dart,Debugger,Embedder,GC,Isolate,VM,API",
115};
116
117static const char* kDartSystraceTraceStreamsArgs[] = {
118 "--timeline_streams=Compiler,Dart,Debugger,Embedder,GC,Isolate,VM,API",
119};
120
121static std::string DartOldGenHeapSizeArgs(uint64_t heap_size) {
122 std::ostringstream oss;
123 oss << "--old_gen_heap_size=" << heap_size;
124 return oss.str();
125}
126
127constexpr char kFileUriPrefix[] = "file://";
128constexpr size_t kFileUriPrefixLength = sizeof(kFileUriPrefix) - 1;
129
130bool DartFileModifiedCallback(const char* source_url, int64_t since_ms) {
131 if (strncmp(source_url, kFileUriPrefix, kFileUriPrefixLength) != 0u) {
132 // Assume modified.
133 return true;
134 }
135
136 const char* path = source_url + kFileUriPrefixLength;
137 struct stat info;
138 if (stat(path, &info) < 0) {
139 return true;
140 }
141
142 // If st_mtime is zero, it's more likely that the file system doesn't support
143 // mtime than that the file was actually modified in the 1970s.
144 if (!info.st_mtime) {
145 return true;
146 }
147
148 // It's very unclear what time bases we're with here. The Dart API doesn't
149 // document the time base for since_ms. Reading the code, the value varies by
150 // platform, with a typical source being something like gettimeofday.
151 //
152 // We add one to st_mtime because st_mtime has less precision than since_ms
153 // and we want to treat the file as modified if the since time is between
154 // ticks of the mtime.
155 fml::TimeDelta mtime = fml::TimeDelta::FromSeconds(info.st_mtime + 1);
157
158 return mtime > since;
159}
160
162
164#if FLUTTER_RELEASE
165 return nullptr;
166#elif OS_FUCHSIA
167 fml::UniqueFD fd = fml::OpenFile("pkg/data/observatory.tar", false,
170 if (mapping.GetSize() == 0 || mapping.GetMapping() == nullptr) {
171 FML_LOG(ERROR) << "Fail to load Observatory archive";
172 return nullptr;
173 }
174 return tonic::DartConverter<tonic::Uint8List>::ToDart(mapping.GetMapping(),
175 mapping.GetSize());
176#else
180#endif
181}
182
183static const char kStdoutStreamId[] = "Stdout";
184static const char kStderrStreamId[] = "Stderr";
185
186static bool ServiceStreamListenCallback(const char* stream_id) {
187 if (strcmp(stream_id, kStdoutStreamId) == 0) {
189 return true;
190 } else if (strcmp(stream_id, kStderrStreamId) == 0) {
192 return true;
193 }
194 return false;
195}
196
197static void ServiceStreamCancelCallback(const char* stream_id) {
198 if (strcmp(stream_id, kStdoutStreamId) == 0) {
200 } else if (strcmp(stream_id, kStderrStreamId) == 0) {
202 }
203}
204
207}
208
209static std::vector<const char*> ProfilingFlags(bool enable_profiling) {
210// Disable Dart's built in profiler when building a debug build. This
211// works around a race condition that would sometimes stop a crash's
212// stack trace from being printed on Android.
213#ifndef NDEBUG
214 enable_profiling = false;
215#endif
216
217 // We want to disable profiling by default because it overwhelms LLDB. But
218 // the VM enables the same by default. In either case, we have some profiling
219 // flags.
220 if (enable_profiling) {
221 return {
222 // This is the default. But just be explicit.
223 "--profiler",
224 // This instructs the profiler to walk C++ frames, and to include
225 // them in the profile.
226 "--profile-vm",
227#if FML_OS_IOS && FML_ARCH_CPU_ARM_FAMILY && FML_ARCH_CPU_ARMEL
228 // Set the profiler interrupt period to 500Hz instead of the
229 // default 1000Hz on 32-bit iOS devices to reduce average and worst
230 // case frame build times.
231 //
232 // Note: profile_period is time in microseconds between sampling
233 // events, not frequency. Frequency is calculated 1/period (or
234 // 1,000,000 / 2,000 -> 500Hz in this case).
235 "--profile_period=2000",
236#else
237 "--profile_period=1000",
238#endif // FML_OS_IOS && FML_ARCH_CPU_ARM_FAMILY && FML_ARCH_CPU_ARMEL
239 };
240 } else {
241 return {"--no-profiler"};
242 }
243}
244
245void PushBackAll(std::vector<const char*>* args,
246 const char** argv,
247 size_t argc) {
248 for (size_t i = 0; i < argc; ++i) {
249 args->push_back(argv[i]);
250 }
251}
252
256 info->name = "Flutter";
257}
258
259std::shared_ptr<DartVM> DartVM::Create(
260 const Settings& settings,
262 fml::RefPtr<const DartSnapshot> isolate_snapshot,
263 std::shared_ptr<IsolateNameServer> isolate_name_server) {
264 auto vm_data = DartVMData::Create(settings, //
265 std::move(vm_snapshot), //
266 std::move(isolate_snapshot) //
267 );
268
269 if (!vm_data) {
270 FML_LOG(ERROR) << "Could not set up VM data to bootstrap the VM from.";
271 return {};
272 }
273
274 // Note: std::make_shared unviable due to hidden constructor.
275 return std::shared_ptr<DartVM>(
276 new DartVM(vm_data, std::move(isolate_name_server)));
277}
278
279static std::atomic_size_t gVMLaunchCount;
280
282 return gVMLaunchCount;
283}
284
285// Minimum and maximum number of worker threads.
286static constexpr size_t kMinCount = 2;
287static constexpr size_t kMaxCount = 4;
288
289DartVM::DartVM(const std::shared_ptr<const DartVMData>& vm_data,
290 std::shared_ptr<IsolateNameServer> isolate_name_server)
291 : settings_(vm_data->GetSettings()),
292 concurrent_message_loop_(fml::ConcurrentMessageLoop::Create(
293 std::clamp(fml::EfficiencyCoreCount().value_or(
294 std::thread::hardware_concurrency()) /
295 2,
296 kMinCount,
297 kMaxCount))),
298 skia_concurrent_executor_(
299 [runner = concurrent_message_loop_->GetTaskRunner()](
300 const fml::closure& work) { runner->PostTask(work); }),
301 vm_data_(vm_data),
302 isolate_name_server_(std::move(isolate_name_server)),
303 service_protocol_(std::make_shared<ServiceProtocol>()) {
304 TRACE_EVENT0("flutter", "DartVMInitializer");
305
307
308 // Setting the executor is not thread safe but Dart VM initialization is. So
309 // this call is thread-safe.
310 SkExecutor::SetDefault(&skia_concurrent_executor_);
311
312 FML_DCHECK(vm_data_);
313 FML_DCHECK(isolate_name_server_);
314 FML_DCHECK(service_protocol_);
315
316 {
317 TRACE_EVENT0("flutter", "dart::bin::BootstrapDartIo");
319
320 if (!settings_.temp_directory_path.empty()) {
321 dart::bin::SetSystemTempDirectory(settings_.temp_directory_path.c_str());
322 }
323 }
324
325 std::vector<const char*> args;
326
327 // Instruct the VM to ignore unrecognized flags.
328 // There is a lot of diversity in a lot of combinations when it
329 // comes to the arguments the VM supports. And, if the VM comes across a flag
330 // it does not recognize, it exits immediately.
331 args.push_back("--ignore-unrecognized-flags");
332
333 for (auto* const profiler_flag :
334 ProfilingFlags(settings_.enable_dart_profiling)) {
335 args.push_back(profiler_flag);
336 }
337
339
340 if (IsRunningPrecompiledCode()) {
343 }
344
345 // Enable Dart assertions if we are not running precompiled code. We run non-
346 // precompiled code only in the debug product mode.
347 bool enable_asserts = !settings_.disable_dart_asserts;
348
349#if !OS_FUCHSIA
350 if (IsRunningPrecompiledCode()) {
351 enable_asserts = false;
352 }
353#endif // !OS_FUCHSIA
354
355#if (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
356#if !FML_OS_IOS && !FML_OS_MACOSX
357 // Debug mode uses the JIT, disable code page write protection to avoid
358 // memory page protection changes before and after every compilation.
361#else
362 const bool tracing_result = EnableTracingIfNecessary(settings_);
363 // This check should only trip if the embedding made no attempts to enable
364 // tracing. At this point, it is too late display user visible messages. Just
365 // log and die.
366 FML_CHECK(tracing_result)
367 << "Tracing not enabled before attempting to run JIT mode VM.";
368#if TARGET_CPU_ARM
369 // Tell Dart in JIT mode to not use integer division on armv7
370 // Ideally, this would be detected at runtime by Dart.
371 // TODO(dnfield): Remove this code
372 // https://github.com/dart-lang/sdk/issues/24743
375#endif // TARGET_CPU_ARM
376#endif // !FML_OS_IOS && !FML_OS_MACOSX
377#endif // (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
378
379 if (enable_asserts) {
381 }
382
383 // On low power devices with lesser number of cores, using concurrent
384 // marking or sweeping causes contention for the UI thread leading to
385 // Jank, this option can be used to turn off all concurrent GC activities.
386 if (settings_.enable_serial_gc) {
388 }
389
390 if (settings_.start_paused) {
392 }
393
394 if (settings_.endless_trace_buffer || settings_.trace_startup) {
395 // If we are tracing startup, make sure the trace buffer is endless so we
396 // don't lose early traces.
399 }
400
401 if (settings_.trace_systrace) {
406 }
407
408 std::string file_recorder_args;
409 if (!settings_.trace_to_file.empty()) {
410 file_recorder_args = DartFileRecorderArgs(settings_.trace_to_file);
411 args.push_back(file_recorder_args.c_str());
414 }
415
416 if (settings_.trace_startup) {
419 }
420
421#if defined(OS_FUCHSIA)
426#else
427 if (!settings_.trace_systrace && !settings_.trace_startup) {
430 }
431#endif // defined(OS_FUCHSIA)
432
433 std::string old_gen_heap_size_args;
434 if (settings_.old_gen_heap_size >= 0) {
435 old_gen_heap_size_args =
436 DartOldGenHeapSizeArgs(settings_.old_gen_heap_size);
437 args.push_back(old_gen_heap_size_args.c_str());
438 }
439
440 for (size_t i = 0; i < settings_.dart_flags.size(); i++) {
441 args.push_back(settings_.dart_flags[i].c_str());
442 }
443
444 char* flags_error = Dart_SetVMFlags(args.size(), args.data());
445 if (flags_error) {
446 FML_LOG(FATAL) << "Error while setting Dart VM flags: " << flags_error;
447 ::free(flags_error);
448 }
449
450 dart::bin::SetExecutableName(settings_.executable_name.c_str());
451
452 {
453 TRACE_EVENT0("flutter", "Dart_Initialize");
456 params.vm_snapshot_data = vm_data_->GetVMSnapshot().GetDataMapping();
457 params.vm_snapshot_instructions =
458 vm_data_->GetVMSnapshot().GetInstructionsMapping();
459 params.create_group = reinterpret_cast<decltype(params.create_group)>(
460 DartIsolate::DartIsolateGroupCreateCallback);
461 params.initialize_isolate =
462 reinterpret_cast<decltype(params.initialize_isolate)>(
463 DartIsolate::DartIsolateInitializeCallback);
464 params.shutdown_isolate =
465 reinterpret_cast<decltype(params.shutdown_isolate)>(
466 DartIsolate::DartIsolateShutdownCallback);
467 params.cleanup_isolate = reinterpret_cast<decltype(params.cleanup_isolate)>(
468 DartIsolate::DartIsolateCleanupCallback);
469 params.cleanup_group = reinterpret_cast<decltype(params.cleanup_group)>(
470 DartIsolate::DartIsolateGroupCleanupCallback);
471 params.thread_exit = ThreadExitCallback;
472 params.file_open = dart::bin::OpenFile;
473 params.file_read = dart::bin::ReadFile;
474 params.file_write = dart::bin::WriteFile;
475 params.file_close = dart::bin::CloseFile;
476 params.entropy_source = dart::bin::GetEntropy;
477 params.get_service_assets = GetVMServiceAssetsArchiveCallback;
479 settings_.enable_timeline_event_handler,
480 settings_.trace_systrace);
481 // Send the earliest available timestamp in the application lifecycle to
482 // timeline. The difference between this timestamp and the time we render
483 // the very first frame gives us a good idea about Flutter's startup time.
484 // Use an instant event because the call to Dart_TimelineGetMicros
485 // may behave differently before and after the Dart VM is initialized.
486 // As this call is immediately after initialization of the Dart VM,
487 // we are interested in only one timestamp.
488 int64_t micros = Dart_TimelineGetMicros();
489 Dart_RecordTimelineEvent("FlutterEngineMainEnter", // label
490 micros, // timestamp0
491 micros, // timestamp1_or_async_id
492 0, // flow_id_count
493 nullptr, // flow_ids
494 Dart_Timeline_Event_Instant, // event type
495 0, // argument_count
496 nullptr, // argument_names
497 nullptr // argument_values
498 );
499 }
500
502
503 // Allow streaming of stdout and stderr by the Dart vm.
506
508
509 if (settings_.dart_library_sources_kernel != nullptr) {
510 std::unique_ptr<fml::Mapping> dart_library_sources =
511 settings_.dart_library_sources_kernel();
512 // Set sources for dart:* libraries for debugging.
513 Dart_SetDartLibrarySourcesKernel(dart_library_sources->GetMapping(),
514 dart_library_sources->GetSize());
515 }
516
517 // Update thread names now that the Dart VM is initialized.
518 concurrent_message_loop_->PostTaskToAllWorkers(
519 [] { Dart_SetThreadName("FlutterConcurrentMessageLoopWorker"); });
520}
521
522DartVM::~DartVM() {
523 // Setting the executor is not thread safe but Dart VM shutdown is. So
524 // this call is thread-safe.
525 SkExecutor::SetDefault(nullptr);
526
527 if (Dart_CurrentIsolate() != nullptr) {
529 }
530
532
534}
535
536std::shared_ptr<const DartVMData> DartVM::GetVMData() const {
537 return vm_data_;
538}
539
540const Settings& DartVM::GetSettings() const {
541 return settings_;
542}
543
544std::shared_ptr<ServiceProtocol> DartVM::GetServiceProtocol() const {
545 return service_protocol_;
546}
547
548std::shared_ptr<IsolateNameServer> DartVM::GetIsolateNameServer() const {
549 return isolate_name_server_;
550}
551
552std::shared_ptr<fml::ConcurrentTaskRunner>
553DartVM::GetConcurrentWorkerTaskRunner() const {
554 return concurrent_message_loop_->GetTaskRunner();
555}
556
557std::shared_ptr<fml::ConcurrentMessageLoop> DartVM::GetConcurrentMessageLoop() {
558 return concurrent_message_loop_;
559}
560
561} // namespace flutter
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
static sk_sp< Effect > Create()
Definition: RefCntTest.cpp:117
static unsigned clamp(SkFixed fx, int max)
static void Initialize(Dart_InitializeParams *params, bool enable_timeline_event_handler, bool trace_systrace)
static void SetDefault(SkExecutor *)
Definition: SkExecutor.cpp:57
static std::shared_ptr< const DartVMData > Create(const Settings &settings, fml::RefPtr< const DartSnapshot > vm_snapshot, fml::RefPtr< const DartSnapshot > isolate_snapshot)
Creates a new instance of DartVMData. Both the VM and isolate snapshot members are optional and may b...
Definition: dart_vm_data.cc:11
static size_t GetVMLaunchCount()
The number of times the VM has been launched in the process. This call is inherently racy because the...
Definition: dart_vm.cc:281
static bool IsRunningPrecompiledCode()
Checks if VM instances in the process can run precompiled code. This call can be made at any time and...
Definition: dart_vm.cc:205
static constexpr TimeDelta FromSeconds(int64_t seconds)
Definition: time_delta.h:49
static constexpr TimeDelta FromMilliseconds(int64_t millis)
Definition: time_delta.h:46
#define DART_INITIALIZE_PARAMS_CURRENT_VERSION
Definition: dart_api.h:840
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
DART_EXPORT bool Dart_IsPrecompiledRuntime(void)
DART_EXPORT Dart_Isolate Dart_CurrentIsolate(void)
DART_EXPORT void Dart_SetDartLibrarySourcesKernel(const uint8_t *platform_kernel, const intptr_t platform_kernel_size)
DART_EXPORT DART_WARN_UNUSED_RESULT char * Dart_SetVMFlags(int argc, const char **argv)
DART_EXPORT void Dart_ExitIsolate(void)
DART_EXPORT void Dart_SetEmbedderInformationCallback(Dart_EmbedderInformationCallback callback)
DART_EXPORT int64_t Dart_TimelineGetMicros()
DART_EXPORT char * Dart_SetFileModifiedCallback(Dart_FileModifiedCallback file_modified_callback)
DART_EXPORT void Dart_SetThreadName(const char *name)
@ Dart_Timeline_Event_Instant
#define DART_EMBEDDER_INFORMATION_CURRENT_VERSION
DART_EXPORT char * Dart_SetServiceStreamCallbacks(Dart_ServiceStreamListenCallback listen_callback, Dart_ServiceStreamCancelCallback cancel_callback)
DART_EXPORT void Dart_RecordTimelineEvent(const char *label, int64_t timestamp0, int64_t timestamp1_or_id, intptr_t flow_id_count, const int64_t *flow_ids, Dart_Timeline_Event_Type type, intptr_t argument_count, const char **argument_names, const char **argument_values)
const EmbeddedViewParams * params
Settings settings_
#define FATAL(error)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
#define FML_ALLOW_UNUSED_TYPE
#define FML_LOG(severity)
Definition: logging.h:82
#define FML_CHECK(condition)
Definition: logging.h:85
#define FML_DCHECK(condition)
Definition: logging.h:103
char ** argv
Definition: library.h:9
void SetExecutableName(const char *executable_name)
void WriteFile(const void *buffer, intptr_t num_bytes, void *stream)
void ReadFile(uint8_t **data, intptr_t *file_len, void *stream)
void GetIOEmbedderInformation(Dart_EmbedderInformation *info)
void SetCaptureStdout(bool value)
Definition: file_support.cc:25
void CleanupDartIo()
void CloseFile(void *stream)
void BootstrapDartIo()
void SetCaptureStderr(bool value)
Definition: file_support.cc:29
bool GetEntropy(uint8_t *buffer, intptr_t length)
void * OpenFile(const char *name, bool write)
void SetSystemTempDirectory(const char *system_temp)
const uint8_t * observatory_assets_archive
unsigned int observatory_assets_archive_len
Definition: dart_vm.cc:33
void ThreadExitCallback()
Definition: dart_vm.cc:161
static const char kStderrStreamId[]
Definition: dart_vm.cc:184
static constexpr size_t kMaxCount
Definition: dart_vm.cc:287
Dart_Handle GetVMServiceAssetsArchiveCallback()
Definition: dart_vm.cc:163
static const char * kDartPrecompilationArgs[]
Definition: dart_vm.cc:62
static const char * kSerialGCArgs[]
Definition: dart_vm.cc:64
static std::string DartFileRecorderArgs(const std::string &path)
Definition: dart_vm.cc:102
constexpr size_t kFileUriPrefixLength
Definition: dart_vm.cc:128
void PushBackAll(std::vector< const char * > *args, const char **argv, size_t argc)
Definition: dart_vm.cc:245
static std::string DartOldGenHeapSizeArgs(uint64_t heap_size)
Definition: dart_vm.cc:121
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
Definition: switches.h:57
static const char * kDartAllConfigsArgs[]
Definition: dart_vm.cc:53
static const char * kDartStartPausedArgs[]
Definition: dart_vm.cc:90
static void EmbedderInformationCallback(Dart_EmbedderInformation *info)
Definition: dart_vm.cc:253
static const char * kDartStartupTraceStreamsArgs[]
Definition: dart_vm.cc:113
static void ServiceStreamCancelCallback(const char *stream_id)
Definition: dart_vm.cc:197
static FML_ALLOW_UNUSED_TYPE const char * kDartWriteProtectCodeArgs[]
Definition: dart_vm.cc:75
static constexpr size_t kMinCount
Definition: dart_vm.cc:286
constexpr char kFileUriPrefix[]
Definition: dart_vm.cc:127
static const char * kDartEndlessTraceBufferArgs[]
Definition: dart_vm.cc:94
static const char * kDartAssertArgs[]
Definition: dart_vm.cc:84
bool EnableTracingIfNecessary(const Settings &vm_settings)
Enables tracing in the process so that JIT mode VMs may be launched. Explicitly enabling tracing is n...
Definition: ptrace_check.h:45
static const char * kDartSystraceTraceBufferArgs[]
Definition: dart_vm.cc:98
static std::atomic_size_t gVMLaunchCount
Definition: dart_vm.cc:279
static const char kStdoutStreamId[]
Definition: dart_vm.cc:183
static FML_ALLOW_UNUSED_TYPE const char * kDartDefaultTraceStreamsArgs[]
Definition: dart_vm.cc:109
static const char * kDartSystraceTraceStreamsArgs[]
Definition: dart_vm.cc:117
bool DartFileModifiedCallback(const char *source_url, int64_t since_ms)
Definition: dart_vm.cc:130
static bool ServiceStreamListenCallback(const char *stream_id)
Definition: dart_vm.cc:186
static std::vector< const char * > ProfilingFlags(bool enable_profiling)
Definition: dart_vm.cc:209
static FML_ALLOW_UNUSED_TYPE const char * kDartDisableIntegerDivisionArgs[]
Definition: dart_vm.cc:80
Definition: ascii_trie.cc:9
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
std::optional< size_t > EfficiencyCoreCount()
Request count of efficiency cores.
Definition: cpu_affinity.cc:18
std::function< void()> closure
Definition: closure.h:14
fml::UniqueFD OpenFile(const char *path, bool create_if_necessary, FilePermission permission)
This can open a directory on POSIX, but not on Windows.
Definition: file_posix.cc:66
Definition: ref_ptr.h:256
Dart_Handle ToDart(const T &object)
#define ERROR(message)
Definition: elf_loader.cc:260
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:131