Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(443)

Side by Side Diff: runtime/bin/gen_snapshot.cc

Issue 1915853004: Option to output precompiled instructions as a blob for use with mmap instead of assembly for use i… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/bin/file_win.cc ('k') | runtime/bin/main.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <stdio.h> 8 #include <stdio.h>
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include <string.h> 10 #include <string.h>
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 Dart_ExitScope(); \ 53 Dart_ExitScope(); \
54 Dart_ShutdownIsolate(); \ 54 Dart_ShutdownIsolate(); \
55 exit(exit_code); \ 55 exit(exit_code); \
56 } 56 }
57 57
58 58
59 // Global state that indicates whether a snapshot is to be created and 59 // Global state that indicates whether a snapshot is to be created and
60 // if so which file to write the snapshot into. 60 // if so which file to write the snapshot into.
61 static const char* vm_isolate_snapshot_filename = NULL; 61 static const char* vm_isolate_snapshot_filename = NULL;
62 static const char* isolate_snapshot_filename = NULL; 62 static const char* isolate_snapshot_filename = NULL;
63 static const char* instructions_snapshot_filename = NULL; 63 static const char* assembly_filename = NULL;
64 static const char* instructions_blob_filename = NULL;
65 static const char* rodata_blob_filename = NULL;
64 static const char* package_root = NULL; 66 static const char* package_root = NULL;
65 67
66 68
67 // Global state which contains a pointer to the script name for which 69 // Global state which contains a pointer to the script name for which
68 // a snapshot needs to be created (NULL would result in the creation 70 // a snapshot needs to be created (NULL would result in the creation
69 // of a generic snapshot that contains only the corelibs). 71 // of a generic snapshot that contains only the corelibs).
70 static char* app_script_name = NULL; 72 static char* app_script_name = NULL;
71 73
72 74
73 // Global state that captures the URL mappings specified on the command line. 75 // Global state that captures the URL mappings specified on the command line.
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 static bool ProcessIsolateSnapshotOption(const char* option) { 197 static bool ProcessIsolateSnapshotOption(const char* option) {
196 const char* name = ProcessOption(option, "--isolate_snapshot="); 198 const char* name = ProcessOption(option, "--isolate_snapshot=");
197 if (name != NULL) { 199 if (name != NULL) {
198 isolate_snapshot_filename = name; 200 isolate_snapshot_filename = name;
199 return true; 201 return true;
200 } 202 }
201 return false; 203 return false;
202 } 204 }
203 205
204 206
205 static bool ProcessInstructionsSnapshotOption(const char* option) { 207 static bool ProcessAssemblyOption(const char* option) {
206 const char* name = ProcessOption(option, "--instructions_snapshot="); 208 const char* name = ProcessOption(option, "--assembly=");
207 if (name != NULL) { 209 if (name != NULL) {
208 instructions_snapshot_filename = name; 210 assembly_filename = name;
209 return true; 211 return true;
210 } 212 }
211 return false; 213 return false;
214 }
215
216
217 static bool ProcessInstructionsBlobOption(const char* option) {
218 const char* name = ProcessOption(option, "--instructions_blob=");
219 if (name != NULL) {
220 instructions_blob_filename = name;
221 return true;
222 }
223 return false;
224 }
225
226
227 static bool ProcessRodataBlobOption(const char* option) {
228 const char* name = ProcessOption(option, "--rodata_blob=");
229 if (name != NULL) {
230 rodata_blob_filename = name;
231 return true;
232 }
233 return false;
212 } 234 }
213 235
214 236
215 static bool ProcessEmbedderEntryPointsManifestOption(const char* option) { 237 static bool ProcessEmbedderEntryPointsManifestOption(const char* option) {
216 const char* name = ProcessOption(option, "--embedder_entry_points_manifest="); 238 const char* name = ProcessOption(option, "--embedder_entry_points_manifest=");
217 if (name != NULL) { 239 if (name != NULL) {
218 entry_points_files->AddArgument(name); 240 entry_points_files->AddArgument(name);
219 return true; 241 return true;
220 } 242 }
221 return false; 243 return false;
(...skipping 19 matching lines...) Expand all
241 mapping = ProcessOption(option, "--url-mapping="); 263 mapping = ProcessOption(option, "--url-mapping=");
242 } 264 }
243 if (mapping != NULL) { 265 if (mapping != NULL) {
244 url_mapping->AddArgument(mapping); 266 url_mapping->AddArgument(mapping);
245 return true; 267 return true;
246 } 268 }
247 return false; 269 return false;
248 } 270 }
249 271
250 272
273 static bool IsSnapshottingForPrecompilation() {
274 return (assembly_filename != NULL) || (instructions_blob_filename != NULL);
275 }
276
277
251 // Parse out the command line arguments. Returns -1 if the arguments 278 // Parse out the command line arguments. Returns -1 if the arguments
252 // are incorrect, 0 otherwise. 279 // are incorrect, 0 otherwise.
253 static int ParseArguments(int argc, 280 static int ParseArguments(int argc,
254 char** argv, 281 char** argv,
255 CommandLineOptions* vm_options, 282 CommandLineOptions* vm_options,
256 char** script_name) { 283 char** script_name) {
257 const char* kPrefix = "-"; 284 const char* kPrefix = "-";
258 const intptr_t kPrefixLen = strlen(kPrefix); 285 const intptr_t kPrefixLen = strlen(kPrefix);
259 286
260 // Skip the binary name. 287 // Skip the binary name.
261 int i = 1; 288 int i = 1;
262 289
263 // Parse out the vm options. 290 // Parse out the vm options.
264 while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) { 291 while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) {
265 if (ProcessVmIsolateSnapshotOption(argv[i]) || 292 if (ProcessVmIsolateSnapshotOption(argv[i]) ||
266 ProcessIsolateSnapshotOption(argv[i]) || 293 ProcessIsolateSnapshotOption(argv[i]) ||
267 ProcessInstructionsSnapshotOption(argv[i]) || 294 ProcessAssemblyOption(argv[i]) ||
295 ProcessInstructionsBlobOption(argv[i]) ||
296 ProcessRodataBlobOption(argv[i]) ||
268 ProcessEmbedderEntryPointsManifestOption(argv[i]) || 297 ProcessEmbedderEntryPointsManifestOption(argv[i]) ||
269 ProcessURLmappingOption(argv[i]) || 298 ProcessURLmappingOption(argv[i]) ||
270 ProcessPackageRootOption(argv[i]) || 299 ProcessPackageRootOption(argv[i]) ||
271 ProcessEnvironmentOption(argv[i])) { 300 ProcessEnvironmentOption(argv[i])) {
272 i += 1; 301 i += 1;
273 continue; 302 continue;
274 } 303 }
275 vm_options->AddArgument(argv[i]); 304 vm_options->AddArgument(argv[i]);
276 i += 1; 305 i += 1;
277 } 306 }
278 307
279 // Get the script name. 308 // Get the script name.
280 if (i < argc) { 309 if (i < argc) {
281 *script_name = argv[i]; 310 *script_name = argv[i];
282 i += 1; 311 i += 1;
283 } else { 312 } else {
284 *script_name = NULL; 313 *script_name = NULL;
285 } 314 }
286 315
287 if (vm_isolate_snapshot_filename == NULL) { 316 if (vm_isolate_snapshot_filename == NULL) {
288 Log::PrintErr("No vm isolate snapshot output file specified.\n\n"); 317 Log::PrintErr("No vm isolate snapshot output file specified.\n\n");
289 return -1; 318 return -1;
290 } 319 }
291 320
292 if (isolate_snapshot_filename == NULL) { 321 if (isolate_snapshot_filename == NULL) {
293 Log::PrintErr("No isolate snapshot output file specified.\n\n"); 322 Log::PrintErr("No isolate snapshot output file specified.\n\n");
294 return -1; 323 return -1;
295 } 324 }
296 325
297 if ((instructions_snapshot_filename != NULL) && 326 bool precompiled_as_assembly = assembly_filename != NULL;
327 bool precompiled_as_blobs = (instructions_blob_filename != NULL) ||
328 (rodata_blob_filename != NULL);
329 if (precompiled_as_assembly && precompiled_as_blobs) {
330 Log::PrintErr(
331 "Cannot request a precompiled snapshot simultaneously as "
332 "assembly (--assembly=<output.file>) and as blobs "
333 "(--instructions-blob=<output.file> and "
334 "--rodata-blob=<output.file>)\n\n");
335 return -1;
336 }
337 if ((instructions_blob_filename != NULL) != (rodata_blob_filename != NULL)) {
338 Log::PrintErr(
339 "Requesting a precompiled snapshot as blobs requires both "
340 "(--instructions-blob=<output.file> and "
341 "--rodata-blob=<output.file>)\n\n");
342 return -1;
343 }
344 if (IsSnapshottingForPrecompilation() &&
298 (entry_points_files->count() == 0)) { 345 (entry_points_files->count() == 0)) {
299 Log::PrintErr( 346 Log::PrintErr(
300 "Specifying an instructions snapshot filename indicates precompilation" 347 "Specifying an instructions snapshot filename indicates precompilation"
301 ". But no embedder entry points manifest was specified.\n\n"); 348 ". But no embedder entry points manifest was specified.\n\n");
302 return -1; 349 return -1;
303 } 350 }
304 351
305 if ((entry_points_files->count() > 0) &&
306 (instructions_snapshot_filename == NULL)) {
307 Log::PrintErr(
308 "Specifying the embedder entry points manifest indicates "
309 "precompilation. But no instuctions snapshot was specified.\n\n");
310 return -1;
311 }
312
313 return 0; 352 return 0;
314 } 353 }
315 354
316 355
317 static bool IsSnapshottingForPrecompilation(void) {
318 return (entry_points_files->count() > 0) &&
319 (instructions_snapshot_filename != NULL);
320 }
321
322
323 static void WriteSnapshotFile(const char* filename, 356 static void WriteSnapshotFile(const char* filename,
324 const uint8_t* buffer, 357 const uint8_t* buffer,
325 const intptr_t size) { 358 const intptr_t size) {
326 File* file = File::Open(filename, File::kWriteTruncate); 359 File* file = File::Open(filename, File::kWriteTruncate);
327 ASSERT(file != NULL); 360 ASSERT(file != NULL);
328 if (!file->WriteFully(buffer, size)) { 361 if (!file->WriteFully(buffer, size)) {
329 Log::PrintErr("Error: Failed to write snapshot file.\n\n"); 362 Log::PrintErr("Error: Failed to write snapshot file.\n\n");
330 } 363 }
331 file->Release(); 364 file->Release();
332 } 365 }
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 "Usage: \n" 609 "Usage: \n"
577 " gen_snapshot [<vm-flags>] [<options>] [<dart-script-file>] \n" 610 " gen_snapshot [<vm-flags>] [<options>] [<dart-script-file>] \n"
578 " \n" 611 " \n"
579 " Writes a snapshot of <dart-script-file> to the specified snapshot files. \n" 612 " Writes a snapshot of <dart-script-file> to the specified snapshot files. \n"
580 " If no <dart-script-file> is passed, a generic snapshot of all the corelibs\n" 613 " If no <dart-script-file> is passed, a generic snapshot of all the corelibs\n"
581 " is created. It is required to specify the VM isolate snapshot and the \n" 614 " is created. It is required to specify the VM isolate snapshot and the \n"
582 " isolate snapshot. The other flags are related to precompilation and are \n" 615 " isolate snapshot. The other flags are related to precompilation and are \n"
583 " optional. \n" 616 " optional. \n"
584 " \n" 617 " \n"
585 " Precompilation: \n" 618 " Precompilation: \n"
586 " In order to configure the snapshotter for precompilation, both the \n" 619 " In order to configure the snapshotter for precompilation, either \n"
587 " instructions snapshot and embedder entry points manifest must be \n" 620 " --assembly=outputfile or --instructions_blob=outputfile1 and \n"
588 " specified. Assembly for the target architecture will be dumped into the \n" 621 " --rodata_blob=outputfile2 must be specified. If the former is choosen, \n"
589 " instructions snapshot. This must be linked into the target binary in a \n" 622 " assembly for the target architecture will be output into the given file, \n"
590 " separate step. The embedder entry points manifest lists the standalone \n" 623 " which must be compiled separately and either statically linked or \n"
591 " entry points into the VM. Not specifying these will cause the tree shaker \n" 624 " dynamically loaded in the target executable. The symbols \n"
592 " to disregard the same as being used. The format of this manifest is as \n" 625 " kInstructionsSnapshot and kDataSnapshot must be passed to Dart_Initialize.\n"
593 " follows. Each line in the manifest is a comma separated list of three \n" 626 " If the latter is choosen, binary data is output into the given files, \n"
594 " elements. The first entry is the library URI, the second entry is the \n" 627 " which should be mmapped and passed to Dart_Initialize, with the \n"
595 " class name and the final entry the function name. The file must be \n" 628 " instruction blob being mapped as executable. \n"
596 " terminated with a newline charater. \n" 629 " In both cases, a entry points manifest must be given to list the places \n"
630 " in the Dart program the embedder calls from the C API (Dart_Invoke, etc). \n"
631 " Not specifying these may cause the tree shaker to remove them from the \n"
632 " program. The format of this manifest is as follows. Each line in the \n"
633 " manifest is a comma separated list of three elements. The first entry is \n"
634 " the library URI, the second entry is the class name and the final entry \n"
635 " the function name. The file must be terminated with a newline charater. \n"
597 " \n" 636 " \n"
598 " Example: \n" 637 " Example: \n"
599 " dart:something,SomeClass,doSomething \n" 638 " dart:something,SomeClass,doSomething \n"
600 " \n" 639 " \n"
601 " Supported options: \n" 640 " Supported options: \n"
602 " --vm_isolate_snapshot=<file> A full snapshot is a compact \n" 641 " --vm_isolate_snapshot=<file> A full snapshot is a compact \n"
603 " --isolate_snapshot=<file> representation of the dart vm isolate \n" 642 " --isolate_snapshot=<file> representation of the dart vm isolate \n"
604 " heap and dart isolate heap states. \n" 643 " heap and dart isolate heap states. \n"
605 " Both these options are required \n" 644 " Both these options are required \n"
606 " \n" 645 " \n"
607 " --package_root=<path> Where to find packages, that is, \n" 646 " --package_root=<path> Where to find packages, that is, \n"
608 " package:... imports. \n" 647 " package:... imports. \n"
609 " \n" 648 " \n"
610 " --url_mapping=<mapping> Uses the URL mapping(s) specified on \n" 649 " --url_mapping=<mapping> Uses the URL mapping(s) specified on \n"
611 " the command line to load the \n" 650 " the command line to load the \n"
612 " libraries. \n" 651 " libraries. \n"
613 " \n" 652 " \n"
614 " --instructions_snapshot=<file> (Precompilation only) Contains the \n" 653 " --assembly=<file> (Precompilation only) Contains the \n"
615 " assembly that must be linked into \n" 654 " assembly that must be linked into \n"
616 " the target binary \n" 655 " the target binary \n"
617 " \n" 656 " \n"
618 " --embedder_entry_points_manifest=<file> (Precompilation only) Contains \n" 657 " --instructions_blob=<file> (Precompilation only) Contains the \n"
619 " the stanalone embedder entry points\n"); 658 " --rodata_blob=<file> instructions and read-only data that \n"
659 " must be mapped into the target binary \n"
660 " \n"
661 " --embedder_entry_points_manifest=<file> (Precompilation or app \n"
662 " snapshots) Contains embedder's entry \n"
663 " points into Dart code from the C API. \n"
664 "\n");
620 } 665 }
621 666
622 667
623 static void VerifyLoaded(Dart_Handle library) { 668 static void VerifyLoaded(Dart_Handle library) {
624 if (Dart_IsError(library)) { 669 if (Dart_IsError(library)) {
625 const char* err_msg = Dart_GetError(library); 670 const char* err_msg = Dart_GetError(library);
626 Log::PrintErr("Errors encountered while loading: %s\n", err_msg); 671 Log::PrintErr("Errors encountered while loading: %s\n", err_msg);
627 CHECK_RESULT(library); 672 CHECK_RESULT(library);
628 } 673 }
629 ASSERT(Dart_IsLibrary(library)); 674 ASSERT(Dart_IsLibrary(library));
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 1032
988 1033
989 static void CreateAndWritePrecompiledSnapshot( 1034 static void CreateAndWritePrecompiledSnapshot(
990 Dart_QualifiedFunctionName* standalone_entry_points) { 1035 Dart_QualifiedFunctionName* standalone_entry_points) {
991 ASSERT(IsSnapshottingForPrecompilation()); 1036 ASSERT(IsSnapshottingForPrecompilation());
992 Dart_Handle result; 1037 Dart_Handle result;
993 uint8_t* vm_isolate_buffer = NULL; 1038 uint8_t* vm_isolate_buffer = NULL;
994 intptr_t vm_isolate_size = 0; 1039 intptr_t vm_isolate_size = 0;
995 uint8_t* isolate_buffer = NULL; 1040 uint8_t* isolate_buffer = NULL;
996 intptr_t isolate_size = 0; 1041 intptr_t isolate_size = 0;
997 uint8_t* instructions_buffer = NULL; 1042 uint8_t* assembly_buffer = NULL;
998 intptr_t instructions_size = 0; 1043 intptr_t assembly_size = 0;
1044 uint8_t* instructions_blob_buffer = NULL;
1045 intptr_t instructions_blob_size = 0;
1046 uint8_t* rodata_blob_buffer = NULL;
1047 intptr_t rodata_blob_size = 0;
999 1048
1000 // Precompile with specified embedder entry points 1049 // Precompile with specified embedder entry points
1001 result = Dart_Precompile(standalone_entry_points, true); 1050 result = Dart_Precompile(standalone_entry_points, true);
1002 CHECK_RESULT(result); 1051 CHECK_RESULT(result);
1003 1052
1004 // Create a precompiled snapshot. This gives us an instruction buffer with 1053 // Create a precompiled snapshot.
1005 // machine code 1054 bool as_assembly = assembly_filename != NULL;
1006 result = Dart_CreatePrecompiledSnapshot(&vm_isolate_buffer, 1055 if (as_assembly) {
1007 &vm_isolate_size, 1056 result = Dart_CreatePrecompiledSnapshotAssembly(&vm_isolate_buffer,
1008 &isolate_buffer, 1057 &vm_isolate_size,
1009 &isolate_size, 1058 &isolate_buffer,
1010 &instructions_buffer, 1059 &isolate_size,
1011 &instructions_size); 1060 &assembly_buffer,
1012 CHECK_RESULT(result); 1061 &assembly_size);
1062 CHECK_RESULT(result);
1063 } else {
1064 result = Dart_CreatePrecompiledSnapshotBlob(&vm_isolate_buffer,
1065 &vm_isolate_size,
1066 &isolate_buffer,
1067 &isolate_size,
1068 &instructions_blob_buffer,
1069 &instructions_blob_size,
1070 &rodata_blob_buffer,
1071 &rodata_blob_size);
1072 CHECK_RESULT(result);
1073 }
1013 1074
1014 // Now write the vm isolate, isolate and instructions snapshots out to the 1075 // Now write the snapshot pieces out to the specified files and exit.
1015 // specified files and exit.
1016 WriteSnapshotFile(vm_isolate_snapshot_filename, 1076 WriteSnapshotFile(vm_isolate_snapshot_filename,
1017 vm_isolate_buffer, 1077 vm_isolate_buffer,
1018 vm_isolate_size); 1078 vm_isolate_size);
1019 WriteSnapshotFile(isolate_snapshot_filename, 1079 WriteSnapshotFile(isolate_snapshot_filename,
1020 isolate_buffer, 1080 isolate_buffer,
1021 isolate_size); 1081 isolate_size);
1022 WriteSnapshotFile(instructions_snapshot_filename, 1082 if (as_assembly) {
1023 instructions_buffer, 1083 WriteSnapshotFile(assembly_filename,
1024 instructions_size); 1084 assembly_buffer,
1085 assembly_size);
1086 } else {
1087 WriteSnapshotFile(instructions_blob_filename,
1088 instructions_blob_buffer,
1089 instructions_blob_size);
1090 WriteSnapshotFile(rodata_blob_filename,
1091 rodata_blob_buffer,
1092 rodata_blob_size);
1093 }
1025 Dart_ExitScope(); 1094 Dart_ExitScope();
1026 1095
1027 // Shutdown the isolate. 1096 // Shutdown the isolate.
1028 Dart_ShutdownIsolate(); 1097 Dart_ShutdownIsolate();
1029 } 1098 }
1030 1099
1031 1100
1032 static void SetupForUriResolution() { 1101 static void SetupForUriResolution() {
1033 // Set up the library tag handler for this isolate. 1102 // Set up the library tag handler for this isolate.
1034 Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler); 1103 Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler);
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1280 EventHandler::Stop(); 1349 EventHandler::Stop();
1281 return 0; 1350 return 0;
1282 } 1351 }
1283 1352
1284 } // namespace bin 1353 } // namespace bin
1285 } // namespace dart 1354 } // namespace dart
1286 1355
1287 int main(int argc, char** argv) { 1356 int main(int argc, char** argv) {
1288 return dart::bin::main(argc, argv); 1357 return dart::bin::main(argc, argv);
1289 } 1358 }
OLDNEW
« no previous file with comments | « runtime/bin/file_win.cc ('k') | runtime/bin/main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698