Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // Generate a snapshot file after loading all the scripts specified on the | 5 // Generate a snapshot file after loading all the scripts specified on the |
| 6 // command line. | 6 // command line. |
| 7 | 7 |
| 8 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 #include <stdio.h> | 10 #include <stdio.h> |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 Dart_ExitScope(); \ | 31 Dart_ExitScope(); \ |
| 32 Dart_ShutdownIsolate(); \ | 32 Dart_ShutdownIsolate(); \ |
| 33 exit(255); \ | 33 exit(255); \ |
| 34 } \ | 34 } \ |
| 35 | 35 |
| 36 | 36 |
| 37 // Global state that indicates whether a snapshot is to be created and | 37 // Global state that indicates whether a snapshot is to be created and |
| 38 // if so which file to write the snapshot into. | 38 // if so which file to write the snapshot into. |
| 39 static const char* vm_isolate_snapshot_filename = NULL; | 39 static const char* vm_isolate_snapshot_filename = NULL; |
| 40 static const char* isolate_snapshot_filename = NULL; | 40 static const char* isolate_snapshot_filename = NULL; |
| 41 static const char* instructions_snapshot_filename = NULL; | |
| 42 static const char* vm_entry_points_manifest = NULL; | |
|
rmacnak
2015/10/21 23:06:18
Throughout: s/vm_entry_points/embedder_entry_point
Chinmay
2015/10/22 00:13:16
ack
| |
| 41 static const char* package_root = NULL; | 43 static const char* package_root = NULL; |
| 42 | 44 |
| 43 | 45 |
| 44 // Global state which contains a pointer to the script name for which | 46 // Global state which contains a pointer to the script name for which |
| 45 // a snapshot needs to be created (NULL would result in the creation | 47 // a snapshot needs to be created (NULL would result in the creation |
| 46 // of a generic snapshot that contains only the corelibs). | 48 // of a generic snapshot that contains only the corelibs). |
| 47 static char* app_script_name = NULL; | 49 static char* app_script_name = NULL; |
| 48 | 50 |
| 49 | 51 |
| 50 // Global state that captures the URL mappings specified on the command line. | 52 // Global state that captures the URL mappings specified on the command line. |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 81 static bool ProcessIsolateSnapshotOption(const char* option) { | 83 static bool ProcessIsolateSnapshotOption(const char* option) { |
| 82 const char* name = ProcessOption(option, "--isolate_snapshot="); | 84 const char* name = ProcessOption(option, "--isolate_snapshot="); |
| 83 if (name != NULL) { | 85 if (name != NULL) { |
| 84 isolate_snapshot_filename = name; | 86 isolate_snapshot_filename = name; |
| 85 return true; | 87 return true; |
| 86 } | 88 } |
| 87 return false; | 89 return false; |
| 88 } | 90 } |
| 89 | 91 |
| 90 | 92 |
| 93 static bool ProcessInstructionsSnapshotOption(const char* option) { | |
| 94 const char* name = ProcessOption(option, "--instructions_snapshot="); | |
| 95 if (name != NULL) { | |
| 96 instructions_snapshot_filename = name; | |
| 97 return true; | |
| 98 } | |
| 99 return false; | |
| 100 } | |
| 101 | |
| 102 | |
| 103 static bool ProcessVMEntryPointsManifestOption(const char* option) { | |
| 104 const char* name = ProcessOption(option, "--vm_entry_points_manifest="); | |
| 105 if (name != NULL) { | |
| 106 vm_entry_points_manifest = name; | |
| 107 return true; | |
| 108 } | |
| 109 return false; | |
| 110 } | |
| 111 | |
| 112 | |
| 91 static bool ProcessPackageRootOption(const char* option) { | 113 static bool ProcessPackageRootOption(const char* option) { |
| 92 const char* name = ProcessOption(option, "--package_root="); | 114 const char* name = ProcessOption(option, "--package_root="); |
| 93 if (name != NULL) { | 115 if (name != NULL) { |
| 94 package_root = name; | 116 package_root = name; |
| 95 return true; | 117 return true; |
| 96 } | 118 } |
| 97 return false; | 119 return false; |
| 98 } | 120 } |
| 99 | 121 |
| 100 | 122 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 120 const char* kPrefix = "--"; | 142 const char* kPrefix = "--"; |
| 121 const intptr_t kPrefixLen = strlen(kPrefix); | 143 const intptr_t kPrefixLen = strlen(kPrefix); |
| 122 | 144 |
| 123 // Skip the binary name. | 145 // Skip the binary name. |
| 124 int i = 1; | 146 int i = 1; |
| 125 | 147 |
| 126 // Parse out the vm options. | 148 // Parse out the vm options. |
| 127 while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) { | 149 while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) { |
| 128 if (ProcessVmIsolateSnapshotOption(argv[i]) || | 150 if (ProcessVmIsolateSnapshotOption(argv[i]) || |
| 129 ProcessIsolateSnapshotOption(argv[i]) || | 151 ProcessIsolateSnapshotOption(argv[i]) || |
| 152 ProcessInstructionsSnapshotOption(argv[i]) || | |
| 153 ProcessVMEntryPointsManifestOption(argv[i]) || | |
| 130 ProcessURLmappingOption(argv[i]) || | 154 ProcessURLmappingOption(argv[i]) || |
| 131 ProcessPackageRootOption(argv[i])) { | 155 ProcessPackageRootOption(argv[i])) { |
| 132 i += 1; | 156 i += 1; |
| 133 continue; | 157 continue; |
| 134 } | 158 } |
| 135 vm_options->AddArgument(argv[i]); | 159 vm_options->AddArgument(argv[i]); |
| 136 i += 1; | 160 i += 1; |
| 137 } | 161 } |
| 138 | 162 |
| 139 // Get the script name. | 163 // Get the script name. |
| 140 if (i < argc) { | 164 if (i < argc) { |
| 141 *script_name = argv[i]; | 165 *script_name = argv[i]; |
| 142 i += 1; | 166 i += 1; |
| 143 } else { | 167 } else { |
| 144 *script_name = NULL; | 168 *script_name = NULL; |
| 145 } | 169 } |
| 146 | 170 |
| 147 if (vm_isolate_snapshot_filename == NULL) { | 171 if (vm_isolate_snapshot_filename == NULL) { |
| 148 Log::PrintErr("No vm isolate snapshot output file specified.\n\n"); | 172 Log::PrintErr("No vm isolate snapshot output file specified.\n\n"); |
| 149 return -1; | 173 return -1; |
| 150 } | 174 } |
| 151 | 175 |
| 152 if (isolate_snapshot_filename == NULL) { | 176 if (isolate_snapshot_filename == NULL) { |
| 153 Log::PrintErr("No isolate snapshot output file specified.\n\n"); | 177 Log::PrintErr("No isolate snapshot output file specified.\n\n"); |
| 154 return -1; | 178 return -1; |
| 155 } | 179 } |
| 156 | 180 |
| 181 if (instructions_snapshot_filename != NULL && | |
| 182 vm_entry_points_manifest == NULL) { | |
| 183 Log::PrintErr( | |
| 184 "Specifying an instructions snapshot filename indicates " | |
| 185 "precompilation. But no VM entry points manifest was specified.\n\n"); | |
| 186 return -1; | |
| 187 } | |
| 188 | |
| 189 if (vm_entry_points_manifest != NULL && | |
| 190 instructions_snapshot_filename == NULL) { | |
| 191 Log::PrintErr( | |
| 192 "Specifying the VM entry points manifest indicates precompilation. But " | |
| 193 "no instuctions snapshot was specified.\n\n"); | |
| 194 return -1; | |
| 195 } | |
| 196 | |
| 157 return 0; | 197 return 0; |
| 158 } | 198 } |
| 159 | 199 |
| 160 | 200 |
| 201 static bool IsSnapshottingForPrecompilation(void) { | |
| 202 return vm_entry_points_manifest != NULL && | |
| 203 instructions_snapshot_filename != NULL; | |
| 204 } | |
| 205 | |
| 206 | |
| 161 static void WriteSnapshotFile(const char* filename, | 207 static void WriteSnapshotFile(const char* filename, |
| 162 const uint8_t* buffer, | 208 const uint8_t* buffer, |
| 163 const intptr_t size) { | 209 const intptr_t size) { |
| 164 File* file = File::Open(filename, File::kWriteTruncate); | 210 File* file = File::Open(filename, File::kWriteTruncate); |
| 165 ASSERT(file != NULL); | 211 ASSERT(file != NULL); |
| 166 if (!file->WriteFully(buffer, size)) { | 212 if (!file->WriteFully(buffer, size)) { |
| 167 Log::PrintErr("Error: Failed to write snapshot file.\n\n"); | 213 Log::PrintErr("Error: Failed to write snapshot file.\n\n"); |
| 168 } | 214 } |
| 169 delete file; | 215 delete file; |
| 170 } | 216 } |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 413 Dart_Handle lib; | 459 Dart_Handle lib; |
| 414 // Load the builtin library to make it available in the snapshot | 460 // Load the builtin library to make it available in the snapshot |
| 415 // for importing. | 461 // for importing. |
| 416 lib = Builtin::LoadAndCheckLibrary(id); | 462 lib = Builtin::LoadAndCheckLibrary(id); |
| 417 ASSERT(!Dart_IsError(lib)); | 463 ASSERT(!Dart_IsError(lib)); |
| 418 return lib; | 464 return lib; |
| 419 } | 465 } |
| 420 | 466 |
| 421 | 467 |
| 422 static void PrintUsage() { | 468 static void PrintUsage() { |
| 423 Log::PrintErr( | 469 #define STRINGERIZE(...) #__VA_ARGS__ |
| 424 "Usage:\n" | 470 // clang-format off |
| 425 "\n" | 471 Log::PrintErr(STRINGERIZE( |
| 426 " gen_snapshot [<vm-flags>] [<options>] \\\n" | 472 Usage: \n |
| 427 " --snapshot=<out-file> [<dart-script-file>]\n" | 473 gen_snapshot [<vm-flags>] [<options>] [<dart-script-file>] \n |
| 428 "\n" | 474 \n |
| 429 " Writes a snapshot of <dart-script-file> to <out-file>. If no\n" | 475 Writes a snapshot of <dart-script-file> to the specified snapshot files. If \n |
| 430 " <dart-script-file> is passed, a generic snapshot of all the corelibs is\n" | 476 no <dart-script-file> is passed, a generic snapshot of all the corelibs is \n |
| 431 " created. It is required to specify an output file name:\n" | 477 created. It is required to specify the VM isolate snapshot and the isolate \n |
| 432 "\n" | 478 snapshot. The other flags are related to precompilation and are optional. \n |
| 433 " --snapshot=<file> Generates a complete snapshot. Uses the url\n" | 479 \n |
| 434 " mapping specified on the command line to load\n" | 480 Precompilation: \n |
| 435 " the libraries.\n" | 481 In order to configure the snapshotter for precompilation, both the \n |
| 436 "Supported options:\n" | 482 instructions snapshot and the VM entry points manifest must be specified. \n |
| 437 "\n" | 483 Machine code for the target architecture will be dumped into the \n |
| 438 "--package_root=<path>\n" | 484 instructions snapshot. This must be linked into the target binary in a \n |
| 439 " Where to find packages, that is, \"package:...\" imports.\n" | 485 separate step. The VM entry points manifest lists the standalone entry \n |
| 440 "\n" | 486 points into the VM. Not specifying these will cause the tree shaker to \n |
| 441 "--url_mapping=<mapping>\n" | 487 disregard the same as being used. The format of this manifest is as follows.\n |
| 442 " Uses the URL mapping(s) specified on the command line to load the\n" | 488 Each line in the manifest is a comma separated list of three elements. The \n |
| 443 " libraries. For use only with --snapshot=.\n"); | 489 first entry is the library URI, the second entry is the class name and the \n |
| 490 final entry the function name. The file must be terminated with a newline \n | |
| 491 charater. \n | |
| 492 \n | |
| 493 Example: \n | |
| 494 dart:something,SomeClass,doSomething \n | |
| 495 \n | |
| 496 Supported options: \n | |
| 497 --vm_isolate_snapshot=<file> A full snapshot is a compact \n | |
| 498 --isolate_snapshot=<file> representation of the dart vm isolate \n | |
| 499 heap and dart isolate heap states. \n | |
| 500 Both these options are required \n | |
| 501 \n | |
| 502 --package_root=<path> Where to find packages, that is, \n | |
| 503 package:... imports. \n | |
| 504 \n | |
| 505 --url_mapping=<mapping> Uses the URL mapping(s) specified on the\n | |
| 506 command line to load the libraries. \n | |
| 507 \n | |
| 508 --instructions_snapshot=<file> (Precompilation only) Contains the \n | |
| 509 machine code that must be linked into \n | |
|
rmacnak
2015/10/21 23:06:18
s/machine code/assembly
Chinmay
2015/10/22 00:13:16
ack
| |
| 510 the target binary \n | |
| 511 \n | |
| 512 --vm_entry_points_manifest=<file> (Precompilation only) Contains the \n | |
| 513 stanalone VM entry points \n | |
| 514 )); | |
| 515 // clang-format on | |
| 516 #undef STRINGERIZE | |
| 444 } | 517 } |
| 445 | 518 |
| 446 | 519 |
| 447 static void VerifyLoaded(Dart_Handle library) { | 520 static void VerifyLoaded(Dart_Handle library) { |
| 448 if (Dart_IsError(library)) { | 521 if (Dart_IsError(library)) { |
| 449 const char* err_msg = Dart_GetError(library); | 522 const char* err_msg = Dart_GetError(library); |
| 450 Log::PrintErr("Errors encountered while loading: %s\n", err_msg); | 523 Log::PrintErr("Errors encountered while loading: %s\n", err_msg); |
| 451 Dart_ExitScope(); | 524 Dart_ExitScope(); |
| 452 Dart_ShutdownIsolate(); | 525 Dart_ShutdownIsolate(); |
| 453 exit(255); | 526 exit(255); |
| 454 } | 527 } |
| 455 ASSERT(Dart_IsLibrary(library)); | 528 ASSERT(Dart_IsLibrary(library)); |
| 456 } | 529 } |
| 457 | 530 |
| 458 | 531 |
| 532 static const char StubNativeFunctionName[] = "StubNativeFunction"; | |
| 533 | |
| 534 | |
| 535 void StubNativeFunction(Dart_NativeArguments arguments) { | |
| 536 // This is a stub function for the resolver | |
| 537 ASSERT(false); | |
|
rmacnak
2015/10/21 23:06:18
UNREACHABLE();
Chinmay
2015/10/22 00:13:16
ack
| |
| 538 } | |
| 539 | |
| 540 | |
| 541 static Dart_NativeFunction StubNativeLookup(Dart_Handle name, | |
| 542 int argument_count, | |
|
Cutch
2015/10/21 22:00:08
align arguments
Chinmay
2015/10/22 00:13:17
ack
| |
| 543 bool* auto_setup_scope) { | |
| 544 return &StubNativeFunction; | |
| 545 } | |
| 546 | |
| 547 | |
| 548 static const uint8_t* StubNativeSymbol(Dart_NativeFunction nf) { | |
| 549 return reinterpret_cast<const uint8_t *>(StubNativeFunctionName); | |
| 550 } | |
| 551 | |
| 552 | |
| 553 static void SetupStubNativeResolver(size_t lib_index, | |
|
rmacnak
2015/10/21 23:06:18
TODO(24686): Remove this.
Chinmay
2015/10/22 00:13:16
ack
| |
| 554 const Dart_QualifiedFunctionName* entry) { | |
| 555 Dart_Handle library_string = Dart_NewStringFromCString(entry->library_uri); | |
| 556 DART_CHECK_VALID(library_string); | |
| 557 Dart_Handle library = Dart_LookupLibrary(library_string); | |
| 558 // VM entry points may be setup in libraries that have not been explicitly | |
| 559 // loaded by the application script. In such cases, library lookup will | |
| 560 // fail. Manually load those libraries. | |
| 561 if (Dart_IsError(library)) { | |
| 562 static const uint32_t kLoadBufferMaxSize = 128; | |
| 563 char* load_buffer = | |
| 564 reinterpret_cast<char*>(calloc(kLoadBufferMaxSize, sizeof(char))); | |
| 565 snprintf(load_buffer, | |
| 566 kLoadBufferMaxSize, | |
| 567 "import '%s';", | |
| 568 DartUtils::GetStringValue(library_string)); | |
| 569 Dart_Handle script_handle = Dart_NewStringFromCString(load_buffer); | |
| 570 memset(load_buffer, 0, kLoadBufferMaxSize); | |
| 571 snprintf(load_buffer, | |
| 572 kLoadBufferMaxSize, | |
| 573 "dart:_snapshot_%zu", | |
| 574 lib_index); | |
| 575 Dart_Handle script_url = Dart_NewStringFromCString(load_buffer); | |
| 576 free(load_buffer); | |
| 577 Dart_Handle loaded = Dart_LoadLibrary(script_url, script_handle, 0, 0); | |
| 578 DART_CHECK_VALID(loaded); | |
| 579 | |
| 580 // Do a fresh lookup | |
| 581 library = Dart_LookupLibrary(library_string); | |
| 582 } | |
| 583 | |
| 584 DART_CHECK_VALID(library); | |
| 585 Dart_Handle result = Dart_SetNativeResolver(library, | |
| 586 &StubNativeLookup, | |
| 587 &StubNativeSymbol); | |
| 588 DART_CHECK_VALID(result); | |
| 589 } | |
| 590 | |
| 591 | |
| 592 static void ImportNativeEntryPointLibrariesIntoRoot( | |
| 593 const Dart_QualifiedFunctionName* entries) { | |
| 594 if (entries == nullptr) { | |
|
rmacnak
2015/10/21 23:06:18
Here and throughout s/nullptr/NULL
nullptr is und
Chinmay
2015/10/22 00:13:17
ack
| |
| 595 return; | |
| 596 } | |
| 597 | |
| 598 size_t index = 0; | |
| 599 while (true) { | |
| 600 Dart_QualifiedFunctionName entry = entries[index++]; | |
| 601 if (entry.library_uri == nullptr) { | |
| 602 // The termination sentinel has null members. | |
| 603 break; | |
| 604 } | |
| 605 Dart_Handle entry_library = | |
| 606 Dart_LookupLibrary(Dart_NewStringFromCString(entry.library_uri)); | |
| 607 DART_CHECK_VALID(entry_library); | |
| 608 Dart_Handle import_result = Dart_LibraryImportLibrary( | |
| 609 entry_library, Dart_RootLibrary(), Dart_EmptyString()); | |
| 610 DART_CHECK_VALID(import_result); | |
| 611 } | |
| 612 } | |
| 613 | |
| 614 | |
| 615 static void SetupStubNativeResolversForPrecompilation( | |
| 616 const Dart_QualifiedFunctionName* entries) { | |
| 617 | |
| 618 if (entries == nullptr) { | |
| 619 return; | |
| 620 } | |
| 621 | |
| 622 // Setup native resolvers for all libraries found in the manifest. | |
| 623 size_t index = 0; | |
| 624 while (true) { | |
| 625 Dart_QualifiedFunctionName entry = entries[index++]; | |
| 626 if (entry.library_uri == nullptr) { | |
| 627 // The termination sentinel has null members. | |
| 628 break; | |
| 629 } | |
| 630 // Setup stub resolvers on loaded libraries | |
| 631 SetupStubNativeResolver(index, &entry); | |
| 632 } | |
| 633 } | |
| 634 | |
| 635 | |
| 636 static bool ParseEntryPointsManifestSingleLine( | |
|
Cutch
2015/10/21 22:00:08
This should take an char** error which indicates w
Chinmay
2015/10/22 00:13:16
ack
| |
| 637 const char* line, Dart_QualifiedFunctionName* entry) { | |
| 638 bool success = true; | |
| 639 size_t offset = 0; | |
| 640 for (uint8_t i = 0; i < 3; i++) { | |
| 641 char* component = strchr(line + offset, i == 2 ? '\n' : ','); | |
|
rmacnak
2015/10/21 23:06:18
const char* component
Chinmay
2015/10/22 00:13:16
ack
| |
| 642 if (component == nullptr) { | |
| 643 success = false; | |
| 644 break; | |
| 645 } | |
| 646 | |
| 647 int64_t chars_read = component - (line + offset); | |
| 648 if (chars_read <= 0) { | |
| 649 success = false; | |
| 650 break; | |
| 651 } | |
| 652 | |
| 653 if (entry != nullptr) { | |
| 654 // These allocations are collected in |CleanupEntryPointsCollection|. | |
| 655 char* entry_item = | |
| 656 reinterpret_cast<char*>(calloc(chars_read + 1, sizeof(char))); | |
| 657 memcpy(entry_item, line + offset, chars_read); | |
| 658 | |
| 659 switch (i) { | |
| 660 case 0: // library | |
| 661 entry->library_uri = entry_item; | |
| 662 break; | |
| 663 case 1: // class | |
| 664 entry->class_name = entry_item; | |
| 665 break; | |
| 666 case 2: // function | |
| 667 entry->function_name = entry_item; | |
| 668 break; | |
| 669 default: | |
| 670 free(entry_item); | |
| 671 success = false; | |
| 672 break; | |
| 673 } | |
| 674 } | |
| 675 | |
| 676 offset += chars_read + 1; | |
| 677 } | |
| 678 return success; | |
| 679 } | |
| 680 | |
| 681 | |
| 682 int64_t ParseEntryPointsManifestLines(FILE* file, | |
| 683 Dart_QualifiedFunctionName* collection) { | |
| 684 int64_t entries = 0; | |
| 685 | |
| 686 static const int kManifestMaxLineLength = 1024; | |
| 687 char* line = reinterpret_cast<char*>(malloc(kManifestMaxLineLength)); | |
| 688 | |
| 689 while (true) { | |
| 690 char* read_line = fgets(line, kManifestMaxLineLength, file); | |
| 691 | |
| 692 if (read_line == nullptr) { | |
| 693 if ((feof(file) != 0) && (ferror(file) != 0)) { | |
| 694 entries = -1; | |
| 695 } | |
| 696 break; | |
| 697 } | |
| 698 | |
| 699 Dart_QualifiedFunctionName* entry = | |
| 700 collection != nullptr ? collection + entries : nullptr; | |
| 701 | |
| 702 if (!ParseEntryPointsManifestSingleLine(read_line, entry)) { | |
| 703 entries = -1; | |
|
Cutch
2015/10/21 22:00:08
This might leak some |entry_item| allocated above
Chinmay
2015/10/22 00:13:16
ack
| |
| 704 break; | |
| 705 } | |
| 706 | |
| 707 entries++; | |
| 708 } | |
| 709 | |
| 710 free(line); | |
| 711 | |
| 712 return entries; | |
| 713 } | |
| 714 | |
| 715 | |
| 716 static Dart_QualifiedFunctionName* ParseEntryPointsManifestFile( | |
| 717 const char* path) { | |
| 718 if (path == nullptr) { | |
| 719 return nullptr; | |
| 720 } | |
| 721 | |
| 722 FILE* file = fopen(path, "r"); | |
| 723 | |
| 724 if (file == nullptr) { | |
| 725 Log::PrintErr("Could not open entry points manifest file\n"); | |
| 726 return nullptr; | |
| 727 } | |
| 728 | |
| 729 // Parse the file once but don't store the results. This is done to first | |
| 730 // determine the number of entries in the manifest | |
| 731 int64_t entry_count = ParseEntryPointsManifestLines(file, nullptr); | |
| 732 | |
| 733 if (entry_count <= 0) { | |
| 734 Log::PrintErr("Manifest file specified is invalid or contained no entries"); | |
| 735 fclose(file); | |
| 736 return nullptr; | |
| 737 } | |
| 738 | |
| 739 rewind(file); | |
| 740 | |
| 741 // Allocate enough storage for the entries in the file plus a termination | |
| 742 // sentinel and parse it again to populate the allocation | |
| 743 Dart_QualifiedFunctionName* entries = | |
| 744 reinterpret_cast<Dart_QualifiedFunctionName*>( | |
| 745 calloc(entry_count + 1, sizeof(Dart_QualifiedFunctionName))); | |
| 746 | |
| 747 int64_t parsed_entry_count = ParseEntryPointsManifestLines(file, entries); | |
| 748 | |
| 749 if (parsed_entry_count != entry_count) { | |
|
Cutch
2015/10/21 22:00:08
You're calling the same function twice with the sa
Chinmay
2015/10/22 00:13:17
Was being paranoid since I am reading from a file
| |
| 750 free(entries); | |
|
Cutch
2015/10/21 22:00:08
This leaks pointers inside of |entries|. Call Clea
Chinmay
2015/10/22 00:13:17
ack. Removed by the assert.
| |
| 751 fclose(file); | |
| 752 return nullptr; | |
| 753 } | |
| 754 | |
| 755 fclose(file); | |
| 756 | |
| 757 // The entries allocation must be explicitly cleaned up via | |
| 758 // |CleanupEntryPointsCollection| | |
| 759 return entries; | |
| 760 } | |
| 761 | |
| 762 | |
| 763 static Dart_QualifiedFunctionName* ParseEntryPointsManifestIfPresent() { | |
| 764 Dart_QualifiedFunctionName* entries = | |
| 765 ParseEntryPointsManifestFile(vm_entry_points_manifest); | |
| 766 if (entries == nullptr && IsSnapshottingForPrecompilation()) { | |
|
Cutch
2015/10/21 22:00:08
s/nullptr/NULL here and elsewhere
Chinmay
2015/10/22 00:13:16
ack
| |
| 767 Log::PrintErr( | |
| 768 "Could not find native VM entry points during precompilation"); | |
| 769 exit(255); | |
| 770 } | |
| 771 return entries; | |
| 772 } | |
| 773 | |
| 774 | |
| 775 void CleanupEntryPointsCollection(Dart_QualifiedFunctionName* entries) { | |
| 776 if (entries == nullptr) { | |
| 777 return; | |
| 778 } | |
| 779 | |
| 780 size_t index = 0; | |
| 781 while (true) { | |
| 782 Dart_QualifiedFunctionName entry = entries[index++]; | |
| 783 if (entry.library_uri == nullptr) { | |
|
Cutch
2015/10/21 22:00:08
s/nullptr/NULL here and elsewhere
Chinmay
2015/10/22 00:13:16
ack
| |
| 784 break; | |
| 785 } | |
| 786 free((char*)entry.library_uri); | |
|
Cutch
2015/10/21 22:00:08
use c++ casts
Chinmay
2015/10/22 00:13:17
ack
| |
| 787 free((char*)entry.class_name); | |
| 788 free((char*)entry.function_name); | |
| 789 } | |
| 790 free(entries); | |
| 791 } | |
| 792 | |
| 793 | |
| 459 static void CreateAndWriteSnapshot() { | 794 static void CreateAndWriteSnapshot() { |
| 460 Dart_Handle result; | 795 Dart_Handle result; |
| 461 uint8_t* vm_isolate_buffer = NULL; | 796 uint8_t* vm_isolate_buffer = NULL; |
| 462 intptr_t vm_isolate_size = 0; | 797 intptr_t vm_isolate_size = 0; |
| 463 uint8_t* isolate_buffer = NULL; | 798 uint8_t* isolate_buffer = NULL; |
| 464 intptr_t isolate_size = 0; | 799 intptr_t isolate_size = 0; |
| 465 | 800 |
| 466 // First create a snapshot. | 801 // First create a snapshot. |
| 467 result = Dart_CreateSnapshot(&vm_isolate_buffer, | 802 result = Dart_CreateSnapshot(&vm_isolate_buffer, |
| 468 &vm_isolate_size, | 803 &vm_isolate_size, |
| 469 &isolate_buffer, | 804 &isolate_buffer, |
| 470 &isolate_size); | 805 &isolate_size); |
| 471 CHECK_RESULT(result); | 806 CHECK_RESULT(result); |
| 472 | 807 |
| 473 // Now write the vm isolate and isolate snapshots out to the | 808 // Now write the vm isolate and isolate snapshots out to the |
| 474 // specified file and exit. | 809 // specified file and exit. |
| 475 WriteSnapshotFile(vm_isolate_snapshot_filename, | 810 WriteSnapshotFile(vm_isolate_snapshot_filename, |
| 476 vm_isolate_buffer, | 811 vm_isolate_buffer, |
| 477 vm_isolate_size); | 812 vm_isolate_size); |
| 478 WriteSnapshotFile(isolate_snapshot_filename, | 813 WriteSnapshotFile(isolate_snapshot_filename, |
| 479 isolate_buffer, | 814 isolate_buffer, |
| 480 isolate_size); | 815 isolate_size); |
| 481 Dart_ExitScope(); | 816 Dart_ExitScope(); |
| 482 | 817 |
| 483 // Shutdown the isolate. | 818 // Shutdown the isolate. |
| 484 Dart_ShutdownIsolate(); | 819 Dart_ShutdownIsolate(); |
| 485 } | 820 } |
| 486 | 821 |
| 487 | 822 |
| 823 static void CreateAndWritePrecompiledSnapshot( | |
| 824 Dart_QualifiedFunctionName* standalone_entry_points) { | |
| 825 | |
| 826 if (standalone_entry_points == nullptr) { | |
|
Cutch
2015/10/21 22:00:08
Can you hoist this out or rename it? It's confusin
Chinmay
2015/10/22 00:13:16
ack
| |
| 827 ASSERT(!IsSnapshottingForPrecompilation()); | |
| 828 CreateAndWriteSnapshot(); | |
| 829 return; | |
| 830 } | |
| 831 | |
| 832 Dart_Handle result; | |
| 833 uint8_t* vm_isolate_buffer = NULL; | |
| 834 intptr_t vm_isolate_size = 0; | |
| 835 uint8_t* isolate_buffer = NULL; | |
| 836 intptr_t isolate_size = 0; | |
| 837 uint8_t* instructions_buffer = NULL; | |
| 838 intptr_t instructions_size = 0; | |
| 839 | |
| 840 // Precompile with specified VM entry points | |
| 841 result = Dart_Precompile(standalone_entry_points, true); | |
| 842 CHECK_RESULT(result); | |
| 843 | |
| 844 // Create a precompiled snapshot. This gives us an instruction buffer with | |
| 845 // machine code | |
| 846 result = Dart_CreatePrecompiledSnapshot(&vm_isolate_buffer, | |
| 847 &vm_isolate_size, | |
| 848 &isolate_buffer, | |
| 849 &isolate_size, | |
| 850 &instructions_buffer, | |
| 851 &instructions_size); | |
| 852 CHECK_RESULT(result); | |
| 853 | |
| 854 // Now write the vm isolate, isolate and instructions snapshots out to the | |
| 855 // specified files and exit. | |
| 856 WriteSnapshotFile(vm_isolate_snapshot_filename, | |
| 857 vm_isolate_buffer, | |
| 858 vm_isolate_size); | |
| 859 WriteSnapshotFile(isolate_snapshot_filename, | |
| 860 isolate_buffer, | |
| 861 isolate_size); | |
| 862 WriteSnapshotFile(instructions_snapshot_filename, | |
| 863 instructions_buffer, | |
| 864 instructions_size); | |
| 865 Dart_ExitScope(); | |
| 866 | |
| 867 // Shutdown the isolate. | |
| 868 Dart_ShutdownIsolate(); | |
| 869 } | |
| 870 | |
| 871 | |
| 488 static void SetupForUriResolution() { | 872 static void SetupForUriResolution() { |
| 489 // Set up the library tag handler for this isolate. | 873 // Set up the library tag handler for this isolate. |
| 490 Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler); | 874 Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler); |
| 491 if (Dart_IsError(result)) { | 875 if (Dart_IsError(result)) { |
| 492 Log::PrintErr("%s", Dart_GetError(result)); | 876 Log::PrintErr("%s", Dart_GetError(result)); |
| 493 Dart_ExitScope(); | 877 Dart_ExitScope(); |
| 494 Dart_ShutdownIsolate(); | 878 Dart_ShutdownIsolate(); |
| 495 exit(255); | 879 exit(255); |
| 496 } | 880 } |
| 497 // This is a generic dart snapshot which needs builtin library setup. | 881 // This is a generic dart snapshot which needs builtin library setup. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 582 | 966 |
| 583 Thread::InitOnce(); | 967 Thread::InitOnce(); |
| 584 DartUtils::SetOriginalWorkingDirectory(); | 968 DartUtils::SetOriginalWorkingDirectory(); |
| 585 // Start event handler. | 969 // Start event handler. |
| 586 EventHandler::Start(); | 970 EventHandler::Start(); |
| 587 | 971 |
| 588 vm_options.AddArgument("--load_deferred_eagerly"); | 972 vm_options.AddArgument("--load_deferred_eagerly"); |
| 589 // Workaround until issue 21620 is fixed. | 973 // Workaround until issue 21620 is fixed. |
| 590 // (https://github.com/dart-lang/sdk/issues/21620) | 974 // (https://github.com/dart-lang/sdk/issues/21620) |
| 591 vm_options.AddArgument("--no-concurrent_sweep"); | 975 vm_options.AddArgument("--no-concurrent_sweep"); |
| 976 | |
| 977 if (IsSnapshottingForPrecompilation()) { | |
| 978 vm_options.AddArgument("--precompilation"); | |
| 979 vm_options.AddArgument("--write_protect_code=false"); | |
|
rmacnak
2015/10/21 23:06:18
--write_protect_code=false should be unnecessary n
Chinmay
2015/10/22 00:13:16
ack
| |
| 980 } | |
| 981 | |
| 592 Dart_SetVMFlags(vm_options.count(), vm_options.arguments()); | 982 Dart_SetVMFlags(vm_options.count(), vm_options.arguments()); |
| 593 | 983 |
| 594 // Initialize the Dart VM. | 984 // Initialize the Dart VM. |
| 595 // Note: We don't expect isolates to be created from dart code during | 985 // Note: We don't expect isolates to be created from dart code during |
| 596 // snapshot generation. | 986 // snapshot generation. |
| 597 char* error = Dart_Initialize( | 987 char* error = Dart_Initialize( |
| 598 NULL, | 988 NULL, |
| 599 NULL, | 989 NULL, |
| 600 CreateServiceIsolate, | 990 CreateServiceIsolate, |
| 601 NULL, | 991 NULL, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 665 fprintf(stderr, "%s", error); | 1055 fprintf(stderr, "%s", error); |
| 666 free(error); | 1056 free(error); |
| 667 exit(255); | 1057 exit(255); |
| 668 } | 1058 } |
| 669 Dart_EnterScope(); | 1059 Dart_EnterScope(); |
| 670 | 1060 |
| 671 // Set up the library tag handler in such a manner that it will use the | 1061 // Set up the library tag handler in such a manner that it will use the |
| 672 // URL mapping specified on the command line to load the libraries. | 1062 // URL mapping specified on the command line to load the libraries. |
| 673 result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler); | 1063 result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler); |
| 674 CHECK_RESULT(result); | 1064 CHECK_RESULT(result); |
| 1065 | |
| 1066 Dart_QualifiedFunctionName* entry_points = | |
| 1067 ParseEntryPointsManifestIfPresent(); | |
| 1068 | |
| 1069 SetupStubNativeResolversForPrecompilation(entry_points); | |
| 1070 | |
| 675 // Load the specified script. | 1071 // Load the specified script. |
| 676 library = LoadSnapshotCreationScript(app_script_name); | 1072 library = LoadSnapshotCreationScript(app_script_name); |
| 677 VerifyLoaded(library); | 1073 VerifyLoaded(library); |
| 1074 | |
| 1075 ImportNativeEntryPointLibrariesIntoRoot(entry_points); | |
| 1076 | |
| 678 // Ensure that we mark all libraries as loaded. | 1077 // Ensure that we mark all libraries as loaded. |
| 679 result = Dart_FinalizeLoading(false); | 1078 result = Dart_FinalizeLoading(false); |
| 680 CHECK_RESULT(result); | 1079 CHECK_RESULT(result); |
| 681 CreateAndWriteSnapshot(); | 1080 CreateAndWritePrecompiledSnapshot(entry_points); |
| 1081 | |
| 1082 CleanupEntryPointsCollection(entry_points); | |
| 682 | 1083 |
| 683 Dart_EnterIsolate(UriResolverIsolateScope::isolate); | 1084 Dart_EnterIsolate(UriResolverIsolateScope::isolate); |
| 684 Dart_ShutdownIsolate(); | 1085 Dart_ShutdownIsolate(); |
| 685 } else { | 1086 } else { |
| 686 SetupForGenericSnapshotCreation(); | 1087 SetupForGenericSnapshotCreation(); |
| 687 CreateAndWriteSnapshot(); | 1088 CreateAndWriteSnapshot(); |
| 688 } | 1089 } |
| 689 EventHandler::Stop(); | 1090 EventHandler::Stop(); |
| 690 return 0; | 1091 return 0; |
| 691 } | 1092 } |
| 692 | 1093 |
| 693 } // namespace bin | 1094 } // namespace bin |
| 694 } // namespace dart | 1095 } // namespace dart |
| 695 | 1096 |
| 696 int main(int argc, char** argv) { | 1097 int main(int argc, char** argv) { |
| 697 return dart::bin::main(argc, argv); | 1098 return dart::bin::main(argc, argv); |
| 698 } | 1099 } |
| OLD | NEW |