1 // Copyright 2015 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/startup-data-util.h" 6 7 #include <stdlib.h> 8 #include <string.h> 9 10 #include "src/base/logging.h" 11 #include "src/base/platform/platform.h" 12 #include "src/utils.h" 13 14 15 namespace v8 { 16 namespace internal { 17 18 #ifdef V8_USE_EXTERNAL_STARTUP_DATA 19 20 namespace { 21 22 v8::StartupData g_natives; 23 v8::StartupData g_snapshot; 24 25 26 void ClearStartupData(v8::StartupData* data) { 27 data->data = nullptr; 28 data->raw_size = 0; 29 } 30 31 32 void DeleteStartupData(v8::StartupData* data) { 33 delete[] data->data; 34 ClearStartupData(data); 35 } 36 37 38 void FreeStartupData() { 39 DeleteStartupData(&g_natives); 40 DeleteStartupData(&g_snapshot); 41 } 42 43 44 void Load(const char* blob_file, v8::StartupData* startup_data, 45 void (*setter_fn)(v8::StartupData*)) { 46 ClearStartupData(startup_data); 47 48 CHECK(blob_file); 49 50 FILE* file = fopen(blob_file, "rb"); 51 if (!file) { 52 PrintF(stderr, "Failed to open startup resource '%s'.\n", blob_file); 53 return; 54 } 55 56 fseek(file, 0, SEEK_END); 57 startup_data->raw_size = static_cast<int>(ftell(file)); 58 rewind(file); 59 60 startup_data->data = new char[startup_data->raw_size]; 61 int read_size = static_cast<int>(fread(const_cast<char*>(startup_data->data), 62 1, startup_data->raw_size, file)); 63 fclose(file); 64 65 if (startup_data->raw_size == read_size) { 66 (*setter_fn)(startup_data); 67 } else { 68 PrintF(stderr, "Corrupted startup resource '%s'.\n", blob_file); 69 } 70 } 71 72 73 void LoadFromFiles(const char* natives_blob, const char* snapshot_blob) { 74 Load(natives_blob, &g_natives, v8::V8::SetNativesDataBlob); 75 Load(snapshot_blob, &g_snapshot, v8::V8::SetSnapshotDataBlob); 76 77 atexit(&FreeStartupData); 78 } 79 80 81 char* RelativePath(char** buffer, const char* exec_path, const char* name) { 82 DCHECK(exec_path); 83 int path_separator = static_cast<int>(strlen(exec_path)) - 1; 84 while (path_separator >= 0 && 85 !base::OS::isDirectorySeparator(exec_path[path_separator])) { 86 path_separator--; 87 } 88 if (path_separator >= 0) { 89 int name_length = static_cast<int>(strlen(name)); 90 *buffer = 91 reinterpret_cast<char*>(calloc(path_separator + name_length + 2, 1)); 92 *buffer[0] = '\0'; 93 strncat(*buffer, exec_path, path_separator + 1); 94 strncat(*buffer, name, name_length); 95 } else { 96 *buffer = strdup(name); 97 } 98 return *buffer; 99 } 100 101 } // namespace 102 #endif // V8_USE_EXTERNAL_STARTUP_DATA 103 104 105 void InitializeExternalStartupData(const char* directory_path) { 106 #ifdef V8_USE_EXTERNAL_STARTUP_DATA 107 char* natives; 108 char* snapshot; 109 LoadFromFiles(RelativePath(&natives, directory_path, "natives_blob.bin"), 110 RelativePath(&snapshot, directory_path, "snapshot_blob.bin")); 111 free(natives); 112 free(snapshot); 113 #endif // V8_USE_EXTERNAL_STARTUP_DATA 114 } 115 116 117 void InitializeExternalStartupData(const char* natives_blob, 118 const char* snapshot_blob) { 119 #ifdef V8_USE_EXTERNAL_STARTUP_DATA 120 LoadFromFiles(natives_blob, snapshot_blob); 121 #endif // V8_USE_EXTERNAL_STARTUP_DATA 122 } 123 124 } // namespace internal 125 } // namespace v8 126