Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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.
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// We define sound_null_safety as an unused option here just to make sure
116// scripts that were passing in this option do not break.
117#define BOOL_OPTIONS_LIST(V) \
118 V(compile_all, compile_all) \
119 V(help, help) \
120 V(obfuscate, obfuscate) \
121 V(strip, strip) \
122 V(verbose, verbose) \
123 V(version, version) \
124 V(sound_null_safety, sound_null_safety)
125
126#define STRING_OPTION_DEFINITION(flag, variable) \
127 static const char* variable = nullptr; \
128 DEFINE_STRING_OPTION(flag, variable)
130#undef STRING_OPTION_DEFINITION
131
132#define BOOL_OPTION_DEFINITION(flag, variable) \
133 static bool variable = false; \
134 DEFINE_BOOL_OPTION(flag, variable)
136#undef BOOL_OPTION_DEFINITION
137
140
145
146// clang-format off
147static void PrintUsage() {
149"Usage: gen_snapshot [<vm-flags>] [<options>] <dart-kernel-file> \n"
150" \n"
151"Common options: \n"
152"--help \n"
153" Display this message (add --verbose for information about all VM options).\n"
154"--version \n"
155" Print the SDK version. \n"
156" \n"
157"To create a core snapshot: \n"
158"--snapshot_kind=core \n"
159"--vm_snapshot_data=<output-file> \n"
160"--isolate_snapshot_data=<output-file> \n"
161"<dart-kernel-file> \n"
162" \n"
163"To create an AOT application snapshot as assembly suitable for compilation \n"
164"as a static or dynamic library: \n"
165"--snapshot_kind=app-aot-assembly \n"
166"--assembly=<output-file> \n"
167"[--strip] \n"
168"[--obfuscate] \n"
169"[--save-debugging-info=<debug-filename>] \n"
170"[--save-obfuscation-map=<map-filename>] \n"
171"<dart-kernel-file> \n"
172" \n"
173"To create an AOT application snapshot as an ELF shared library: \n"
174"--snapshot_kind=app-aot-elf \n"
175"--elf=<output-file> \n"
176"[--strip] \n"
177"[--obfuscate] \n"
178"[--save-debugging-info=<debug-filename>] \n"
179"[--save-obfuscation-map=<map-filename>] \n"
180"<dart-kernel-file> \n"
181" \n"
182"AOT snapshots can be obfuscated: that is all identifiers will be renamed \n"
183"during compilation. This mode is enabled with --obfuscate flag. Mapping \n"
184"between original and obfuscated names can be serialized as a JSON array \n"
185"using --save-obfuscation-map=<filename> option. See dartbug.com/30524 \n"
186"for implementation details and limitations of the obfuscation pass. \n"
187" \n"
188"\n");
189 if (verbose) {
191"The following options are only used for VM development and may\n"
192"be changed in any future version:\n");
193 const char* print_flags = "--print_flags";
194 char* error = Dart_SetVMFlags(1, &print_flags);
195 ASSERT(error == nullptr);
196 }
197}
198// clang-format on
199
200// Parse out the command line arguments. Returns -1 if the arguments
201// are incorrect, 0 otherwise.
202static int ParseArguments(int argc,
203 char** argv,
204 CommandLineOptions* vm_options,
205 CommandLineOptions* inputs) {
206 // Skip the binary name.
207 int i = 1;
208
209 // Parse out the vm options.
210 while ((i < argc) && OptionProcessor::IsValidShortFlag(argv[i])) {
211 if (OptionProcessor::TryProcess(argv[i], vm_options)) {
212 i += 1;
213 continue;
214 }
215 vm_options->AddArgument(argv[i]);
216 i += 1;
217 }
218
219 // Parse out the kernel inputs.
220 while (i < argc) {
221 inputs->AddArgument(argv[i]);
222 i++;
223 }
224
225 if (help) {
226 PrintUsage();
228 } else if (version) {
229 Syslog::PrintErr("Dart SDK version: %s\n", Dart_VersionString());
231 }
232
233 // Verify consistency of arguments.
234 if (inputs->count() < 1) {
235 Syslog::PrintErr("At least one input is required\n");
236 return -1;
237 }
238
239 switch (snapshot_kind) {
240 case kCore: {
241 if ((vm_snapshot_data_filename == nullptr) ||
242 (isolate_snapshot_data_filename == nullptr)) {
244 "Building a core snapshot requires specifying output files for "
245 "--vm_snapshot_data and --isolate_snapshot_data.\n\n");
246 return -1;
247 }
248 break;
249 }
250 case kApp:
251 case kAppJIT: {
252 if ((load_vm_snapshot_data_filename == nullptr) ||
253 (isolate_snapshot_data_filename == nullptr) ||
254 (isolate_snapshot_instructions_filename == nullptr)) {
256 "Building an app JIT snapshot requires specifying input files for "
257 "--load_vm_snapshot_data and --load_vm_snapshot_instructions, an "
258 " output file for --isolate_snapshot_data, and an output "
259 "file for --isolate_snapshot_instructions.\n\n");
260 return -1;
261 }
262 break;
263 }
264 case kAppAOTElf: {
265 if (elf_filename == nullptr) {
267 "Building an AOT snapshot as ELF requires specifying "
268 "an output file for --elf.\n\n");
269 return -1;
270 }
271 break;
272 }
273 case kAppAOTAssembly:
274 case kVMAOTAssembly: {
275 if (assembly_filename == nullptr) {
277 "Building an AOT snapshot as assembly requires specifying "
278 "an output file for --assembly.\n\n");
279 return -1;
280 }
281 break;
282 }
283 }
284
285 if (!obfuscate && obfuscation_map_filename != nullptr) {
287 "--save-obfuscation_map=<...> should only be specified when "
288 "obfuscation is enabled by the --obfuscate flag.\n\n");
289 return -1;
290 }
291
293 if (obfuscate) {
295 "Obfuscation can only be enabled when building an AOT snapshot.\n\n");
296 return -1;
297 }
298
299 if (debugging_info_filename != nullptr) {
301 "--save-debugging-info=<...> can only be enabled when building an "
302 "AOT snapshot.\n\n");
303 return -1;
304 }
305
306 if (strip) {
308 "Stripping can only be enabled when building an AOT snapshot.\n\n");
309 return -1;
310 }
311 }
312
313 return 0;
314}
315
316PRINTF_ATTRIBUTE(1, 2) static void PrintErrAndExit(const char* format, ...) {
317 va_list args;
321
325}
326
327static File* OpenFile(const char* filename) {
328 File* file = File::Open(nullptr, filename, File::kWriteTruncate);
329 if (file == nullptr) {
330 PrintErrAndExit("Error: Unable to write file: %s\n\n", filename);
331 }
332 return file;
333}
334
335static void WriteFile(const char* filename,
336 const uint8_t* buffer,
337 const intptr_t size) {
338 File* file = OpenFile(filename);
340 if (!file->WriteFully(buffer, size)) {
341 PrintErrAndExit("Error: Unable to write file: %s\n\n", filename);
342 }
343}
344
345static void ReadFile(const char* filename, uint8_t** buffer, intptr_t* size) {
346 File* file = File::Open(nullptr, filename, File::kRead);
347 if (file == nullptr) {
348 PrintErrAndExit("Error: Unable to read file: %s\n", filename);
349 }
351 *size = file->Length();
352 *buffer = reinterpret_cast<uint8_t*>(malloc(*size));
353 if (!file->ReadFully(*buffer, *size)) {
354 PrintErrAndExit("Error: Unable to read file: %s\n", filename);
355 }
356}
357
358static void MallocFinalizer(void* isolate_callback_data, void* peer) {
359 free(peer);
360}
361
362static void MaybeLoadExtraInputs(const CommandLineOptions& inputs) {
363 for (intptr_t i = 1; i < inputs.count(); i++) {
364 uint8_t* buffer = nullptr;
365 intptr_t size = 0;
366 ReadFile(inputs.GetArgument(i), &buffer, &size);
369 CHECK_RESULT(td);
372 }
373}
374
375static void MaybeLoadCode() {
376 if (compile_all && (snapshot_kind == kAppJIT)) {
379 }
380}
381
384 ASSERT(vm_snapshot_data_filename != nullptr);
385 ASSERT(isolate_snapshot_data_filename != nullptr);
386
388 uint8_t* vm_snapshot_data_buffer = nullptr;
389 intptr_t vm_snapshot_data_size = 0;
390 uint8_t* isolate_snapshot_data_buffer = nullptr;
391 intptr_t isolate_snapshot_data_size = 0;
392
393 // First create a snapshot.
394 result = Dart_CreateSnapshot(&vm_snapshot_data_buffer, &vm_snapshot_data_size,
395 &isolate_snapshot_data_buffer,
396 &isolate_snapshot_data_size,
397 /*is_core=*/true);
399
400 // Now write the vm isolate and isolate snapshots out to the
401 // specified file and exit.
402 WriteFile(vm_snapshot_data_filename, vm_snapshot_data_buffer,
403 vm_snapshot_data_size);
404 if (vm_snapshot_instructions_filename != nullptr) {
405 // Create empty file for the convenience of build systems.
406 WriteFile(vm_snapshot_instructions_filename, nullptr, 0);
407 }
408 WriteFile(isolate_snapshot_data_filename, isolate_snapshot_data_buffer,
409 isolate_snapshot_data_size);
410 if (isolate_snapshot_instructions_filename != nullptr) {
411 // Create empty file for the convenience of build systems.
412 WriteFile(isolate_snapshot_instructions_filename, nullptr, 0);
413 }
414}
415
416static std::unique_ptr<MappedMemory> MapFile(const char* filename,
418 const uint8_t** buffer) {
419 File* file = File::Open(nullptr, filename, File::kRead);
420 if (file == nullptr) {
421 Syslog::PrintErr("Failed to open: %s\n", filename);
423 }
425 intptr_t length = file->Length();
426 if (length == 0) {
427 // Can't map an empty file.
428 *buffer = nullptr;
429 return nullptr;
430 }
431 MappedMemory* mapping = file->Map(type, 0, length);
432 if (mapping == nullptr) {
433 Syslog::PrintErr("Failed to read: %s\n", filename);
435 }
436 *buffer = reinterpret_cast<const uint8_t*>(mapping->address());
437 return std::unique_ptr<MappedMemory>(mapping);
438}
439
442 ASSERT(isolate_snapshot_data_filename != nullptr);
443
445 uint8_t* isolate_snapshot_data_buffer = nullptr;
446 intptr_t isolate_snapshot_data_size = 0;
447
448 result = Dart_CreateSnapshot(nullptr, nullptr, &isolate_snapshot_data_buffer,
449 &isolate_snapshot_data_size, /*is_core=*/false);
451
452 WriteFile(isolate_snapshot_data_filename, isolate_snapshot_data_buffer,
453 isolate_snapshot_data_size);
454 if (isolate_snapshot_instructions_filename != nullptr) {
455 // Create empty file for the convenience of build systems.
456 WriteFile(isolate_snapshot_instructions_filename, nullptr, 0);
457 }
458}
459
462 ASSERT(isolate_snapshot_data_filename != nullptr);
463 ASSERT(isolate_snapshot_instructions_filename != nullptr);
464
466 uint8_t* isolate_snapshot_data_buffer = nullptr;
467 intptr_t isolate_snapshot_data_size = 0;
468 uint8_t* isolate_snapshot_instructions_buffer = nullptr;
469 intptr_t isolate_snapshot_instructions_size = 0;
470
472 &isolate_snapshot_data_buffer, &isolate_snapshot_data_size,
473 &isolate_snapshot_instructions_buffer,
474 &isolate_snapshot_instructions_size);
476
477 WriteFile(isolate_snapshot_data_filename, isolate_snapshot_data_buffer,
478 isolate_snapshot_data_size);
479 WriteFile(isolate_snapshot_instructions_filename,
480 isolate_snapshot_instructions_buffer,
481 isolate_snapshot_instructions_size);
482}
483
484static void StreamingWriteCallback(void* callback_data,
485 const uint8_t* buffer,
486 intptr_t size) {
487 File* file = reinterpret_cast<File*>(callback_data);
488 if ((file != nullptr) && !file->WriteFully(buffer, size)) {
489 PrintErrAndExit("Error: Unable to write snapshot file\n\n");
490 }
491}
492
493static void StreamingCloseCallback(void* callback_data) {
494 File* file = reinterpret_cast<File*>(callback_data);
495 file->Release();
496}
497
499 File* manifest_file = OpenFile(loading_unit_manifest_filename);
500 if (!manifest_file->Print("{ \"loadingUnits\": [\n ")) {
501 PrintErrAndExit("Error: Unable to write file: %s\n\n",
502 loading_unit_manifest_filename);
503 }
504 return manifest_file;
505}
506
507static void WriteLoadingUnitManifest(File* manifest_file,
508 intptr_t id,
509 const char* path,
510 const char* debug_path = nullptr) {
511 TextBuffer line(128);
512 if (id != 1) {
513 line.AddString(",\n ");
514 }
515 line.Printf("{\n \"id\": %" Pd ",\n \"path\": \"", id);
516 line.AddEscapedString(path);
517 if (debug_path != nullptr) {
518 line.Printf("\",\n \"debugPath\": \"");
519 line.AddEscapedString(debug_path);
520 }
521 line.AddString("\",\n \"libraries\": [\n ");
523 CHECK_RESULT(uris);
524 intptr_t length;
526 for (intptr_t i = 0; i < length; i++) {
527 const char* uri;
529 if (i != 0) {
530 line.AddString(",\n ");
531 }
532 line.AddString("\"");
533 line.AddEscapedString(uri);
534 line.AddString("\"");
535 }
536 line.AddString("\n ]}");
537 if (!manifest_file->Print("%s", line.buffer())) {
538 PrintErrAndExit("Error: Unable to write file: %s\n\n",
539 loading_unit_manifest_filename);
540 }
541}
542
543static void CloseLoadingUnitManifest(File* manifest_file) {
544 if (!manifest_file->Print("]}\n")) {
545 PrintErrAndExit("Error: Unable to write file: %s\n\n",
546 loading_unit_manifest_filename);
547 }
548 manifest_file->Release();
549}
550
551static void NextLoadingUnit(void* callback_data,
552 intptr_t loading_unit_id,
553 void** write_callback_data,
554 void** write_debug_callback_data,
555 const char* main_filename,
556 const char* suffix) {
557 char* filename = loading_unit_id == 1
558 ? Utils::StrDup(main_filename)
559 : Utils::SCreate("%s-%" Pd ".part.%s", main_filename,
560 loading_unit_id, suffix);
561 File* file = OpenFile(filename);
562 *write_callback_data = file;
563
564 char* debug_filename = nullptr;
565 if (debugging_info_filename != nullptr) {
566 debug_filename =
567 loading_unit_id == 1
568 ? Utils::StrDup(debugging_info_filename)
569 : Utils::SCreate("%s-%" Pd ".part.so", debugging_info_filename,
570 loading_unit_id);
571 File* debug_file = OpenFile(debug_filename);
572 *write_debug_callback_data = debug_file;
573 }
574
575 WriteLoadingUnitManifest(reinterpret_cast<File*>(callback_data),
576 loading_unit_id, filename, debug_filename);
577 free(debug_filename);
578
579 free(filename);
580}
581
582static void NextAsmCallback(void* callback_data,
583 intptr_t loading_unit_id,
584 void** write_callback_data,
585 void** write_debug_callback_data) {
586 NextLoadingUnit(callback_data, loading_unit_id, write_callback_data,
587 write_debug_callback_data, assembly_filename, "S");
588}
589
590static void NextElfCallback(void* callback_data,
591 intptr_t loading_unit_id,
592 void** write_callback_data,
593 void** write_debug_callback_data) {
594 NextLoadingUnit(callback_data, loading_unit_id, write_callback_data,
595 write_debug_callback_data, elf_filename, "so");
596}
597
601
602 // Precompile with specified embedder entry points
605
606 // Create a precompiled snapshot.
608 if (strip && (debugging_info_filename == nullptr)) {
610 "Warning: Generating assembly code without DWARF debugging"
611 " information.\n");
612 }
613 if (loading_unit_manifest_filename == nullptr) {
614 File* file = OpenFile(assembly_filename);
616 File* debug_file = nullptr;
617 if (debugging_info_filename != nullptr) {
618 debug_file = OpenFile(debugging_info_filename);
619 }
621 strip, debug_file);
622 if (debug_file != nullptr) debug_file->Release();
624 } else {
625 File* manifest_file = OpenLoadingUnitManifest();
627 NextAsmCallback, manifest_file, strip, StreamingWriteCallback,
630 CloseLoadingUnitManifest(manifest_file);
631 }
632 if (obfuscate && !strip) {
634 "Warning: The generated assembly code contains unobfuscated DWARF "
635 "debugging information.\n"
636 " To avoid this, use --strip to remove it.\n");
637 }
638 } else if (snapshot_kind == kAppAOTElf) {
639 if (strip && (debugging_info_filename == nullptr)) {
641 "Warning: Generating ELF library without DWARF debugging"
642 " information.\n");
643 }
644 if (loading_unit_manifest_filename == nullptr) {
645 File* file = OpenFile(elf_filename);
647 File* debug_file = nullptr;
648 if (debugging_info_filename != nullptr) {
649 debug_file = OpenFile(debugging_info_filename);
650 }
652 strip, debug_file);
653 if (debug_file != nullptr) debug_file->Release();
655 } else {
656 File* manifest_file = OpenLoadingUnitManifest();
661 CloseLoadingUnitManifest(manifest_file);
662 }
663 if (obfuscate && !strip) {
665 "Warning: The generated ELF library contains unobfuscated DWARF "
666 "debugging information.\n"
667 " To avoid this, use --strip to remove it and "
668 "--save-debugging-info=<...> to save it to a separate file.\n");
669 }
670 } else {
671 UNREACHABLE();
672 }
673
674 // Serialize obfuscation map if requested.
675 if (obfuscation_map_filename != nullptr) {
676 ASSERT(obfuscate);
677 uint8_t* buffer = nullptr;
678 intptr_t size = 0;
681 WriteFile(obfuscation_map_filename, buffer, size);
682 }
683}
684
686 uint8_t* kernel_buffer = nullptr;
687 intptr_t kernel_buffer_size = 0;
688 ReadFile(inputs.GetArgument(0), &kernel_buffer, &kernel_buffer_size);
689
690 Dart_IsolateFlags isolate_flags;
691 Dart_IsolateFlagsInitialize(&isolate_flags);
693 isolate_flags.obfuscate = obfuscate;
694 }
695
696 auto isolate_group_data = std::unique_ptr<IsolateGroupData>(
697 new IsolateGroupData(nullptr, nullptr, nullptr, false));
698 Dart_Isolate isolate;
699 char* error = nullptr;
700
701 bool loading_kernel_failed = false;
702 if (isolate_snapshot_data == nullptr) {
703 // We need to capture the vmservice library in the core snapshot, so load it
704 // in the main isolate as well.
705 isolate_flags.load_vmservice_library = true;
707 nullptr, nullptr, kernel_buffer, kernel_buffer_size, &isolate_flags,
708 isolate_group_data.get(), /*isolate_data=*/nullptr, &error);
709 loading_kernel_failed = (isolate == nullptr);
710 } else {
711 isolate = Dart_CreateIsolateGroup(nullptr, nullptr, isolate_snapshot_data,
713 &isolate_flags, isolate_group_data.get(),
714 /*isolate_data=*/nullptr, &error);
715 }
716 if (isolate == nullptr) {
717 Syslog::PrintErr("%s\n", error);
718 free(error);
719 free(kernel_buffer);
720 // The only real reason when `gen_snapshot` fails to create an isolate from
721 // a valid kernel file is if loading the kernel results in a "compile-time"
722 // error.
723 //
724 // There are other possible reasons, like memory allocation failures, but
725 // those are very uncommon.
726 //
727 // The Dart API doesn't allow us to distinguish the different error cases,
728 // so we'll use [kCompilationErrorExitCode] for failed kernel loading, since
729 // a compile-time error is the most probable cause.
730 return loading_kernel_failed ? kCompilationErrorExitCode : kErrorExitCode;
731 }
732
737
738 // The root library has to be set to generate AOT snapshots, and sometimes we
739 // set one for the core snapshot too.
740 // If the input dill file has a root library, then Dart_LoadScript will
741 // ignore this dummy uri and set the root library to the one reported in
742 // the dill file. Since dill files are not dart script files,
743 // trying to resolve the root library URI based on the dill file name
744 // would not help.
745 //
746 // If the input dill file does not have a root library, then
747 // Dart_LoadScript will error.
748 //
749 // TODO(kernel): Dart_CreateIsolateGroupFromKernel should respect the root
750 // library in the kernel file, though this requires auditing the other
751 // loading paths in the embedders that had to work around this.
753 Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size));
755
756 MaybeLoadExtraInputs(inputs);
757
759
760 switch (snapshot_kind) {
761 case kCore:
763 break;
764 case kApp:
766 break;
767 case kAppJIT:
769 break;
770 case kAppAOTAssembly:
771 case kAppAOTElf:
773 break;
774 case kVMAOTAssembly: {
775 File* file = OpenFile(assembly_filename);
779 break;
780 }
781 default:
782 UNREACHABLE();
783 }
784
787
788 free(kernel_buffer);
789 return 0;
790}
791
792int main(int argc, char** argv) {
793#if !defined(DART_HOST_OS_WINDOWS)
794 // Very early so any crashes during startup can also be symbolized.
796#endif
797
798 const int EXTRA_VM_ARGUMENTS = 7;
799 CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
800 CommandLineOptions inputs(argc);
801
802 // When running from the command line we assume that we are optimizing for
803 // throughput, and therefore use a larger new gen semi space size and a faster
804 // new gen growth factor unless others have been specified.
805 if (kWordSize <= 4) {
806 vm_options.AddArgument("--new_gen_semi_max_size=16");
807 } else {
808 vm_options.AddArgument("--new_gen_semi_max_size=32");
809 }
810 vm_options.AddArgument("--new_gen_growth_factor=4");
811 vm_options.AddArgument("--deterministic");
812
813 // Parse command line arguments.
814 if (ParseArguments(argc, argv, &vm_options, &inputs) < 0) {
815 PrintUsage();
816 return kErrorExitCode;
817 }
819
820 if (!Platform::Initialize()) {
821 Syslog::PrintErr("Initialization failed\n");
822 return kErrorExitCode;
823 }
827 // Start event handler.
830
832 vm_options.AddArgument("--precompilation");
833 // AOT snapshot can be deployed to another machine,
834 // so generated code should not depend on the CPU features
835 // of the system where snapshot was generated.
836 vm_options.AddArgument("--target_unknown_cpu");
837 } else if (snapshot_kind == kAppJIT) {
838 // App-jit snapshot can be deployed to another machine,
839 // so generated code should not depend on the CPU features
840 // of the system where snapshot was generated.
841 vm_options.AddArgument("--target_unknown_cpu");
842#if !defined(TARGET_ARCH_IA32)
843 vm_options.AddArgument("--link_natives_lazily");
844#endif
845 }
846
847 char* error = Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
848 if (error != nullptr) {
849 Syslog::PrintErr("Setting VM flags failed: %s\n", error);
850 free(error);
851 return kErrorExitCode;
852 }
853
854 Dart_InitializeParams init_params;
855 memset(&init_params, 0, sizeof(init_params));
857 init_params.file_open = DartUtils::OpenFile;
858 init_params.file_read = DartUtils::ReadFile;
859 init_params.file_write = DartUtils::WriteFile;
860 init_params.file_close = DartUtils::CloseFile;
862 init_params.start_kernel_isolate = false;
863#if defined(DART_HOST_OS_FUCHSIA)
864 init_params.vmex_resource = Platform::GetVMEXResource();
865#endif
866
867 std::unique_ptr<MappedMemory> mapped_vm_snapshot_data;
868 std::unique_ptr<MappedMemory> mapped_vm_snapshot_instructions;
869 std::unique_ptr<MappedMemory> mapped_isolate_snapshot_data;
870 std::unique_ptr<MappedMemory> mapped_isolate_snapshot_instructions;
871 if (load_vm_snapshot_data_filename != nullptr) {
872 mapped_vm_snapshot_data =
873 MapFile(load_vm_snapshot_data_filename, File::kReadOnly,
874 &init_params.vm_snapshot_data);
875 }
876 if (load_vm_snapshot_instructions_filename != nullptr) {
877 mapped_vm_snapshot_instructions =
878 MapFile(load_vm_snapshot_instructions_filename, File::kReadExecute,
879 &init_params.vm_snapshot_instructions);
880 }
881 if (load_isolate_snapshot_data_filename != nullptr) {
882 mapped_isolate_snapshot_data =
883 MapFile(load_isolate_snapshot_data_filename, File::kReadOnly,
885 }
886 if (load_isolate_snapshot_instructions_filename != nullptr) {
887 mapped_isolate_snapshot_instructions =
888 MapFile(load_isolate_snapshot_instructions_filename, File::kReadExecute,
890 }
891
892 error = Dart_Initialize(&init_params);
893 if (error != nullptr) {
894 Syslog::PrintErr("VM initialization failed: %s\n", error);
895 free(error);
896 return kErrorExitCode;
897 }
898
899 int result = CreateIsolateAndSnapshot(inputs);
900 if (result != 0) {
901 return result;
902 }
903
905 if (error != nullptr) {
906 Syslog::PrintErr("VM cleanup failed: %s\n", error);
907 free(error);
908 }
910 return 0;
911}
912
913} // namespace bin
914} // namespace dart
915
916int main(int argc, char** argv) {
917 return dart::bin::main(argc, argv);
918}
#define UNREACHABLE()
Definition assert.h:248
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:277
static bool SetOriginalWorkingDirectory()
Definition dartutils.cc:827
static bool EntropySource(uint8_t *buffer, intptr_t length)
Definition dartutils.cc:312
static Dart_Handle EnvironmentCallback(Dart_Handle name)
Definition dartutils.cc:841
static void SetEnvironment(dart::SimpleHashMap *environment)
Definition dartutils.cc:837
static void CloseFile(void *stream)
Definition dartutils.cc:307
static void * OpenFile(const char *name, bool write)
Definition dartutils.cc:265
static void WriteFile(const void *buffer, intptr_t num_bytes, void *stream)
Definition dartutils.cc:298
static void LoadDartProfilerSymbols(const char *exepath)
Definition exe_utils.cc:125
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:169
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:839
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:2606
#define CHECK_RESULT(result)
#define ASSERT(E)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
uint32_t uint32_t * format
#define BOOL_OPTIONS_LIST(V)
#define STRING_OPTION_DEFINITION(flag, variable)
#define BOOL_OPTION_DEFINITION(flag, variable)
#define STRING_OPTIONS_LIST(V)
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
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)
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)
static void WriteLoadingUnitManifest(File *manifest_file, intptr_t id, const char *path, const char *debug_path=nullptr)
static SnapshotKind snapshot_kind
static void StreamingCloseCallback(void *callback_data)
static void CreateAndWriteAppJITSnapshot()
static int ParseArguments(int argc, char **argv, CommandLineOptions *vm_options, CommandLineOptions *inputs)
static void CreateAndWriteAppSnapshot()
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)
static const char *const kSnapshotKindNames[]
Dart_ShutdownIsolate()
static dart::SimpleHashMap * environment
const uint8_t * isolate_snapshot_instructions
static std::unique_ptr< MappedMemory > MapFile(const char *filename, File::MapType type, const uint8_t **buffer)
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)
Definition main.py:1
#define DEFINE_ENUM_OPTION(name, enum_name, variable)
Definition options.h:85
#define DEFINE_CB_OPTION(callback)
Definition options.h:60
#define Pd
Definition globals.h:408
#define PRINTF_ATTRIBUTE(string_index, first_to_check)
Definition globals.h:697
Dart_FileReadCallback file_read
Definition dart_api.h:954
const uint8_t * vm_snapshot_data
Definition dart_api.h:910
Dart_FileOpenCallback file_open
Definition dart_api.h:953
Dart_FileWriteCallback file_write
Definition dart_api.h:955
Dart_EntropySource entropy_source
Definition dart_api.h:957
const uint8_t * vm_snapshot_instructions
Definition dart_api.h:918
Dart_FileCloseCallback file_close
Definition dart_api.h:956
bool load_vmservice_library
Definition dart_api.h:590