Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Namespaces | Macros | Enumerations | Functions | Variables
gen_snapshot.cc File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstdarg>
#include <memory>
#include "bin/builtin.h"
#include "bin/console.h"
#include "bin/dartutils.h"
#include "bin/error_exit.h"
#include "bin/eventhandler.h"
#include "bin/exe_utils.h"
#include "bin/file.h"
#include "bin/loader.h"
#include "bin/options.h"
#include "bin/platform.h"
#include "bin/snapshot_utils.h"
#include "bin/thread.h"
#include "bin/utils.h"
#include "bin/vmservice_impl.h"
#include "include/dart_api.h"
#include "include/dart_tools_api.h"
#include "platform/globals.h"
#include "platform/growable_array.h"
#include "platform/hashmap.h"
#include "platform/syslog.h"
#include "platform/text_buffer.h"

Go to the source code of this file.

Namespaces

namespace  dart
 
namespace  dart::bin
 

Macros

#define CHECK_RESULT(result)
 
#define STRING_OPTIONS_LIST(V)
 
#define BOOL_OPTIONS_LIST(V)
 
#define STRING_OPTION_DEFINITION(flag, variable)
 
#define BOOL_OPTION_DEFINITION(flag, variable)
 

Enumerations

enum  dart::bin::SnapshotKind {
  dart::bin::kCore , dart::bin::kApp , dart::bin::kAppJIT , dart::bin::kAppAOTAssembly ,
  dart::bin::kAppAOTElf , dart::bin::kVMAOTAssembly , dart::bin::kNone , dart::bin::kKernel ,
  dart::bin::kAppJIT
}
 

Functions

static bool dart::bin::ProcessEnvironmentOption (const char *arg, CommandLineOptions *vm_options)
 
 dart::bin::DEFINE_ENUM_OPTION (snapshot_kind, SnapshotKind, snapshot_kind)
 
 dart::bin::DEFINE_CB_OPTION (ProcessEnvironmentOption)
 
static bool dart::bin::IsSnapshottingForPrecompilation ()
 
static void dart::bin::PrintUsage ()
 
static int dart::bin::ParseArguments (int argc, char **argv, CommandLineOptions *vm_options, CommandLineOptions *inputs)
 
 dart::bin::PRINTF_ATTRIBUTE (1, 2) static void PrintErrAndExit(const char *format
 
 dart::bin::va_start (args, format)
 
 dart::bin::va_end (args)
 
 dart::bin::Dart_ExitScope ()
 
 dart::bin::Dart_ShutdownIsolate ()
 
 dart::bin::exit (kErrorExitCode)
 
static Filedart::bin::OpenFile (const char *filename)
 
static void dart::bin::WriteFile (const char *filename, const uint8_t *buffer, const intptr_t size)
 
static void dart::bin::ReadFile (const char *filename, uint8_t **buffer, intptr_t *size)
 
static void dart::bin::MallocFinalizer (void *isolate_callback_data, void *peer)
 
static void dart::bin::MaybeLoadExtraInputs (const CommandLineOptions &inputs)
 
static void dart::bin::MaybeLoadCode ()
 
static void dart::bin::CreateAndWriteCoreSnapshot ()
 
static std::unique_ptr< MappedMemorydart::bin::MapFile (const char *filename, File::MapType type, const uint8_t **buffer)
 
static void dart::bin::CreateAndWriteAppSnapshot ()
 
static void dart::bin::CreateAndWriteAppJITSnapshot ()
 
static void dart::bin::StreamingWriteCallback (void *callback_data, const uint8_t *buffer, intptr_t size)
 
static void dart::bin::StreamingCloseCallback (void *callback_data)
 
static Filedart::bin::OpenLoadingUnitManifest ()
 
static void dart::bin::WriteLoadingUnitManifest (File *manifest_file, intptr_t id, const char *path, const char *debug_path=nullptr)
 
static void dart::bin::CloseLoadingUnitManifest (File *manifest_file)
 
static void dart::bin::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 dart::bin::NextAsmCallback (void *callback_data, intptr_t loading_unit_id, void **write_callback_data, void **write_debug_callback_data)
 
static void dart::bin::NextElfCallback (void *callback_data, intptr_t loading_unit_id, void **write_callback_data, void **write_debug_callback_data)
 
static void dart::bin::CreateAndWritePrecompiledSnapshot ()
 
static int dart::bin::CreateIsolateAndSnapshot (const CommandLineOptions &inputs)
 
int dart::bin::main (int argc, char **argv)
 
int main (int argc, char **argv)
 

Variables

static dart::SimpleHashMapdart::bin::environment = nullptr
 
const uint8_t * dart::bin::isolate_snapshot_data = nullptr
 
const uint8_t * dart::bin::isolate_snapshot_instructions = nullptr
 
static SnapshotKind dart::bin::snapshot_kind = kCore
 
static const char *const dart::bin::kSnapshotKindNames []
 

Macro Definition Documentation

◆ BOOL_OPTION_DEFINITION

#define BOOL_OPTION_DEFINITION (   flag,
  variable 
)
Value:
static bool variable = false; \
DEFINE_BOOL_OPTION(flag, variable)
FlutterSemanticsFlag flag

