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/init/startup-data-util.h"
6 
7 #include <stdlib.h>
8 #include <string.h>
9 
10 #include "include/v8-initialization.h"
11 #include "include/v8-snapshot.h"
12 #include "src/base/file-utils.h"
13 #include "src/base/logging.h"
14 #include "src/base/platform/platform.h"
15 #include "src/base/platform/wrappers.h"
16 #include "src/flags/flags.h"
17 #include "src/utils/utils.h"
18 
19 namespace v8 {
20 namespace internal {
21 
22 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
23 
24 namespace {
25 
26 v8::StartupData g_snapshot;
27 
ClearStartupData(v8::StartupData * data)28 void ClearStartupData(v8::StartupData* data) {
29   data->data = nullptr;
30   data->raw_size = 0;
31 }
32 
DeleteStartupData(v8::StartupData * data)33 void DeleteStartupData(v8::StartupData* data) {
34   delete[] data->data;
35   ClearStartupData(data);
36 }
37 
FreeStartupData()38 void FreeStartupData() {
39   DeleteStartupData(&g_snapshot);
40 }
41 
Load(const char * blob_file,v8::StartupData * startup_data,void (* setter_fn)(v8::StartupData *))42 void Load(const char* blob_file, v8::StartupData* startup_data,
43           void (*setter_fn)(v8::StartupData*)) {
44   ClearStartupData(startup_data);
45 
46   CHECK(blob_file);
47 
48   FILE* file = base::Fopen(blob_file, "rb");
49   if (!file) {
50     PrintF(stderr, "Failed to open startup resource '%s'.\n", blob_file);
51     return;
52   }
53 
54   fseek(file, 0, SEEK_END);
55   startup_data->raw_size = static_cast<int>(ftell(file));
56   rewind(file);
57 
58   startup_data->data = new char[startup_data->raw_size];
59   int read_size = static_cast<int>(fread(const_cast<char*>(startup_data->data),
60                                          1, startup_data->raw_size, file));
61   base::Fclose(file);
62 
63   if (startup_data->raw_size == read_size) {
64     (*setter_fn)(startup_data);
65   } else {
66     PrintF(stderr, "Corrupted startup resource '%s'.\n", blob_file);
67   }
68 }
69 
LoadFromFile(const char * snapshot_blob)70 void LoadFromFile(const char* snapshot_blob) {
71   Load(snapshot_blob, &g_snapshot, v8::V8::SetSnapshotDataBlob);
72   atexit(&FreeStartupData);
73 }
74 
75 }  // namespace
76 #endif  // V8_USE_EXTERNAL_STARTUP_DATA
77 
InitializeExternalStartupData(const char * directory_path)78 void InitializeExternalStartupData(const char* directory_path) {
79 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
80   const char* snapshot_name = "snapshot_blob.bin";
81   std::unique_ptr<char[]> snapshot =
82       base::RelativePath(directory_path, snapshot_name);
83   LoadFromFile(snapshot.get());
84 #endif  // V8_USE_EXTERNAL_STARTUP_DATA
85 }
86 
InitializeExternalStartupDataFromFile(const char * snapshot_blob)87 void InitializeExternalStartupDataFromFile(const char* snapshot_blob) {
88 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
89   LoadFromFile(snapshot_blob);
90 #endif  // V8_USE_EXTERNAL_STARTUP_DATA
91 }
92 
93 }  // namespace internal
94 }  // namespace v8
95