| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 #include <stdlib.h> | 5 #include <stdlib.h> |
| 6 #include <string.h> | 6 #include <string.h> |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 | 8 |
| 9 #include "include/dart_api.h" | 9 #include "include/dart_api.h" |
| 10 #include "include/dart_tools_api.h" | 10 #include "include/dart_tools_api.h" |
| 11 | 11 |
| 12 #include "bin/builtin.h" | 12 #include "bin/builtin.h" |
| 13 #include "bin/dartutils.h" | 13 #include "bin/dartutils.h" |
| 14 #include "bin/directory.h" | 14 #include "bin/directory.h" |
| 15 #include "bin/embedded_dart_io.h" | 15 #include "bin/embedded_dart_io.h" |
| 16 #include "bin/eventhandler.h" | 16 #include "bin/eventhandler.h" |
| 17 #include "bin/exit.h" |
| 17 #include "bin/extensions.h" | 18 #include "bin/extensions.h" |
| 18 #include "bin/file.h" | 19 #include "bin/file.h" |
| 19 #include "bin/isolate_data.h" | 20 #include "bin/isolate_data.h" |
| 20 #include "bin/loader.h" | 21 #include "bin/loader.h" |
| 21 #include "bin/log.h" | 22 #include "bin/log.h" |
| 22 #include "bin/platform.h" | 23 #include "bin/platform.h" |
| 23 #include "bin/process.h" | 24 #include "bin/process.h" |
| 25 #include "bin/snapshot.h" |
| 24 #include "bin/thread.h" | 26 #include "bin/thread.h" |
| 25 #include "bin/utils.h" | 27 #include "bin/utils.h" |
| 26 #include "bin/vmservice_impl.h" | 28 #include "bin/vmservice_impl.h" |
| 27 #include "platform/globals.h" | 29 #include "platform/globals.h" |
| 28 #include "platform/hashmap.h" | 30 #include "platform/hashmap.h" |
| 29 #include "platform/text_buffer.h" | 31 #include "platform/text_buffer.h" |
| 30 #if !defined(DART_PRECOMPILER) | 32 #if !defined(DART_PRECOMPILER) |
| 31 #include "zlib/zlib.h" | 33 #include "zlib/zlib.h" |
| 32 #endif | 34 #endif |
| 33 | 35 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 // dart functions and not run anything. | 90 // dart functions and not run anything. |
| 89 static bool compile_all = false; | 91 static bool compile_all = false; |
| 90 static bool parse_all = false; | 92 static bool parse_all = false; |
| 91 | 93 |
| 92 | 94 |
| 93 // Global flag that is used to indicate that we want to use blobs/mmap instead | 95 // Global flag that is used to indicate that we want to use blobs/mmap instead |
| 94 // of assembly/shared libraries for precompilation. | 96 // of assembly/shared libraries for precompilation. |
| 95 static bool use_blobs = false; | 97 static bool use_blobs = false; |
| 96 | 98 |
| 97 | 99 |
| 98 extern const char* kVmSnapshotDataSymbolName; | |
| 99 extern const char* kVmSnapshotInstructionsSymbolName; | |
| 100 extern const char* kIsolateSnapshotDataSymbolName; | |
| 101 extern const char* kIsolateSnapshotInstructionsSymbolName; | |
| 102 | |
| 103 | |
| 104 // Global flag that is used to indicate that we want to trace resolution of | 100 // Global flag that is used to indicate that we want to trace resolution of |
| 105 // URIs and the loading of libraries, parts and scripts. | 101 // URIs and the loading of libraries, parts and scripts. |
| 106 static bool trace_loading = false; | 102 static bool trace_loading = false; |
| 107 | 103 |
| 108 | 104 |
| 109 static char* app_script_uri = NULL; | 105 static char* app_script_uri = NULL; |
| 110 static const uint8_t* app_isolate_snapshot_data = NULL; | 106 static const uint8_t* app_isolate_snapshot_data = NULL; |
| 111 static const uint8_t* app_isolate_snapshot_instructions = NULL; | 107 static const uint8_t* app_isolate_snapshot_instructions = NULL; |
| 112 | 108 |
| 113 | 109 |
| 114 static Dart_Isolate main_isolate = NULL; | 110 static Dart_Isolate main_isolate = NULL; |
| 115 | 111 |
| 116 | 112 |
| 117 static const char* DEFAULT_VM_SERVICE_SERVER_IP = "localhost"; | 113 static const char* DEFAULT_VM_SERVICE_SERVER_IP = "localhost"; |
| 118 static const int DEFAULT_VM_SERVICE_SERVER_PORT = 8181; | 114 static const int DEFAULT_VM_SERVICE_SERVER_PORT = 8181; |
| 119 // VM Service options. | 115 // VM Service options. |
| 120 static const char* vm_service_server_ip = DEFAULT_VM_SERVICE_SERVER_IP; | 116 static const char* vm_service_server_ip = DEFAULT_VM_SERVICE_SERVER_IP; |
| 121 // The 0 port is a magic value which results in the first available port | 117 // The 0 port is a magic value which results in the first available port |
| 122 // being allocated. | 118 // being allocated. |
| 123 static int vm_service_server_port = -1; | 119 static int vm_service_server_port = -1; |
| 124 // True when we are running in development mode and cross origin security | 120 // True when we are running in development mode and cross origin security |
| 125 // checks are disabled. | 121 // checks are disabled. |
| 126 static bool vm_service_dev_mode = false; | 122 static bool vm_service_dev_mode = false; |
| 127 | 123 |
| 128 // Exit code indicating an internal Dart Frontend error. | |
| 129 static const int kDartFrontendErrorExitCode = 252; | |
| 130 // Exit code indicating an API error. | |
| 131 static const int kApiErrorExitCode = 253; | |
| 132 // Exit code indicating a compilation error. | |
| 133 static const int kCompilationErrorExitCode = 254; | |
| 134 // Exit code indicating an unhandled error that is not a compilation error. | |
| 135 static const int kErrorExitCode = 255; | |
| 136 // Exit code indicating a vm restart request. Never returned to the user. | |
| 137 static const int kRestartRequestExitCode = 1000; | |
| 138 | |
| 139 static void ErrorExit(int exit_code, const char* format, ...) { | |
| 140 va_list arguments; | |
| 141 va_start(arguments, format); | |
| 142 Log::VPrintErr(format, arguments); | |
| 143 va_end(arguments); | |
| 144 | |
| 145 Dart_ExitScope(); | |
| 146 Dart_ShutdownIsolate(); | |
| 147 | |
| 148 // Terminate process exit-code handler. | |
| 149 Process::TerminateExitCodeHandler(); | |
| 150 | |
| 151 char* error = Dart_Cleanup(); | |
| 152 if (error != NULL) { | |
| 153 Log::PrintErr("VM cleanup failed: %s\n", error); | |
| 154 free(error); | |
| 155 } | |
| 156 | |
| 157 EventHandler::Stop(); | |
| 158 Platform::Exit(exit_code); | |
| 159 } | |
| 160 | |
| 161 | 124 |
| 162 // The environment provided through the command line using -D options. | 125 // The environment provided through the command line using -D options. |
| 163 static dart::HashMap* environment = NULL; | 126 static dart::HashMap* environment = NULL; |
| 164 | 127 |
| 165 static bool IsValidFlag(const char* name, | 128 static bool IsValidFlag(const char* name, |
| 166 const char* prefix, | 129 const char* prefix, |
| 167 intptr_t prefix_length) { | 130 intptr_t prefix_length) { |
| 168 intptr_t name_length = strlen(name); | 131 intptr_t name_length = strlen(name); |
| 169 return ((name_length > prefix_length) && | 132 return ((name_length > prefix_length) && |
| 170 (strncmp(name, prefix, prefix_length) == 0)); | 133 (strncmp(name, prefix, prefix_length) == 0)); |
| (...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 *exit_code = kRestartRequestExitCode; \ | 764 *exit_code = kRestartRequestExitCode; \ |
| 802 } else { \ | 765 } else { \ |
| 803 *exit_code = kErrorExitCode; \ | 766 *exit_code = kErrorExitCode; \ |
| 804 } \ | 767 } \ |
| 805 Dart_ExitScope(); \ | 768 Dart_ExitScope(); \ |
| 806 Dart_ShutdownIsolate(); \ | 769 Dart_ShutdownIsolate(); \ |
| 807 return NULL; \ | 770 return NULL; \ |
| 808 } | 771 } |
| 809 | 772 |
| 810 | 773 |
| 811 static void SnapshotOnExitHook(int64_t exit_code); | 774 static void SnapshotOnExitHook(int64_t exit_code) { |
| 812 | 775 if (Dart_CurrentIsolate() != main_isolate) { |
| 813 | 776 Log::PrintErr( |
| 814 static const int64_t kAppSnapshotHeaderSize = 5 * kInt64Size; | 777 "A snapshot was requested, but a secondary isolate " |
| 815 static const int64_t kAppSnapshotMagicNumber = 0xf6f6dcdc; | 778 "performed a hard exit (%" Pd64 ").\n", |
| 816 static const int64_t kAppSnapshotPageSize = 4 * KB; | 779 exit_code); |
| 817 | |
| 818 | |
| 819 static bool ReadAppSnapshotBlobs(const char* script_name, | |
| 820 const uint8_t** vm_data_buffer, | |
| 821 const uint8_t** vm_instructions_buffer, | |
| 822 const uint8_t** isolate_data_buffer, | |
| 823 const uint8_t** isolate_instructions_buffer) { | |
| 824 File* file = File::Open(script_name, File::kRead); | |
| 825 if (file == NULL) { | |
| 826 return false; | |
| 827 } | |
| 828 if (file->Length() < kAppSnapshotHeaderSize) { | |
| 829 file->Release(); | |
| 830 return false; | |
| 831 } | |
| 832 int64_t header[5]; | |
| 833 ASSERT(sizeof(header) == kAppSnapshotHeaderSize); | |
| 834 if (!file->ReadFully(&header, kAppSnapshotHeaderSize)) { | |
| 835 file->Release(); | |
| 836 return false; | |
| 837 } | |
| 838 if (header[0] != kAppSnapshotMagicNumber) { | |
| 839 file->Release(); | |
| 840 return false; | |
| 841 } | |
| 842 | |
| 843 int64_t vm_data_size = header[1]; | |
| 844 int64_t vm_data_position = | |
| 845 Utils::RoundUp(file->Position(), kAppSnapshotPageSize); | |
| 846 int64_t vm_instructions_size = header[2]; | |
| 847 int64_t vm_instructions_position = vm_data_position + vm_data_size; | |
| 848 if (vm_instructions_size != 0) { | |
| 849 vm_instructions_position = | |
| 850 Utils::RoundUp(vm_instructions_position, kAppSnapshotPageSize); | |
| 851 } | |
| 852 int64_t isolate_data_size = header[3]; | |
| 853 int64_t isolate_data_position = Utils::RoundUp( | |
| 854 vm_instructions_position + vm_instructions_size, kAppSnapshotPageSize); | |
| 855 int64_t isolate_instructions_size = header[4]; | |
| 856 int64_t isolate_instructions_position = | |
| 857 isolate_data_position + isolate_data_size; | |
| 858 if (isolate_instructions_size != 0) { | |
| 859 isolate_instructions_position = | |
| 860 Utils::RoundUp(isolate_instructions_position, kAppSnapshotPageSize); | |
| 861 } | |
| 862 | |
| 863 if (vm_data_size != 0) { | |
| 864 *vm_data_buffer = reinterpret_cast<const uint8_t*>( | |
| 865 file->Map(File::kReadOnly, vm_data_position, vm_data_size)); | |
| 866 if (vm_data_buffer == NULL) { | |
| 867 Log::PrintErr("Failed to memory map snapshot\n"); | |
| 868 Platform::Exit(kErrorExitCode); | |
| 869 } | |
| 870 } | |
| 871 | |
| 872 if (vm_instructions_size != 0) { | |
| 873 *vm_instructions_buffer = reinterpret_cast<const uint8_t*>(file->Map( | |
| 874 File::kReadExecute, vm_instructions_position, vm_instructions_size)); | |
| 875 if (*vm_instructions_buffer == NULL) { | |
| 876 Log::PrintErr("Failed to memory map snapshot\n"); | |
| 877 Platform::Exit(kErrorExitCode); | |
| 878 } | |
| 879 } | |
| 880 | |
| 881 *isolate_data_buffer = reinterpret_cast<const uint8_t*>( | |
| 882 file->Map(File::kReadOnly, isolate_data_position, isolate_data_size)); | |
| 883 if (isolate_data_buffer == NULL) { | |
| 884 Log::PrintErr("Failed to memory map snapshot\n"); | |
| 885 Platform::Exit(kErrorExitCode); | 780 Platform::Exit(kErrorExitCode); |
| 886 } | 781 } |
| 887 | 782 if (exit_code == 0) { |
| 888 if (isolate_instructions_size == 0) { | 783 Snapshot::GenerateAppJIT(snapshot_filename); |
| 889 *isolate_instructions_buffer = NULL; | |
| 890 } else { | |
| 891 *isolate_instructions_buffer = reinterpret_cast<const uint8_t*>( | |
| 892 file->Map(File::kReadExecute, isolate_instructions_position, | |
| 893 isolate_instructions_size)); | |
| 894 if (*isolate_instructions_buffer == NULL) { | |
| 895 Log::PrintErr("Failed to memory map snapshot\n"); | |
| 896 Platform::Exit(kErrorExitCode); | |
| 897 } | |
| 898 } | 784 } |
| 899 | |
| 900 file->Release(); | |
| 901 return true; | |
| 902 } | 785 } |
| 903 | 786 |
| 904 | 787 |
| 905 #if defined(DART_PRECOMPILED_RUNTIME) | |
| 906 static bool ReadAppSnapshotDynamicLibrary( | |
| 907 const char* script_name, | |
| 908 const uint8_t** vm_data_buffer, | |
| 909 const uint8_t** vm_instructions_buffer, | |
| 910 const uint8_t** isolate_data_buffer, | |
| 911 const uint8_t** isolate_instructions_buffer) { | |
| 912 void* library = Extensions::LoadExtensionLibrary(script_name); | |
| 913 if (library == NULL) { | |
| 914 return false; | |
| 915 } | |
| 916 | |
| 917 *vm_data_buffer = reinterpret_cast<const uint8_t*>( | |
| 918 Extensions::ResolveSymbol(library, kVmSnapshotDataSymbolName)); | |
| 919 if (*vm_data_buffer == NULL) { | |
| 920 Log::PrintErr("Failed to resolve symbol '%s'\n", kVmSnapshotDataSymbolName); | |
| 921 Platform::Exit(kErrorExitCode); | |
| 922 } | |
| 923 | |
| 924 *vm_instructions_buffer = reinterpret_cast<const uint8_t*>( | |
| 925 Extensions::ResolveSymbol(library, kVmSnapshotInstructionsSymbolName)); | |
| 926 if (*vm_instructions_buffer == NULL) { | |
| 927 Log::PrintErr("Failed to resolve symbol '%s'\n", | |
| 928 kVmSnapshotInstructionsSymbolName); | |
| 929 Platform::Exit(kErrorExitCode); | |
| 930 } | |
| 931 | |
| 932 *isolate_data_buffer = reinterpret_cast<const uint8_t*>( | |
| 933 Extensions::ResolveSymbol(library, kIsolateSnapshotDataSymbolName)); | |
| 934 if (*isolate_data_buffer == NULL) { | |
| 935 Log::PrintErr("Failed to resolve symbol '%s'\n", | |
| 936 kIsolateSnapshotDataSymbolName); | |
| 937 Platform::Exit(kErrorExitCode); | |
| 938 } | |
| 939 | |
| 940 *isolate_instructions_buffer = | |
| 941 reinterpret_cast<const uint8_t*>(Extensions::ResolveSymbol( | |
| 942 library, kIsolateSnapshotInstructionsSymbolName)); | |
| 943 if (*isolate_instructions_buffer == NULL) { | |
| 944 Log::PrintErr("Failed to resolve symbol '%s'\n", | |
| 945 kIsolateSnapshotInstructionsSymbolName); | |
| 946 Platform::Exit(kErrorExitCode); | |
| 947 } | |
| 948 | |
| 949 return true; | |
| 950 } | |
| 951 #endif // defined(DART_PRECOMPILED_RUNTIME) | |
| 952 | |
| 953 | |
| 954 static bool ReadAppSnapshot(const char* script_name, | |
| 955 const uint8_t** vm_data_buffer, | |
| 956 const uint8_t** vm_instructions_buffer, | |
| 957 const uint8_t** isolate_data_buffer, | |
| 958 const uint8_t** isolate_instructions_buffer) { | |
| 959 if (File::GetType(script_name, true) != File::kIsFile) { | |
| 960 // If 'script_name' refers to a pipe, don't read to check for an app | |
| 961 // snapshot since we cannot rewind if it isn't (and couldn't mmap it in | |
| 962 // anyway if it was). | |
| 963 return false; | |
| 964 } | |
| 965 if (ReadAppSnapshotBlobs(script_name, vm_data_buffer, vm_instructions_buffer, | |
| 966 isolate_data_buffer, isolate_instructions_buffer)) { | |
| 967 return true; | |
| 968 } | |
| 969 #if defined(DART_PRECOMPILED_RUNTIME) | |
| 970 // For testing AOT with the standalone embedder, we also support loading | |
| 971 // from a dynamic library to simulate what happens on iOS. | |
| 972 return ReadAppSnapshotDynamicLibrary( | |
| 973 script_name, vm_data_buffer, vm_instructions_buffer, isolate_data_buffer, | |
| 974 isolate_instructions_buffer); | |
| 975 #else | |
| 976 return false; | |
| 977 #endif // defined(DART_PRECOMPILED_RUNTIME) | |
| 978 } | |
| 979 | |
| 980 | |
| 981 // Returns newly created Isolate on success, NULL on failure. | 788 // Returns newly created Isolate on success, NULL on failure. |
| 982 static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate, | 789 static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate, |
| 983 const char* script_uri, | 790 const char* script_uri, |
| 984 const char* main, | 791 const char* main, |
| 985 const char* package_root, | 792 const char* package_root, |
| 986 const char* packages_config, | 793 const char* packages_config, |
| 987 Dart_IsolateFlags* flags, | 794 Dart_IsolateFlags* flags, |
| 988 char** error, | 795 char** error, |
| 989 int* exit_code) { | 796 int* exit_code) { |
| 990 ASSERT(script_uri != NULL); | 797 ASSERT(script_uri != NULL); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1020 (is_main_isolate || ((app_script_uri != NULL) && | 827 (is_main_isolate || ((app_script_uri != NULL) && |
| 1021 (strcmp(script_uri, app_script_uri) == 0)))) { | 828 (strcmp(script_uri, app_script_uri) == 0)))) { |
| 1022 isolate_run_app_snapshot = true; | 829 isolate_run_app_snapshot = true; |
| 1023 isolate_snapshot_data = app_isolate_snapshot_data; | 830 isolate_snapshot_data = app_isolate_snapshot_data; |
| 1024 isolate_snapshot_instructions = app_isolate_snapshot_instructions; | 831 isolate_snapshot_instructions = app_isolate_snapshot_instructions; |
| 1025 } else if (!is_main_isolate) { | 832 } else if (!is_main_isolate) { |
| 1026 const uint8_t* file_vm_snapshot_data = NULL; | 833 const uint8_t* file_vm_snapshot_data = NULL; |
| 1027 const uint8_t* file_vm_snapshot_instructions = NULL; | 834 const uint8_t* file_vm_snapshot_instructions = NULL; |
| 1028 const uint8_t* file_isolate_snapshot_data = NULL; | 835 const uint8_t* file_isolate_snapshot_data = NULL; |
| 1029 const uint8_t* file_isolate_snapshot_instructions = NULL; | 836 const uint8_t* file_isolate_snapshot_instructions = NULL; |
| 1030 if (ReadAppSnapshot( | 837 if (Snapshot::ReadAppSnapshot( |
| 1031 script_uri, &file_vm_snapshot_data, &file_vm_snapshot_instructions, | 838 script_uri, &file_vm_snapshot_data, &file_vm_snapshot_instructions, |
| 1032 &file_isolate_snapshot_data, &file_isolate_snapshot_instructions)) { | 839 &file_isolate_snapshot_data, &file_isolate_snapshot_instructions)) { |
| 1033 // TODO(rmacnak): We are leaking the snapshot when the isolate shuts down. | 840 // TODO(rmacnak): We are leaking the snapshot when the isolate shuts down. |
| 1034 isolate_run_app_snapshot = true; | 841 isolate_run_app_snapshot = true; |
| 1035 isolate_snapshot_data = file_isolate_snapshot_data; | 842 isolate_snapshot_data = file_isolate_snapshot_data; |
| 1036 isolate_snapshot_instructions = file_isolate_snapshot_instructions; | 843 isolate_snapshot_instructions = file_isolate_snapshot_instructions; |
| 1037 } | 844 } |
| 1038 } | 845 } |
| 1039 #endif | 846 #endif |
| 1040 | 847 |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1455 int64_t data[File::kStatSize]; | 1262 int64_t data[File::kStatSize]; |
| 1456 File::Stat(url + 7, data); | 1263 File::Stat(url + 7, data); |
| 1457 if (data[File::kType] == File::kDoesNotExist) { | 1264 if (data[File::kType] == File::kDoesNotExist) { |
| 1458 return true; | 1265 return true; |
| 1459 } | 1266 } |
| 1460 bool modified = data[File::kModifiedTime] > since; | 1267 bool modified = data[File::kModifiedTime] > since; |
| 1461 return modified; | 1268 return modified; |
| 1462 } | 1269 } |
| 1463 | 1270 |
| 1464 | 1271 |
| 1465 static void WriteSnapshotFile(const char* filename, | |
| 1466 bool write_magic_number, | |
| 1467 const uint8_t* buffer, | |
| 1468 const intptr_t size) { | |
| 1469 char* concat = NULL; | |
| 1470 File* file = File::Open(filename, File::kWriteTruncate); | |
| 1471 if (file == NULL) { | |
| 1472 ErrorExit(kErrorExitCode, "Unable to open file %s for writing snapshot\n", | |
| 1473 filename); | |
| 1474 } | |
| 1475 | |
| 1476 if (write_magic_number) { | |
| 1477 // Write the magic number to indicate file is a script snapshot. | |
| 1478 DartUtils::WriteMagicNumber(file); | |
| 1479 } | |
| 1480 | |
| 1481 if (!file->WriteFully(buffer, size)) { | |
| 1482 ErrorExit(kErrorExitCode, "Unable to write file %s for writing snapshot\n", | |
| 1483 filename); | |
| 1484 } | |
| 1485 file->Release(); | |
| 1486 if (concat != NULL) { | |
| 1487 delete concat; | |
| 1488 } | |
| 1489 } | |
| 1490 | |
| 1491 | |
| 1492 static bool WriteInt64(File* file, int64_t size) { | |
| 1493 return file->WriteFully(&size, sizeof(size)); | |
| 1494 } | |
| 1495 | |
| 1496 | |
| 1497 static void WriteAppSnapshot(const char* filename, | |
| 1498 uint8_t* vm_data_buffer, | |
| 1499 intptr_t vm_data_size, | |
| 1500 uint8_t* vm_instructions_buffer, | |
| 1501 intptr_t vm_instructions_size, | |
| 1502 uint8_t* isolate_data_buffer, | |
| 1503 intptr_t isolate_data_size, | |
| 1504 uint8_t* isolate_instructions_buffer, | |
| 1505 intptr_t isolate_instructions_size) { | |
| 1506 File* file = File::Open(filename, File::kWriteTruncate); | |
| 1507 if (file == NULL) { | |
| 1508 ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename); | |
| 1509 } | |
| 1510 | |
| 1511 file->WriteFully(&kAppSnapshotMagicNumber, sizeof(kAppSnapshotMagicNumber)); | |
| 1512 WriteInt64(file, vm_data_size); | |
| 1513 WriteInt64(file, vm_instructions_size); | |
| 1514 WriteInt64(file, isolate_data_size); | |
| 1515 WriteInt64(file, isolate_instructions_size); | |
| 1516 ASSERT(file->Position() == kAppSnapshotHeaderSize); | |
| 1517 | |
| 1518 file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize)); | |
| 1519 if (!file->WriteFully(vm_data_buffer, vm_data_size)) { | |
| 1520 ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename); | |
| 1521 } | |
| 1522 | |
| 1523 if (vm_instructions_size != 0) { | |
| 1524 file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize)); | |
| 1525 if (!file->WriteFully(vm_instructions_buffer, vm_instructions_size)) { | |
| 1526 ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", | |
| 1527 filename); | |
| 1528 } | |
| 1529 } | |
| 1530 | |
| 1531 file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize)); | |
| 1532 if (!file->WriteFully(isolate_data_buffer, isolate_data_size)) { | |
| 1533 ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename); | |
| 1534 } | |
| 1535 | |
| 1536 if (isolate_instructions_size != 0) { | |
| 1537 file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize)); | |
| 1538 if (!file->WriteFully(isolate_instructions_buffer, | |
| 1539 isolate_instructions_size)) { | |
| 1540 ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", | |
| 1541 filename); | |
| 1542 } | |
| 1543 } | |
| 1544 | |
| 1545 file->Flush(); | |
| 1546 file->Release(); | |
| 1547 } | |
| 1548 | |
| 1549 | |
| 1550 static void GenerateScriptSnapshot() { | |
| 1551 // First create a snapshot. | |
| 1552 uint8_t* buffer = NULL; | |
| 1553 intptr_t size = 0; | |
| 1554 Dart_Handle result = Dart_CreateScriptSnapshot(&buffer, &size); | |
| 1555 if (Dart_IsError(result)) { | |
| 1556 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result)); | |
| 1557 } | |
| 1558 | |
| 1559 WriteSnapshotFile(snapshot_filename, true, buffer, size); | |
| 1560 } | |
| 1561 | |
| 1562 | |
| 1563 static void GenerateAppAOTSnapshotAsBlobs() { | |
| 1564 uint8_t* vm_data_buffer = NULL; | |
| 1565 intptr_t vm_data_size = 0; | |
| 1566 uint8_t* vm_instructions_buffer = NULL; | |
| 1567 intptr_t vm_instructions_size = 0; | |
| 1568 uint8_t* isolate_data_buffer = NULL; | |
| 1569 intptr_t isolate_data_size = 0; | |
| 1570 uint8_t* isolate_instructions_buffer = NULL; | |
| 1571 intptr_t isolate_instructions_size = 0; | |
| 1572 Dart_Handle result = Dart_CreateAppAOTSnapshotAsBlobs( | |
| 1573 &vm_data_buffer, &vm_data_size, &vm_instructions_buffer, | |
| 1574 &vm_instructions_size, &isolate_data_buffer, &isolate_data_size, | |
| 1575 &isolate_instructions_buffer, &isolate_instructions_size); | |
| 1576 if (Dart_IsError(result)) { | |
| 1577 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result)); | |
| 1578 } | |
| 1579 WriteAppSnapshot(snapshot_filename, vm_data_buffer, vm_data_size, | |
| 1580 vm_instructions_buffer, vm_instructions_size, | |
| 1581 isolate_data_buffer, isolate_data_size, | |
| 1582 isolate_instructions_buffer, isolate_instructions_size); | |
| 1583 } | |
| 1584 | |
| 1585 static void GenerateAppAOTSnapshotAsAssembly() { | |
| 1586 uint8_t* assembly_buffer = NULL; | |
| 1587 intptr_t assembly_size = 0; | |
| 1588 Dart_Handle result = | |
| 1589 Dart_CreateAppAOTSnapshotAsAssembly(&assembly_buffer, &assembly_size); | |
| 1590 if (Dart_IsError(result)) { | |
| 1591 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result)); | |
| 1592 } | |
| 1593 WriteSnapshotFile(snapshot_filename, false, assembly_buffer, assembly_size); | |
| 1594 } | |
| 1595 | |
| 1596 | |
| 1597 static void GenerateAppAOTSnapshot() { | 1272 static void GenerateAppAOTSnapshot() { |
| 1598 if (use_blobs) { | 1273 if (use_blobs) { |
| 1599 GenerateAppAOTSnapshotAsBlobs(); | 1274 Snapshot::GenerateAppAOTAsBlobs(snapshot_filename); |
| 1600 } else { | 1275 } else { |
| 1601 GenerateAppAOTSnapshotAsAssembly(); | 1276 Snapshot::GenerateAppAOTAsAssembly(snapshot_filename); |
| 1602 } | 1277 } |
| 1603 } | 1278 } |
| 1604 | 1279 |
| 1605 | 1280 |
| 1606 static void GenerateAppJITSnapshot() { | |
| 1607 #if defined(TARGET_ARCH_X64) | |
| 1608 uint8_t* isolate_data_buffer = NULL; | |
| 1609 intptr_t isolate_data_size = 0; | |
| 1610 uint8_t* isolate_instructions_buffer = NULL; | |
| 1611 intptr_t isolate_instructions_size = 0; | |
| 1612 Dart_Handle result = Dart_CreateAppJITSnapshotAsBlobs( | |
| 1613 &isolate_data_buffer, &isolate_data_size, &isolate_instructions_buffer, | |
| 1614 &isolate_instructions_size); | |
| 1615 if (Dart_IsError(result)) { | |
| 1616 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result)); | |
| 1617 } | |
| 1618 WriteAppSnapshot(snapshot_filename, NULL, 0, NULL, 0, isolate_data_buffer, | |
| 1619 isolate_data_size, isolate_instructions_buffer, | |
| 1620 isolate_instructions_size); | |
| 1621 #else | |
| 1622 uint8_t* isolate_buffer = NULL; | |
| 1623 intptr_t isolate_size = 0; | |
| 1624 | |
| 1625 Dart_Handle result = | |
| 1626 Dart_CreateSnapshot(NULL, NULL, &isolate_buffer, &isolate_size); | |
| 1627 if (Dart_IsError(result)) { | |
| 1628 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result)); | |
| 1629 } | |
| 1630 | |
| 1631 WriteAppSnapshot(snapshot_filename, NULL, 0, NULL, 0, isolate_buffer, | |
| 1632 isolate_size, NULL, 0); | |
| 1633 #endif // defined(TARGET_ARCH_X64) | |
| 1634 } | |
| 1635 | |
| 1636 | |
| 1637 #define CHECK_RESULT(result) \ | 1281 #define CHECK_RESULT(result) \ |
| 1638 if (Dart_IsError(result)) { \ | 1282 if (Dart_IsError(result)) { \ |
| 1639 if (Dart_IsVMRestartRequest(result)) { \ | 1283 if (Dart_IsVMRestartRequest(result)) { \ |
| 1640 Dart_ExitScope(); \ | 1284 Dart_ExitScope(); \ |
| 1641 Dart_ShutdownIsolate(); \ | 1285 Dart_ShutdownIsolate(); \ |
| 1642 return true; \ | 1286 return true; \ |
| 1643 } \ | 1287 } \ |
| 1644 const int exit_code = Dart_IsCompilationError(result) \ | 1288 const int exit_code = Dart_IsCompilationError(result) \ |
| 1645 ? kCompilationErrorExitCode \ | 1289 ? kCompilationErrorExitCode \ |
| 1646 : kErrorExitCode; \ | 1290 : kErrorExitCode; \ |
| 1647 ErrorExit(exit_code, "%s\n", Dart_GetError(result)); \ | 1291 ErrorExit(exit_code, "%s\n", Dart_GetError(result)); \ |
| 1648 } | 1292 } |
| 1649 | 1293 |
| 1650 | 1294 |
| 1651 static void SnapshotOnExitHook(int64_t exit_code) { | 1295 static void WriteFile(const char* filename, |
| 1652 if (Dart_CurrentIsolate() != main_isolate) { | 1296 const uint8_t* buffer, |
| 1653 Log::PrintErr( | 1297 const intptr_t size) { |
| 1654 "A snapshot was requested, but a secondary isolate " | 1298 File* file = File::Open(filename, File::kWriteTruncate); |
| 1655 "performed a hard exit (%" Pd64 ").\n", | 1299 if (file == NULL) { |
| 1656 exit_code); | 1300 ErrorExit(kErrorExitCode, "Unable to open file %s\n", filename); |
| 1657 Platform::Exit(kErrorExitCode); | |
| 1658 } | 1301 } |
| 1659 if (exit_code == 0) { | 1302 if (!file->WriteFully(buffer, size)) { |
| 1660 GenerateAppJITSnapshot(); | 1303 ErrorExit(kErrorExitCode, "Unable to write file %s\n", filename); |
| 1661 } | 1304 } |
| 1305 file->Release(); |
| 1662 } | 1306 } |
| 1663 | 1307 |
| 1664 | 1308 |
| 1665 bool RunMainIsolate(const char* script_name, CommandLineOptions* dart_options) { | 1309 bool RunMainIsolate(const char* script_name, CommandLineOptions* dart_options) { |
| 1666 // Call CreateIsolateAndSetup which creates an isolate and loads up | 1310 // Call CreateIsolateAndSetup which creates an isolate and loads up |
| 1667 // the specified application script. | 1311 // the specified application script. |
| 1668 char* error = NULL; | 1312 char* error = NULL; |
| 1669 bool is_main_isolate = true; | 1313 bool is_main_isolate = true; |
| 1670 int exit_code = 0; | 1314 int exit_code = 0; |
| 1671 char* isolate_name = BuildIsolateName(script_name, "main"); | 1315 char* isolate_name = BuildIsolateName(script_name, "main"); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1694 delete[] isolate_name; | 1338 delete[] isolate_name; |
| 1695 | 1339 |
| 1696 Dart_EnterIsolate(isolate); | 1340 Dart_EnterIsolate(isolate); |
| 1697 ASSERT(isolate == Dart_CurrentIsolate()); | 1341 ASSERT(isolate == Dart_CurrentIsolate()); |
| 1698 ASSERT(isolate != NULL); | 1342 ASSERT(isolate != NULL); |
| 1699 Dart_Handle result; | 1343 Dart_Handle result; |
| 1700 | 1344 |
| 1701 Dart_EnterScope(); | 1345 Dart_EnterScope(); |
| 1702 | 1346 |
| 1703 if (gen_snapshot_kind == kScript) { | 1347 if (gen_snapshot_kind == kScript) { |
| 1704 GenerateScriptSnapshot(); | 1348 Snapshot::GenerateScript(snapshot_filename); |
| 1705 } else { | 1349 } else { |
| 1706 // Lookup the library of the root script. | 1350 // Lookup the library of the root script. |
| 1707 Dart_Handle root_lib = Dart_RootLibrary(); | 1351 Dart_Handle root_lib = Dart_RootLibrary(); |
| 1708 // Import the root library into the builtin library so that we can easily | 1352 // Import the root library into the builtin library so that we can easily |
| 1709 // lookup the main entry point exported from the root library. | 1353 // lookup the main entry point exported from the root library. |
| 1710 IsolateData* isolate_data = | 1354 IsolateData* isolate_data = |
| 1711 reinterpret_cast<IsolateData*>(Dart_IsolateData(isolate)); | 1355 reinterpret_cast<IsolateData*>(Dart_IsolateData(isolate)); |
| 1712 result = Dart_LibraryImportLibrary(isolate_data->builtin_lib(), root_lib, | 1356 result = Dart_LibraryImportLibrary(isolate_data->builtin_lib(), root_lib, |
| 1713 Dart_Null()); | 1357 Dart_Null()); |
| 1714 if ((gen_snapshot_kind == kAppAOT) || (gen_snapshot_kind == kAppJIT)) { | 1358 if ((gen_snapshot_kind == kAppAOT) || (gen_snapshot_kind == kAppJIT)) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1825 Dart_NewStringFromCString("_startMainIsolate"), | 1469 Dart_NewStringFromCString("_startMainIsolate"), |
| 1826 kNumIsolateArgs, isolate_args); | 1470 kNumIsolateArgs, isolate_args); |
| 1827 CHECK_RESULT(result); | 1471 CHECK_RESULT(result); |
| 1828 | 1472 |
| 1829 // Keep handling messages until the last active receive port is closed. | 1473 // Keep handling messages until the last active receive port is closed. |
| 1830 result = Dart_RunLoop(); | 1474 result = Dart_RunLoop(); |
| 1831 // Generate an app snapshot after execution if specified. | 1475 // Generate an app snapshot after execution if specified. |
| 1832 if (gen_snapshot_kind == kAppJIT) { | 1476 if (gen_snapshot_kind == kAppJIT) { |
| 1833 if (!Dart_IsCompilationError(result) && | 1477 if (!Dart_IsCompilationError(result) && |
| 1834 !Dart_IsVMRestartRequest(result)) { | 1478 !Dart_IsVMRestartRequest(result)) { |
| 1835 GenerateAppJITSnapshot(); | 1479 Snapshot::GenerateAppJIT(snapshot_filename); |
| 1836 } | 1480 } |
| 1837 } | 1481 } |
| 1838 CHECK_RESULT(result); | 1482 CHECK_RESULT(result); |
| 1839 | 1483 |
| 1840 if (save_feedback_filename != NULL) { | 1484 if (save_feedback_filename != NULL) { |
| 1841 uint8_t* buffer = NULL; | 1485 uint8_t* buffer = NULL; |
| 1842 intptr_t size = 0; | 1486 intptr_t size = 0; |
| 1843 result = Dart_SaveJITFeedback(&buffer, &size); | 1487 result = Dart_SaveJITFeedback(&buffer, &size); |
| 1844 if (Dart_IsError(result)) { | 1488 if (Dart_IsError(result)) { |
| 1845 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result)); | 1489 ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result)); |
| 1846 } | 1490 } |
| 1847 WriteSnapshotFile(save_feedback_filename, false, buffer, size); | 1491 WriteFile(save_feedback_filename, buffer, size); |
| 1848 } | 1492 } |
| 1849 } | 1493 } |
| 1850 } | 1494 } |
| 1851 | 1495 |
| 1852 Dart_ExitScope(); | 1496 Dart_ExitScope(); |
| 1853 // Shutdown the isolate. | 1497 // Shutdown the isolate. |
| 1854 Dart_ShutdownIsolate(); | 1498 Dart_ShutdownIsolate(); |
| 1855 | 1499 |
| 1856 // No restart. | 1500 // No restart. |
| 1857 return false; | 1501 return false; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1988 Thread::InitOnce(); | 1632 Thread::InitOnce(); |
| 1989 | 1633 |
| 1990 Loader::InitOnce(); | 1634 Loader::InitOnce(); |
| 1991 | 1635 |
| 1992 if (!DartUtils::SetOriginalWorkingDirectory()) { | 1636 if (!DartUtils::SetOriginalWorkingDirectory()) { |
| 1993 OSError err; | 1637 OSError err; |
| 1994 Log::PrintErr("Error determining current directory: %s\n", err.message()); | 1638 Log::PrintErr("Error determining current directory: %s\n", err.message()); |
| 1995 Platform::Exit(kErrorExitCode); | 1639 Platform::Exit(kErrorExitCode); |
| 1996 } | 1640 } |
| 1997 | 1641 |
| 1998 if (ReadAppSnapshot(script_name, &vm_snapshot_data, &vm_snapshot_instructions, | 1642 if (Snapshot::ReadAppSnapshot( |
| 1999 &app_isolate_snapshot_data, | 1643 script_name, &vm_snapshot_data, &vm_snapshot_instructions, |
| 2000 &app_isolate_snapshot_instructions)) { | 1644 &app_isolate_snapshot_data, &app_isolate_snapshot_instructions)) { |
| 2001 vm_run_app_snapshot = true; | 1645 vm_run_app_snapshot = true; |
| 2002 } | 1646 } |
| 2003 | 1647 |
| 2004 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME) | 1648 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME) |
| 2005 // Constant true if PRODUCT or DART_PRECOMPILED_RUNTIME. | 1649 // Constant true if PRODUCT or DART_PRECOMPILED_RUNTIME. |
| 2006 if ((gen_snapshot_kind != kNone) || vm_run_app_snapshot) { | 1650 if ((gen_snapshot_kind != kNone) || vm_run_app_snapshot) { |
| 2007 vm_options.AddArgument("--load_deferred_eagerly"); | 1651 vm_options.AddArgument("--load_deferred_eagerly"); |
| 2008 } | 1652 } |
| 2009 #endif | 1653 #endif |
| 2010 | 1654 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2096 Platform::Exit(Process::GlobalExitCode()); | 1740 Platform::Exit(Process::GlobalExitCode()); |
| 2097 } | 1741 } |
| 2098 | 1742 |
| 2099 } // namespace bin | 1743 } // namespace bin |
| 2100 } // namespace dart | 1744 } // namespace dart |
| 2101 | 1745 |
| 2102 int main(int argc, char** argv) { | 1746 int main(int argc, char** argv) { |
| 2103 dart::bin::main(argc, argv); | 1747 dart::bin::main(argc, argv); |
| 2104 UNREACHABLE(); | 1748 UNREACHABLE(); |
| 2105 } | 1749 } |
| OLD | NEW |