Definition at line 132 of file gen_snapshot.cc.

141 {
142 return (snapshot_kind == kAppAOTAssembly) || (snapshot_kind == kAppAOTElf) ||
143 (snapshot_kind == kVMAOTAssembly);
144}
145
146// clang-format off
147static void PrintUsage() {
148 Syslog::PrintErr(
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) {
190 Syslog::PrintErr(
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();
227 Platform::Exit(0);
228 } else if (version) {
229 Syslog::PrintErr("Dart SDK version: %s\n", Dart_VersionString());
230 Platform::Exit(0);
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)) {
243 Syslog::PrintErr(
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)) {
255 Syslog::PrintErr(
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) {
266 Syslog::PrintErr(
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) {
276 Syslog::PrintErr(
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) {
286 Syslog::PrintErr(
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) {
294 Syslog::PrintErr(
295 "Obfuscation can only be enabled when building an AOT snapshot.\n\n");
296 return -1;
297 }
298
299 if (debugging_info_filename != nullptr) {
300 Syslog::PrintErr(
301 "--save-debugging-info=<...> can only be enabled when building an "
302 "AOT snapshot.\n\n");
303 return -1;
304 }
305
306 if (strip) {
307 Syslog::PrintErr(
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;
319 Syslog::VPrintErr(format, args);
320 va_end(args);
321
324 exit(kErrorExitCode);
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);
339 RefCntReleaseScope<File> rs(file);
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 }
350 RefCntReleaseScope<File> rs(file);
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);
368 Dart_TypedData_kUint8, buffer, size, buffer, size, MallocFinalizer);
369 CHECK_RESULT(td);
372 }
373}
374
375static void MaybeLoadCode() {
376 if (compile_all && (snapshot_kind == kAppJIT)) {
379 }
380}
381
382static void CreateAndWriteCoreSnapshot() {
383 ASSERT(snapshot_kind == kCore);
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,
417 File::MapType type,
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);
422 exit(kErrorExitCode);
423 }
424 RefCntReleaseScope<File> rs(file);
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);
434 exit(kErrorExitCode);
435 }
436 *buffer = reinterpret_cast<const uint8_t*>(mapping->address());
437 return std::unique_ptr<MappedMemory>(mapping);
438}
439
440static void CreateAndWriteAppSnapshot() {
441 ASSERT(snapshot_kind == kApp);
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
460static void CreateAndWriteAppJITSnapshot() {
461 ASSERT(snapshot_kind == kAppJIT);
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
498static File* OpenLoadingUnitManifest() {
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.
607 if (snapshot_kind == kAppAOTAssembly) {
608 if (strip && (debugging_info_filename == nullptr)) {
609 Syslog::PrintErr(
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);
615 RefCntReleaseScope<File> rs(file);
616 File* debug_file = nullptr;
617 if (debugging_info_filename != nullptr) {
618 debug_file = OpenFile(debugging_info_filename);
619 }
620 result = Dart_CreateAppAOTSnapshotAsAssembly(StreamingWriteCallback, file,
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,
628 StreamingCloseCallback);
630 CloseLoadingUnitManifest(manifest_file);
631 }
632 if (obfuscate && !strip) {
633 Syslog::PrintErr(
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)) {
640 Syslog::PrintErr(
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);
646 RefCntReleaseScope<File> rs(file);
647 File* debug_file = nullptr;
648 if (debugging_info_filename != nullptr) {
649 debug_file = OpenFile(debugging_info_filename);
650 }
651 result = Dart_CreateAppAOTSnapshotAsElf(StreamingWriteCallback, file,
652 strip, debug_file);
653 if (debug_file != nullptr) debug_file->Release();
655 } else {
656 File* manifest_file = OpenLoadingUnitManifest();
657 result = Dart_CreateAppAOTSnapshotAsElfs(NextElfCallback, manifest_file,
658 strip, StreamingWriteCallback,
659 StreamingCloseCallback);
661 CloseLoadingUnitManifest(manifest_file);
662 }
663 if (obfuscate && !strip) {
664 Syslog::PrintErr(
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
685static int CreateIsolateAndSnapshot(const CommandLineOptions& inputs) {
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,
712 isolate_snapshot_instructions,
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
735 Dart_SetEnvironmentCallback(DartUtils::EnvironmentCallback);
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);
776 RefCntReleaseScope<File> rs(file);
777 result = Dart_CreateVMAOTSnapshotAsAssembly(StreamingWriteCallback, file);
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.
795 EXEUtils::LoadDartProfilerSymbols(argv[0]);
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 }
818 DartUtils::SetEnvironment(environment);
819
820 if (!Platform::Initialize()) {
821 Syslog::PrintErr("Initialization failed\n");
822 return kErrorExitCode;
823 }
824 Console::SaveConfig();
825 Loader::InitOnce();
826 DartUtils::SetOriginalWorkingDirectory();
827 // Start event handler.
828 TimerUtils::InitOnce();
829 EventHandler::Start();
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;
861 init_params.entropy_source = DartUtils::EntropySource;
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,
884 &isolate_snapshot_data);
885 }
886 if (load_isolate_snapshot_instructions_filename != nullptr) {
887 mapped_isolate_snapshot_instructions =
888 MapFile(load_isolate_snapshot_instructions_filename, File::kReadExecute,
889 &isolate_snapshot_instructions);
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 }
909 EventHandler::Stop();
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
DART_EXPORT Dart_Isolate Dart_CreateIsolateGroup(const char *script_uri, const char *name, const uint8_t *isolate_snapshot_data, const uint8_t *isolate_snapshot_instructions, Dart_IsolateFlags *flags, void *isolate_group_data, void *isolate_data, char **error)
DART_EXPORT void Dart_IsolateFlagsInitialize(Dart_IsolateFlags *flags)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_CreateAppAOTSnapshotAsElf(Dart_StreamingWriteCallback callback, void *callback_data, bool stripped, void *debug_callback_data)
#define DART_INITIALIZE_PARAMS_CURRENT_VERSION
Definition dart_api.h:839
DART_EXPORT void Dart_EnterScope(void)
DART_EXPORT void Dart_ExitScope(void)
DART_EXPORT const char * Dart_VersionString(void)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_CreateAppAOTSnapshotAsAssemblies(Dart_CreateLoadingUnitCallback next_callback, void *next_callback_data, bool stripped, Dart_StreamingWriteCallback write_callback, Dart_StreamingCloseCallback close_callback)
DART_EXPORT void Dart_ShutdownIsolate(void)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_CreateAppAOTSnapshotAsElfs(Dart_CreateLoadingUnitCallback next_callback, void *next_callback_data, bool stripped, Dart_StreamingWriteCallback write_callback, Dart_StreamingCloseCallback close_callback)
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_CreateVMAOTSnapshotAsAssembly(Dart_StreamingWriteCallback callback, void *callback_data)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_CreateAppAOTSnapshotAsAssembly(Dart_StreamingWriteCallback callback, void *callback_data, bool stripped, void *debug_callback_data)
struct _Dart_Isolate * Dart_Isolate
Definition dart_api.h:88
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_LoadLibraryFromKernel(const uint8_t *kernel_buffer, intptr_t kernel_buffer_size)
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_WARN_UNUSED_RESULT char * Dart_Initialize(Dart_InitializeParams *params)
@ Dart_TypedData_kUint8
Definition dart_api.h:2606
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_GetObfuscationMap(uint8_t **buffer, intptr_t *buffer_length)
DART_EXPORT DART_WARN_UNUSED_RESULT 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_WARN_UNUSED_RESULT Dart_Handle Dart_LoadLibrary(Dart_Handle kernel_buffer)
DART_EXPORT Dart_Handle Dart_SetEnvironmentCallback(Dart_EnvironmentCallback callback)
DART_EXPORT Dart_Handle Dart_Precompile(void)
DART_EXPORT DART_WARN_UNUSED_RESULT char * Dart_Cleanup(void)
DART_EXPORT DART_WARN_UNUSED_RESULT 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_ListLength(Dart_Handle list, intptr_t *length)
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 Dart_Handle Dart_StringToCString(Dart_Handle str, const char **cstr)
DART_EXPORT DART_WARN_UNUSED_RESULT char * Dart_SetVMFlags(int argc, const char **argv)
DART_EXPORT Dart_Handle Dart_ListGetAt(Dart_Handle list, intptr_t index)
DART_EXPORT Dart_Handle Dart_LoadingUnitLibraryUris(intptr_t loading_unit_id)
DART_EXPORT Dart_Handle Dart_SetRootLibrary(Dart_Handle library)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_CompileAll(void)
#define ASSERT(E)
void PrintUsage()
Definition main.cc:143
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 CHECK_RESULT(result)
size_t length
constexpr int kCompilationErrorExitCode
Definition error_exit.h:16
static void CloseLoadingUnitManifest(File *manifest_file)
void ReadFile(uint8_t **data, intptr_t *file_len, void *stream)
static bool IsSnapshottingForPrecompilation()
static void CreateAndWritePrecompiledSnapshot()
static int CreateIsolateAndSnapshot(const CommandLineOptions &inputs)
va_start(args, format)
static File * OpenLoadingUnitManifest()
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()
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 std::unique_ptr< MappedMemory > MapFile(const char *filename, File::MapType type, const uint8_t **buffer)
bool WriteFile(const std::string &path, const char *data, ssize_t size)
Definition files.cc:69
void * malloc(size_t size)
Definition allocation.cc:19
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
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 main.py:1
#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

◆ BOOL_OPTIONS_LIST

#define BOOL_OPTIONS_LIST (   V)
Value:
V(compile_all, compile_all) \
V(help, help) \
V(obfuscate, obfuscate) \
V(strip, strip) \
V(verbose, verbose) \
V(version, version) \
V(sound_null_safety, sound_null_safety)
#define V(name)
Definition raw_object.h:124

Definition at line 117 of file gen_snapshot.cc.

◆ CHECK_RESULT

#define CHECK_RESULT (   result)
Value:
if (Dart_IsError(result)) { \
intptr_t exit_code = 0; \
Syslog::PrintErr("Error: %s\n", Dart_GetError(result)); \
exit_code = kCompilationErrorExitCode; \
} else if (Dart_IsApiError(result)) { \
exit_code = kApiErrorExitCode; \
} else { \
exit_code = kErrorExitCode; \
} \
Dart_ExitScope(); \
Dart_ShutdownIsolate(); \
exit(exit_code); \
}
DART_EXPORT bool Dart_IsApiError(Dart_Handle handle)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT const char * Dart_GetError(Dart_Handle handle)
DART_EXPORT bool Dart_IsCompilationError(Dart_Handle handle)

Definition at line 42 of file gen_snapshot.cc.

43 { \
44 intptr_t exit_code = 0; \
45 Syslog::PrintErr("Error: %s\n", Dart_GetError(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 }
constexpr int kApiErrorExitCode
Definition error_exit.h:14

◆ STRING_OPTION_DEFINITION

#define STRING_OPTION_DEFINITION (   flag,
  variable 
)
Value:
static const char* variable = nullptr; \
DEFINE_STRING_OPTION(flag, variable)

Definition at line 126 of file gen_snapshot.cc.

◆ STRING_OPTIONS_LIST

#define STRING_OPTIONS_LIST (   V)
Value:
V(load_vm_snapshot_data, load_vm_snapshot_data_filename) \
V(load_vm_snapshot_instructions, load_vm_snapshot_instructions_filename) \
V(load_isolate_snapshot_data, load_isolate_snapshot_data_filename) \
V(load_isolate_snapshot_instructions, \
load_isolate_snapshot_instructions_filename) \
V(vm_snapshot_data, vm_snapshot_data_filename) \
V(vm_snapshot_instructions, vm_snapshot_instructions_filename) \
V(isolate_snapshot_data, isolate_snapshot_data_filename) \
V(isolate_snapshot_instructions, isolate_snapshot_instructions_filename) \
V(blobs_container_filename, blobs_container_filename) \
V(assembly, assembly_filename) \
V(elf, elf_filename) \
V(loading_unit_manifest, loading_unit_manifest_filename) \
V(save_debugging_info, debugging_info_filename) \
V(save_obfuscation_map, obfuscation_map_filename)

Definition at line 98 of file gen_snapshot.cc.

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 916 of file gen_snapshot.cc.

916 {
917 return dart::bin::main(argc, argv);
918}