• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ClearStartupData(v8::StartupData * data)26 void ClearStartupData(v8::StartupData* data) {
27   data->data = nullptr;
28   data->raw_size = 0;
29 }
30 
31 
DeleteStartupData(v8::StartupData * data)32 void DeleteStartupData(v8::StartupData* data) {
33   delete[] data->data;
34   ClearStartupData(data);
35 }
36 
37 
FreeStartupData()38 void FreeStartupData() {
39   DeleteStartupData(&g_natives);
40   DeleteStartupData(&g_snapshot);
41 }
42 
43 
Load(const char * blob_file,v8::StartupData * startup_data,void (* setter_fn)(v8::StartupData *))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 
LoadFromFiles(const char * natives_blob,const char * snapshot_blob)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 
RelativePath(char ** buffer,const char * exec_path,const char * name)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 
InitializeExternalStartupData(const char * directory_path)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 
InitializeExternalStartupData(const char * natives_blob,const char * snapshot_blob)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