Flutter Engine
The Flutter Engine
gen_snapshot.cc
Go to the documentation of this file.
1// Copyright (c) 2013, 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// Generate a snapshot file after loading all the scripts specified on the
6// command line.
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include <cstdarg>
13#include <memory>
14
15#include "bin/builtin.h"
16#include "bin/console.h"
17#include "bin/dartutils.h"
18#include "bin/error_exit.h"
19#include "bin/eventhandler.h"
20#include "bin/exe_utils.h"
21#include "bin/file.h"
22#include "bin/loader.h"
23#include "bin/options.h"
24#include "bin/platform.h"
25#include "bin/snapshot_utils.h"
26#include "bin/thread.h"
27#include "bin/utils.h"
28#include "bin/vmservice_impl.h"
29
30#include "include/dart_api.h"
32
33#include "platform/globals.h"
35#include "platform/hashmap.h"
36#include "platform/syslog.h"
38
39namespace dart {
40namespace bin {
41
42#define CHECK_RESULT(result) \
43 if (Dart_IsError(result)) { \
44 intptr_t exit_code = 0; \
45 Syslog::PrintErr("Error: %s\n", Dart_GetError(result)); \
46 if (Dart_IsCompilationError(result)) { \
47 exit_code = kCompilationErrorExitCode; \
48 } else if (Dart_IsApiError(result)) { \
49 exit_code = kApiErrorExitCode; \
50 } else { \
51 exit_code = kErrorExitCode; \
52 } \
53 Dart_ExitScope(); \
54 Dart_ShutdownIsolate(); \
55 exit(exit_code); \
56 }
57
58// The environment provided through the command line using -D options.
60
61static bool ProcessEnvironmentOption(const char* arg,
62 CommandLineOptions* vm_options) {
63 return OptionProcessor::ProcessEnvironmentOption(arg, vm_options,
65}
66
67// The core snapshot to use when creating isolates. Normally nullptr, but loaded
68// from a file when creating AppJIT snapshots.
69const uint8_t* isolate_snapshot_data = nullptr;
70const uint8_t* isolate_snapshot_instructions = nullptr;
71
72// Global state that indicates whether a snapshot is to be created and
73// if so which file to write the snapshot into. The ordering of this list must
74// match kSnapshotKindNames below.
82};
84
85// The ordering of this list must match the SnapshotKind enum above.
86static const char* const kSnapshotKindNames[] = {
87 // clang-format off
88 "core",
89 "app",
90 "app-jit",
91 "app-aot-assembly",
92 "app-aot-elf",
93 "vm-aot-assembly",
94 nullptr,
95 // clang-format on
96};
97
98#define STRING_OPTIONS_LIST(V) \
99 V(load_vm_snapshot_data, load_vm_snapshot_data_filename) \
100 V(load_vm_snapshot_instructions, load_vm_snapshot_instructions_filename) \
101 V(load_isolate_snapshot_data, load_isolate_snapshot_data_filename) \
102 V(load_isolate_snapshot_instructions, \
103 load_isolate_snapshot_instructions_filename) \
104 V(vm_snapshot_data, vm_snapshot_data_filename) \
105 V(vm_snapshot_instructions, vm_snapshot_instructions_filename) \
106 V(isolate_snapshot_data, isolate_snapshot_data_filename) \
107 V(isolate_snapshot_instructions, isolate_snapshot_instructions_filename) \
108 V(blobs_container_filename, blobs_container_filename) \
109 V(assembly, assembly_filename) \
110 V(elf, elf_filename) \
111 V(loading_unit_manifest, loading_unit_manifest_filename) \
112 V(save_debugging_info, debugging_info_filename) \
113 V(save_obfuscation_map, obfuscation_map_filename)
114
115#define BOOL_OPTIONS_LIST(V) \
116 V(compile_all, compile_all) \
117 V(help, help) \
118 V(obfuscate, obfuscate) \
119 V(strip, strip) \
120 V(verbose, verbose) \
121 V(version, version)
122
123#define STRING_OPTION_DEFINITION(flag, variable) \
124 static const char* variable = nullptr; \
125 DEFINE_STRING_OPTION(flag, variable)
127#undef STRING_OPTION_DEFINITION
128
129#define BOOL_OPTION_DEFINITION(flag, variable) \
130 static bool variable = false; \
131 DEFINE_BOOL_OPTION(flag, variable)
133#undef BOOL_OPTION_DEFINITION
134
137
141}
142
143// clang-format off
144static void PrintUsage() {
146"Usage: gen_snapshot [<vm-flags>] [<options>] <dart-kernel-file> \n"
147" \n"
148"Common options: \n"
149"--help \n"
150" Display this message (add --verbose for information about all VM options).\n"
151"--version \n"
152" Print the SDK version. \n"
153" \n"
154"To create a core snapshot: \n"
155"--snapshot_kind=core \n"
156"--vm_snapshot_data=<output-file> \n"
157"--isolate_snapshot_data=<output-file> \n"
158"<dart-kernel-file> \n"
159" \n"
160"To create an AOT application snapshot as assembly suitable for compilation \n"
161"as a static or dynamic library: \n"
162"--snapshot_kind=app-aot-assembly \n"
163"--assembly=<output-file> \n"
164"[--strip] \n"
165"[--obfuscate] \n"
166"[--save-debugging-info=<debug-filename>] \n"
167"[--save-obfuscation-map=<map-filename>] \n"
168"<dart-kernel-file> \n"
169" \n"
170"To create an AOT application snapshot as an ELF shared library: \n"
171"--snapshot_kind=app-aot-elf \n"
172"--elf=<output-file> \n"
173"[--strip] \n"
174"[--obfuscate] \n"
175"[--save-debugging-info=<debug-filename>] \n"
176"[--save-obfuscation-map=<map-filename>] \n"
177"<dart-kernel-file> \n"
178" \n"
179"AOT snapshots can be obfuscated: that is all identifiers will be renamed \n"
180"during compilation. This mode is enabled with --obfuscate flag. Mapping \n"
181"between original and obfuscated names can be serialized as a JSON array \n"
182"using --save-obfuscation-map=<filename> option. See dartbug.com/30524 \n"
183"for implementation details and limitations of the obfuscation pass. \n"
184" \n"
185"\n");
186 if (verbose) {
188"The following options are only used for VM development and may\n"
189"be changed in any future version:\n");
190 const char* print_flags = "--print_flags";
191 char* error = Dart_SetVMFlags(1, &print_flags);
192 ASSERT(error == nullptr);
193 }
194}
195// clang-format on
196
197// Parse out the command line arguments. Returns -1 if the arguments
198// are incorrect, 0 otherwise.
199static int ParseArguments(int argc,
200 char** argv,
201 CommandLineOptions* vm_options,
203 // Skip the binary name.
204 int i = 1;
205
206 // Parse out the vm options.
207 while ((i < argc) && OptionProcessor::IsValidShortFlag(argv[i])) {
208 if (OptionProcessor::TryProcess(argv[i], vm_options)) {
209 i += 1;
210 continue;
211 }
212 vm_options->AddArgument(argv[i]);
213 i += 1;
214 }
215
216 // Parse out the kernel inputs.
217 while (i < argc) {
218 inputs->AddArgument(argv[i]);
219 i++;
220 }
221
222 if (help) {
223 PrintUsage();
225 } else if (version) {
226 Syslog::PrintErr("Dart SDK version: %s\n", Dart_VersionString());
228 }
229
230 // Verify consistency of arguments.
231 if (inputs->count() < 1) {
232 Syslog::PrintErr("At least one input is required\n");
233 return -1;
234 }
235
236 switch (snapshot_kind) {
237 case kCore: {
238 if ((vm_snapshot_data_filename == nullptr) ||
239 (isolate_snapshot_data_filename == nullptr)) {
241 "Building a core snapshot requires specifying output files for "
242 "--vm_snapshot_data and --isolate_snapshot_data.\n\n");
243 return -1;
244 }
245 break;
246 }
247 case kApp:
248 case kAppJIT: {
249 if ((load_vm_snapshot_data_filename == nullptr) ||
250 (isolate_snapshot_data_filename == nullptr) ||
251 (isolate_snapshot_instructions_filename == nullptr)) {
253 "Building an app JIT snapshot requires specifying input files for "
254 "--load_vm_snapshot_data and --load_vm_snapshot_instructions, an "
255 " output file for --isolate_snapshot_data, and an output "
256 "file for --isolate_snapshot_instructions.\n\n");
257 return -1;
258 }
259 break;
260 }
261 case kAppAOTElf: {
262 if (elf_filename == nullptr) {
264 "Building an AOT snapshot as ELF requires specifying "
265 "an output file for --elf.\n\n");
266 return -1;
267 }
268 break;
269 }
270 case kAppAOTAssembly:
271 case kVMAOTAssembly: {
272 if (assembly_filename == nullptr) {
274 "Building an AOT snapshot as assembly requires specifying "
275 "an output file for --assembly.\n\n");
276 return -1;
277 }
278 break;
279 }
280 }
281
282 if (!obfuscate && obfuscation_map_filename != nullptr) {
284 "--save-obfuscation_map=<...> should only be specified when "
285 "obfuscation is enabled by the --obfuscate flag.\n\n");
286 return -1;
287 }
288
290 if (obfuscate) {
292 "Obfuscation can only be enabled when building an AOT snapshot.\n\n");
293 return -1;
294 }
295
296 if (debugging_info_filename != nullptr) {
298 "--save-debugging-info=<...> can only be enabled when building an "
299 "AOT snapshot.\n\n");
300 return -1;
301 }
302
303 if (strip) {
305 "Stripping can only be enabled when building an AOT snapshot.\n\n");
306 return -1;
307 }
308 }
309
310 return 0;
311}
312
313PRINTF_ATTRIBUTE(1, 2) static void PrintErrAndExit(const char* format, ...) {
314 va_list args;
318
322}
323
324static File* OpenFile(const char* filename) {
325 File* file = File::Open(nullptr, filename, File::kWriteTruncate);
326 if (file == nullptr) {
327 PrintErrAndExit("Error: Unable to write file: %s\n\n", filename);
328 }
329 return file;
330}
331
332static void WriteFile(const char* filename,
333 const uint8_t* buffer,
334 const intptr_t size) {
335 File* file = OpenFile(filename);
337 if (!file->WriteFully(buffer, size)) {
338 PrintErrAndExit("Error: Unable to write file: %s\n\n", filename);
339 }
340}
341
342static void ReadFile(const char* filename, uint8_t** buffer, intptr_t* size) {
343 File* file = File::Open(nullptr, filename, File::kRead);
344 if (file == nullptr) {
345 PrintErrAndExit("Error: Unable to read file: %s\n", filename);
346 }
348 *size = file->Length();
349 *buffer = reinterpret_cast<uint8_t*>(malloc(*size));
350 if (!file->ReadFully(*buffer, *size)) {
351 PrintErrAndExit("Error: Unable to read file: %s\n", filename);
352 }
353}
354
355static void MallocFinalizer(void* isolate_callback_data, void* peer) {
356 free(peer);
357}
358
360 for (intptr_t i = 1; i < inputs.count(); i++) {
361 uint8_t* buffer = nullptr;
362 intptr_t size = 0;
363 ReadFile(inputs.GetArgument(i), &buffer, &size);
366 CHECK_RESULT(td);
369 }
370}
371
372static void MaybeLoadCode() {
373 if (compile_all && (snapshot_kind == kAppJIT)) {
376 }
377}
378
381 ASSERT(vm_snapshot_data_filename != nullptr);
382 ASSERT(isolate_snapshot_data_filename != nullptr);
383
385 uint8_t* vm_snapshot_data_buffer = nullptr;
386 intptr_t vm_snapshot_data_size = 0;
387 uint8_t* isolate_snapshot_data_buffer = nullptr;
388 intptr_t isolate_snapshot_data_size = 0;
389
390 // First create a snapshot.
391 result = Dart_CreateSnapshot(&vm_snapshot_data_buffer, &vm_snapshot_data_size,
392 &isolate_snapshot_data_buffer,
393 &isolate_snapshot_data_size,
394 /*is_core=*/true);
396
397 // Now write the vm isolate and isolate snapshots out to the
398 // specified file and exit.
399 WriteFile(vm_snapshot_data_filename, vm_snapshot_data_buffer,
400 vm_snapshot_data_size);
401 if (vm_snapshot_instructions_filename != nullptr) {
402 // Create empty file for the convenience of build systems.
403 WriteFile(vm_snapshot_instructions_filename, nullptr, 0);
404 }
405 WriteFile(isolate_snapshot_data_filename, isolate_snapshot_data_buffer,
406 isolate_snapshot_data_size);
407 if (isolate_snapshot_instructions_filename != nullptr) {
408 // Create empty file for the convenience of build systems.
409 WriteFile(isolate_snapshot_instructions_filename, nullptr, 0);
410 }
411}
412
413static std::unique_ptr<MappedMemory> MapFile(const char* filename,
415 const uint8_t** buffer) {
416 File* file = File::Open(nullptr, filename, File::kRead);
417 if (file == nullptr) {
418 Syslog::PrintErr("Failed to open: %s\n", filename);
420 }
422 intptr_t length = file->Length();
423 if (length == 0) {
424 // Can't map an empty file.
425 *buffer = nullptr;
426 return nullptr;
427 }
428 MappedMemory* mapping = file->Map(type, 0, length);
429 if (mapping == nullptr) {
430 Syslog::PrintErr("Failed to read: %s\n", filename);
432 }
433 *buffer = reinterpret_cast<const uint8_t*>(mapping->address());
434 return std::unique_ptr<MappedMemory>(mapping);
435}
436
439 ASSERT(isolate_snapshot_data_filename != nullptr);
440
442 uint8_t* isolate_snapshot_data_buffer = nullptr;
443 intptr_t isolate_snapshot_data_size = 0;
444
445 result = Dart_CreateSnapshot(nullptr, nullptr, &isolate_snapshot_data_buffer,
446 &isolate_snapshot_data_size, /*is_core=*/false);
448
449 WriteFile(isolate_snapshot_data_filename, isolate_snapshot_data_buffer,
450 isolate_snapshot_data_size);
451 if (isolate_snapshot_instructions_filename != nullptr) {
452 // Create empty file for the convenience of build systems.
453 WriteFile(isolate_snapshot_instructions_filename, nullptr, 0);
454 }
455}
456
459 ASSERT(isolate_snapshot_data_filename != nullptr);
460 ASSERT(isolate_snapshot_instructions_filename != nullptr);
461
463 uint8_t* isolate_snapshot_data_buffer = nullptr;
464 intptr_t isolate_snapshot_data_size = 0;
465 uint8_t* isolate_snapshot_instructions_buffer = nullptr;
466 intptr_t isolate_snapshot_instructions_size = 0;
467
469 &isolate_snapshot_data_buffer, &isolate_snapshot_data_size,
470 &isolate_snapshot_instructions_buffer,
471 &isolate_snapshot_instructions_size);
473
474 WriteFile(isolate_snapshot_data_filename, isolate_snapshot_data_buffer,
475 isolate_snapshot_data_size);
476 WriteFile(isolate_snapshot_instructions_filename,
477 isolate_snapshot_instructions_buffer,
478 isolate_snapshot_instructions_size);
479}
480
481static void StreamingWriteCallback(void* callback_data,
482 const uint8_t* buffer,
483 intptr_t size) {
484 File* file = reinterpret_cast<File*>(callback_data);
485 if ((file != nullptr) && !file->WriteFully(buffer, size)) {
486 PrintErrAndExit("Error: Unable to write snapshot file\n\n");
487 }
488}
489
490static void StreamingCloseCallback(void* callback_data) {
491 File* file = reinterpret_cast<File*>(callback_data);
492 file->Release();
493}
494
496 File* manifest_file = OpenFile(loading_unit_manifest_filename);
497 if (!manifest_file->Print("{ \"loadingUnits\": [\n ")) {
498 PrintErrAndExit("Error: Unable to write file: %s\n\n",
499 loading_unit_manifest_filename);
500 }
501 return manifest_file;
502}
503
504static void WriteLoadingUnitManifest(File* manifest_file,
505 intptr_t id,
506 const char* path,
507 const char* debug_path = nullptr) {
508 TextBuffer line(128);
509 if (id != 1) {
510 line.AddString(",\n ");
511 }
512 line.Printf("{\n \"id\": %" Pd ",\n \"path\": \"", id);
513 line.AddEscapedString(path);
514 if (debug_path != nullptr) {
515 line.Printf("\",\n \"debugPath\": \"");
516 line.AddEscapedString(debug_path);
517 }
518 line.AddString("\",\n \"libraries\": [\n ");
520 CHECK_RESULT(uris);
521 intptr_t length;
523 for (intptr_t i = 0; i < length; i++) {
524 const char* uri;
526 if (i != 0) {
527 line.AddString(",\n ");
528 }
529 line.AddString("\"");
530 line.AddEscapedString(uri);
531 line.AddString("\"");
532 }
533 line.AddString("\n ]}");
534 if (!manifest_file->Print("%s", line.buffer())) {
535 PrintErrAndExit("Error: Unable to write file: %s\n\n",
536 loading_unit_manifest_filename);
537 }
538}
539
540static void CloseLoadingUnitManifest(File* manifest_file) {
541 if (!manifest_file->Print("]}\n")) {
542 PrintErrAndExit("Error: Unable to write file: %s\n\n",
543 loading_unit_manifest_filename);
544 }
545 manifest_file->Release();
546}
547
548static void NextLoadingUnit(void* callback_data,
549 intptr_t loading_unit_id,
550 void** write_callback_data,
551 void** write_debug_callback_data,
552 const char* main_filename,
553 const char* suffix) {
554 char* filename = loading_unit_id == 1
555 ? Utils::StrDup(main_filename)
556 : Utils::SCreate("%s-%" Pd ".part.%s", main_filename,
557 loading_unit_id, suffix);
558 File* file = OpenFile(filename);
559 *write_callback_data = file;
560
561 char* debug_filename = nullptr;
562 if (debugging_info_filename != nullptr) {
563 debug_filename =
564 loading_unit_id == 1
565 ? Utils::StrDup(debugging_info_filename)
566 : Utils::SCreate("%s-%" Pd ".part.so", debugging_info_filename,
567 loading_unit_id);
568 File* debug_file = OpenFile(debug_filename);
569 *write_debug_callback_data = debug_file;
570 }
571
572 WriteLoadingUnitManifest(reinterpret_cast<File*>(callback_data),
573 loading_unit_id, filename, debug_filename);
574 free(debug_filename);
575
576 free(filename);
577}
578
579static void NextAsmCallback(void* callback_data,
580 intptr_t loading_unit_id,
581 void** write_callback_data,
582 void** write_debug_callback_data) {
583 NextLoadingUnit(callback_data, loading_unit_id, write_callback_data,
584 write_debug_callback_data, assembly_filename, "S");
585}
586
587static void NextElfCallback(void* callback_data,
588 intptr_t loading_unit_id,
589 void** write_callback_data,
590 void** write_debug_callback_data) {
591 NextLoadingUnit(callback_data, loading_unit_id, write_callback_data,
592 write_debug_callback_data, elf_filename, "so");
593}
594
598
599 // Precompile with specified embedder entry points
602
603 // Create a precompiled snapshot.
605 if (strip && (debugging_info_filename == nullptr)) {
607 "Warning: Generating assembly code without DWARF debugging"
608 " information.\n");
609 }
610 if (loading_unit_manifest_filename == nullptr) {
611 File* file = OpenFile(assembly_filename);
613 File* debug_file = nullptr;
614 if (debugging_info_filename != nullptr) {
615 debug_file = OpenFile(debugging_info_filename);
616 }
618 strip, debug_file);
619 if (debug_file != nullptr) debug_file->Release();
621 } else {
622 File* manifest_file = OpenLoadingUnitManifest();
624 NextAsmCallback, manifest_file, strip, StreamingWriteCallback,
627 CloseLoadingUnitManifest(manifest_file);
628 }
629 if (obfuscate && !strip) {
631 "Warning: The generated assembly code contains unobfuscated DWARF "
632 "debugging information.\n"
633 " To avoid this, use --strip to remove it.\n");
634 }
635 } else if (snapshot_kind == kAppAOTElf) {
636 if (strip && (debugging_info_filename == nullptr)) {
638 "Warning: Generating ELF library without DWARF debugging"
639 " information.\n");
640 }
641 if (loading_unit_manifest_filename == nullptr) {
642 File* file = OpenFile(elf_filename);
644 File* debug_file = nullptr;
645 if (debugging_info_filename != nullptr) {
646 debug_file = OpenFile(debugging_info_filename);
647 }
649 strip, debug_file);
650 if (debug_file != nullptr) debug_file->Release();
652 } else {
653 File* manifest_file = OpenLoadingUnitManifest();
658 CloseLoadingUnitManifest(manifest_file);
659 }
660 if (obfuscate && !strip) {
662 "Warning: The generated ELF library contains unobfuscated DWARF "
663 "debugging information.\n"
664 " To avoid this, use --strip to remove it and "
665 "--save-debugging-info=<...> to save it to a separate file.\n");
666 }
667 } else {
668 UNREACHABLE();
669 }
670
671 // Serialize obfuscation map if requested.
672 if (obfuscation_map_filename != nullptr) {
673 ASSERT(obfuscate);
674 uint8_t* buffer = nullptr;
675 intptr_t size = 0;
678 WriteFile(obfuscation_map_filename, buffer, size);
679 }
680}
681
683 uint8_t* kernel_buffer = nullptr;
684 intptr_t kernel_buffer_size = 0;
685 ReadFile(inputs.GetArgument(0), &kernel_buffer, &kernel_buffer_size);
686
687 Dart_IsolateFlags isolate_flags;
688 Dart_IsolateFlagsInitialize(&isolate_flags);
690 isolate_flags.obfuscate = obfuscate;
691 }
692
693 auto isolate_group_data = std::unique_ptr<IsolateGroupData>(
694 new IsolateGroupData(nullptr, nullptr, nullptr, false));
695 Dart_Isolate isolate;
696 char* error = nullptr;
697
698 bool loading_kernel_failed = false;
699 if (isolate_snapshot_data == nullptr) {
700 // We need to capture the vmservice library in the core snapshot, so load it
701 // in the main isolate as well.
702 isolate_flags.load_vmservice_library = true;
704 nullptr, nullptr, kernel_buffer, kernel_buffer_size, &isolate_flags,
705 isolate_group_data.get(), /*isolate_data=*/nullptr, &error);
706 loading_kernel_failed = (isolate == nullptr);
707 } else {
708 isolate = Dart_CreateIsolateGroup(nullptr, nullptr, isolate_snapshot_data,
710 &isolate_flags, isolate_group_data.get(),
711 /*isolate_data=*/nullptr, &error);
712 }
713 if (isolate == nullptr) {
714 Syslog::PrintErr("%s\n", error);
715 free(error);
716 free(kernel_buffer);
717 // The only real reason when `gen_snapshot` fails to create an isolate from
718 // a valid kernel file is if loading the kernel results in a "compile-time"
719 // error.
720 //
721 // There are other possible reasons, like memory allocation failures, but
722 // those are very uncommon.
723 //
724 // The Dart API doesn't allow us to distinguish the different error cases,
725 // so we'll use [kCompilationErrorExitCode] for failed kernel loading, since
726 // a compile-time error is the most probable cause.
727 return loading_kernel_failed ? kCompilationErrorExitCode : kErrorExitCode;
728 }
729
734
735 // The root library has to be set to generate AOT snapshots, and sometimes we
736 // set one for the core snapshot too.
737 // If the input dill file has a root library, then Dart_LoadScript will
738 // ignore this dummy uri and set the root library to the one reported in
739 // the dill file. Since dill files are not dart script files,
740 // trying to resolve the root library URI based on the dill file name
741 // would not help.
742 //
743 // If the input dill file does not have a root library, then
744 // Dart_LoadScript will error.
745 //
746 // TODO(kernel): Dart_CreateIsolateGroupFromKernel should respect the root
747 // library in the kernel file, though this requires auditing the other
748 // loading paths in the embedders that had to work around this.
750 Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size));
752
754
756
757 switch (snapshot_kind) {
758 case kCore:
760 break;
761 case kApp:
763 break;
764 case kAppJIT:
766 break;
767 case kAppAOTAssembly:
768 case kAppAOTElf:
770 break;
771 case kVMAOTAssembly: {
772 File* file = OpenFile(assembly_filename);
776 break;
777 }
778 default:
779 UNREACHABLE();
780 }
781
784
785 free(kernel_buffer);
786 return 0;
787}
788
789int main(int argc, char** argv) {
790#if !defined(DART_HOST_OS_WINDOWS)
791 // Very early so any crashes during startup can also be symbolized.
793#endif
794
795 const int EXTRA_VM_ARGUMENTS = 7;
796 CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
798
799 // When running from the command line we assume that we are optimizing for
800 // throughput, and therefore use a larger new gen semi space size and a faster
801 // new gen growth factor unless others have been specified.
802 if (kWordSize <= 4) {
803 vm_options.AddArgument("--new_gen_semi_max_size=16");
804 } else {
805 vm_options.AddArgument("--new_gen_semi_max_size=32");
806 }
807 vm_options.AddArgument("--new_gen_growth_factor=4");
808 vm_options.AddArgument("--deterministic");
809
810 // Parse command line arguments.
811 if (ParseArguments(argc, argv, &vm_options, &inputs) < 0) {
812 PrintUsage();
813 return kErrorExitCode;
814 }
816
817 if (!Platform::Initialize()) {
818 Syslog::PrintErr("Initialization failed\n");
819 return kErrorExitCode;
820 }
824 // Start event handler.
827
829 vm_options.AddArgument("--precompilation");
830 // AOT snapshot can be deployed to another machine,
831 // so generated code should not depend on the CPU features
832 // of the system where snapshot was generated.
833 vm_options.AddArgument("--target_unknown_cpu");
834 } else if (snapshot_kind == kAppJIT) {
835 // App-jit snapshot can be deployed to another machine,
836 // so generated code should not depend on the CPU features
837 // of the system where snapshot was generated.
838 vm_options.AddArgument("--target_unknown_cpu");
839#if !defined(TARGET_ARCH_IA32)
840 vm_options.AddArgument("--link_natives_lazily");
841#endif
842 }
843
844 char* error = Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
845 if (error != nullptr) {
846 Syslog::PrintErr("Setting VM flags failed: %s\n", error);
847 free(error);
848 return kErrorExitCode;
849 }
850
851 Dart_InitializeParams init_params;
852 memset(&init_params, 0, sizeof(init_params));
854 init_params.file_open = DartUtils::OpenFile;
855 init_params.file_read = DartUtils::ReadFile;
856 init_params.file_write = DartUtils::WriteFile;
857 init_params.file_close = DartUtils::CloseFile;
859 init_params.start_kernel_isolate = false;
860#if defined(DART_HOST_OS_FUCHSIA)
861 init_params.vmex_resource = Platform::GetVMEXResource();
862#endif
863
864 std::unique_ptr<MappedMemory> mapped_vm_snapshot_data;
865 std::unique_ptr<MappedMemory> mapped_vm_snapshot_instructions;
866 std::unique_ptr<MappedMemory> mapped_isolate_snapshot_data;
867 std::unique_ptr<MappedMemory> mapped_isolate_snapshot_instructions;
868 if (load_vm_snapshot_data_filename != nullptr) {
869 mapped_vm_snapshot_data =
870 MapFile(load_vm_snapshot_data_filename, File::kReadOnly,
871 &init_params.vm_snapshot_data);
872 }
873 if (load_vm_snapshot_instructions_filename != nullptr) {
874 mapped_vm_snapshot_instructions =
875 MapFile(load_vm_snapshot_instructions_filename, File::kReadExecute,
876 &init_params.vm_snapshot_instructions);
877 }
878 if (load_isolate_snapshot_data_filename != nullptr) {
879 mapped_isolate_snapshot_data =
880 MapFile(load_isolate_snapshot_data_filename, File::kReadOnly,
882 }
883 if (load_isolate_snapshot_instructions_filename != nullptr) {
884 mapped_isolate_snapshot_instructions =
885 MapFile(load_isolate_snapshot_instructions_filename, File::kReadExecute,
887 }
888
889 error = Dart_Initialize(&init_params);
890 if (error != nullptr) {
891 Syslog::PrintErr("VM initialization failed: %s\n", error);
892 free(error);
893 return kErrorExitCode;
894 }
895
897 if (result != 0) {
898 return result;
899 }
900
902 if (error != nullptr) {
903 Syslog::PrintErr("VM cleanup failed: %s\n", error);
904 free(error);
905 }
907 return 0;
908}
909
910} // namespace bin
911} // namespace dart
912
913int main(int argc, char** argv) {
914 return dart::bin::main(argc, argv);
915}
#define UNREACHABLE()
Definition: assert.h:248
GLenum type
static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
VPrintErr(format, args)
static char * StrDup(const char *s)
static char * SCreate(const char *format,...) PRINTF_ATTRIBUTE(1
Definition: utils.cc:231
const char ** arguments() const
Definition: dartutils.h:63
void AddArgument(const char *argument)
Definition: dartutils.h:68
static void SaveConfig()
static void ReadFile(uint8_t **data, intptr_t *file_len, void *stream)
Definition: dartutils.cc:273
static bool SetOriginalWorkingDirectory()
Definition: dartutils.cc:821
static bool EntropySource(uint8_t *buffer, intptr_t length)
Definition: dartutils.cc:308
static Dart_Handle EnvironmentCallback(Dart_Handle name)
Definition: dartutils.cc:835
static void SetEnvironment(dart::SimpleHashMap *environment)
Definition: dartutils.cc:831
static void CloseFile(void *stream)
Definition: dartutils.cc:303
static void * OpenFile(const char *name, bool write)
Definition: dartutils.cc:261
static void WriteFile(const void *buffer, intptr_t num_bytes, void *stream)
Definition: dartutils.cc:294
static void LoadDartProfilerSymbols(const char *exepath)
Definition: exe_utils.cc:129
@ kReadExecute
Definition: file.h:122
static File * Open(Namespace *namespc, const char *path, FileOpenMode mode)
@ kWriteTruncate
Definition: file.h:60
bool Print(const char *format,...) PRINTF_ATTRIBUTE(2
static void InitOnce()
Definition: loader.cc:182
void * address() const
Definition: file.h:34
static bool TryProcess(const char *option, CommandLineOptions *options)
Definition: options.cc:34
static bool IsValidShortFlag(const char *name)
Definition: options.cc:16
static bool ProcessEnvironmentOption(const char *arg, CommandLineOptions *vm_options, dart::SimpleHashMap **environment)
Definition: options.cc:54
static DART_NORETURN void Exit(int exit_code)
static bool Initialize()
static void InitOnce()
#define DART_INITIALIZE_PARAMS_CURRENT_VERSION
Definition: dart_api.h:840
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
struct _Dart_Isolate * Dart_Isolate
Definition: dart_api.h:88
@ Dart_TypedData_kUint8
Definition: dart_api.h:2615
#define ASSERT(E)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
uint32_t uint32_t * format
#define CHECK_RESULT(result)
Definition: gen_snapshot.cc:42
int main(int argc, char **argv)
#define BOOL_OPTIONS_LIST(V)
#define STRING_OPTION_DEFINITION(flag, variable)
#define BOOL_OPTION_DEFINITION(flag, variable)
#define STRING_OPTIONS_LIST(V)
Definition: gen_snapshot.cc:98
size_t length
char ** argv
Definition: library.h:9
constexpr int kCompilationErrorExitCode
Definition: error_exit.h:16
static void CloseLoadingUnitManifest(File *manifest_file)
void WriteFile(const void *buffer, intptr_t num_bytes, void *stream)
void ReadFile(uint8_t **data, intptr_t *file_len, void *stream)
const uint8_t * isolate_snapshot_data
Definition: gen_snapshot.cc:69
static bool IsSnapshottingForPrecompilation()
static void CreateAndWritePrecompiledSnapshot()
static int CreateIsolateAndSnapshot(const CommandLineOptions &inputs)
va_start(args, format)
static File * OpenLoadingUnitManifest()
static bool ProcessEnvironmentOption(const char *arg, CommandLineOptions *vm_options)
Definition: gen_snapshot.cc:61
static void PrintUsage()
static void MaybeLoadCode()
static void CreateAndWriteCoreSnapshot()
exit(kErrorExitCode)
static void StreamingWriteCallback(void *callback_data, const uint8_t *buffer, intptr_t size)
int main(int argc, char **argv)
constexpr int kErrorExitCode
Definition: error_exit.h:18
va_end(args)
static void MaybeLoadExtraInputs(const CommandLineOptions &inputs)
static void NextLoadingUnit(void *callback_data, intptr_t loading_unit_id, void **write_callback_data, void **write_debug_callback_data, const char *main_filename, const char *suffix)
DEFINE_ENUM_OPTION(snapshot_kind, SnapshotKind, snapshot_kind)
static void WriteLoadingUnitManifest(File *manifest_file, intptr_t id, const char *path, const char *debug_path=nullptr)
static SnapshotKind snapshot_kind
Definition: gen_snapshot.cc:83
static void StreamingCloseCallback(void *callback_data)
static void CreateAndWriteAppJITSnapshot()
static int ParseArguments(int argc, char **argv, CommandLineOptions *vm_options, CommandLineOptions *inputs)
static void CreateAndWriteAppSnapshot()
PRINTF_ATTRIBUTE(1, 2) static void PrintErrAndExit(const char *format
void * OpenFile(const char *name, bool write)
static void MallocFinalizer(void *isolate_callback_data, void *peer)
static void NextAsmCallback(void *callback_data, intptr_t loading_unit_id, void **write_callback_data, void **write_debug_callback_data)
static void NextElfCallback(void *callback_data, intptr_t loading_unit_id, void **write_callback_data, void **write_debug_callback_data)
DEFINE_CB_OPTION(ProcessEnvironmentOption)
static const char *const kSnapshotKindNames[]
Definition: gen_snapshot.cc:86
Dart_ShutdownIsolate()
static dart::SimpleHashMap * environment
Definition: gen_snapshot.cc:59
const uint8_t * isolate_snapshot_instructions
Definition: gen_snapshot.cc:70
static std::unique_ptr< MappedMemory > MapFile(const char *filename, File::MapType type, const uint8_t **buffer)
Definition: dart_vm.cc:33
DART_EXPORT Dart_Handle Dart_ListGetAt(Dart_Handle list, intptr_t index)
DART_EXPORT Dart_Handle Dart_CreateAppAOTSnapshotAsElfs(Dart_CreateLoadingUnitCallback next_callback, void *next_callback_data, bool strip, Dart_StreamingWriteCallback write_callback, Dart_StreamingCloseCallback close_callback)
DART_EXPORT void Dart_EnterScope()
DART_EXPORT Dart_Handle Dart_GetObfuscationMap(uint8_t **buffer, intptr_t *buffer_length)
DART_EXPORT Dart_Handle Dart_CreateAppAOTSnapshotAsAssemblies(Dart_CreateLoadingUnitCallback next_callback, void *next_callback_data, bool strip, Dart_StreamingWriteCallback write_callback, Dart_StreamingCloseCallback close_callback)
void * malloc(size_t size)
Definition: allocation.cc:19
DART_EXPORT Dart_Handle Dart_Precompile()
DART_EXPORT void Dart_IsolateFlagsInitialize(Dart_IsolateFlags *flags)
DART_EXPORT Dart_Handle Dart_NewExternalTypedDataWithFinalizer(Dart_TypedData_Type type, void *data, intptr_t length, void *peer, intptr_t external_allocation_size, Dart_HandleFinalizer callback)
DART_EXPORT Dart_Handle Dart_CreateAppJITSnapshotAsBlobs(uint8_t **isolate_snapshot_data_buffer, intptr_t *isolate_snapshot_data_size, uint8_t **isolate_snapshot_instructions_buffer, intptr_t *isolate_snapshot_instructions_size)
DART_EXPORT Dart_Handle Dart_CreateAppAOTSnapshotAsElf(Dart_StreamingWriteCallback callback, void *callback_data, bool strip, void *debug_callback_data)
DART_EXPORT char * Dart_Initialize(Dart_InitializeParams *params)
DART_EXPORT const char * Dart_VersionString()
DART_EXPORT char * Dart_Cleanup()
DART_EXPORT Dart_Handle Dart_CreateAppAOTSnapshotAsAssembly(Dart_StreamingWriteCallback callback, void *callback_data, bool strip, void *debug_callback_data)
DART_EXPORT Dart_Isolate Dart_CreateIsolateGroup(const char *script_uri, const char *name, const uint8_t *snapshot_data, const uint8_t *snapshot_instructions, Dart_IsolateFlags *flags, void *isolate_group_data, void *isolate_data, char **error)
DART_EXPORT Dart_Handle Dart_LoadLibrary(Dart_Handle kernel_buffer)
DART_EXPORT Dart_Isolate Dart_CreateIsolateGroupFromKernel(const char *script_uri, const char *name, const uint8_t *kernel_buffer, intptr_t kernel_buffer_size, Dart_IsolateFlags *flags, void *isolate_group_data, void *isolate_data, char **error)
DART_EXPORT char * Dart_SetVMFlags(int argc, const char **argv)
DART_EXPORT Dart_Handle Dart_CreateVMAOTSnapshotAsAssembly(Dart_StreamingWriteCallback callback, void *callback_data)
DART_EXPORT Dart_Handle Dart_LoadingUnitLibraryUris(intptr_t loading_unit_id)
DART_EXPORT Dart_Handle Dart_CompileAll()
DART_EXPORT Dart_Handle Dart_ListLength(Dart_Handle list, intptr_t *len)
constexpr intptr_t kWordSize
Definition: globals.h:509
DART_EXPORT Dart_Handle Dart_SetEnvironmentCallback(Dart_EnvironmentCallback callback)
DART_EXPORT Dart_Handle Dart_SetRootLibrary(Dart_Handle library)
DART_EXPORT Dart_Handle Dart_StringToCString(Dart_Handle object, const char **cstr)
DART_EXPORT Dart_Handle Dart_CreateSnapshot(uint8_t **vm_snapshot_data_buffer, intptr_t *vm_snapshot_data_size, uint8_t **isolate_snapshot_data_buffer, intptr_t *isolate_snapshot_data_size, bool is_core)
DART_EXPORT Dart_Handle Dart_LoadLibraryFromKernel(const uint8_t *buffer, intptr_t buffer_size)
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
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
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
help
Definition: zip.py:79
#define Pd
Definition: globals.h:408
Dart_FileReadCallback file_read
Definition: dart_api.h:955
const uint8_t * vm_snapshot_data
Definition: dart_api.h:911
Dart_FileOpenCallback file_open
Definition: dart_api.h:954
Dart_FileWriteCallback file_write
Definition: dart_api.h:956
Dart_EntropySource entropy_source
Definition: dart_api.h:958
const uint8_t * vm_snapshot_instructions
Definition: dart_api.h:919
Dart_FileCloseCallback file_close
Definition: dart_api.h:957
bool load_vmservice_library
Definition: dart_api.h:590