1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
From 2493dac20f0b4134bbf02ac48dffde6c2643608b Mon Sep 17 00:00:00 2001
From: Elvis Pranskevichus <elvis@magic.io>
Date: Sat, 11 Jun 2016 18:27:19 -0400
Subject: [PATCH] Add support for external V8 snapshots
---
src/node.cc | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+)
diff --git a/src/node.cc b/src/node.cc
index cbe1538..521708a 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -4037,6 +4037,90 @@ Environment* CreateEnvironment(Isolate* isolate,
return env;
}
+#include <sys/mman.h>
+
+const char kProcSelfExe[] = "/proc/self/exe";
+const char kNativesFileName[] = "natives_blob.bin";
+const char kSnapshotFileName[] = "snapshot_blob.bin";
+const char *g_mapped_natives = nullptr;
+const char *g_mapped_snapshot = nullptr;
+
+static char* SnapshotPath(const char* filename) {
+ char *path;
+ char *dir;
+ ssize_t r;
+
+ path = reinterpret_cast<char*>(malloc(4096 + strlen(filename) + 2));
+ if (path == nullptr) {
+ fprintf(stderr, "out of memory\n");
+ ABORT();
+ }
+
+ r = readlink(kProcSelfExe, path, 4096 + 1);
+ if (r == -1) {
+ perror("could not determine node executable directory");
+ ABORT();
+ }
+
+ path[r] = '\0';
+
+ dir = strrchr(path, '/');
+
+ strcpy(dir + 1, filename);
+
+ return path;
+}
+
+static void LoadV8Snapshot(const char* name, const char** addr, size_t *size) {
+ char *path = SnapshotPath(name);
+ int fd;
+ struct stat sb;
+
+ fd = open(path, O_RDONLY);
+
+ if (fd == -1) {
+ fprintf(stderr, "could not open snapshot file '%s': %s\n",
+ path, sys_errlist[errno]);
+ ABORT();
+ }
+
+ if (fstat(fd, &sb) == -1) {
+ fprintf(stderr, "could not stat snapshot file '%s': %s\n",
+ path, sys_errlist[errno]);
+ ABORT();
+ }
+
+ *size = sb.st_size;
+
+ *addr = reinterpret_cast<const char*>(
+ mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0));
+ if (*addr == MAP_FAILED) {
+ fprintf(stderr, "could not read snapshot file '%s': %s\n",
+ path, sys_errlist[errno]);
+ ABORT();
+ }
+
+ close(fd);
+ free(path);
+}
+
+static void LoadV8Snapshots() {
+ size_t natives_size;
+ size_t snapshot_size;
+
+ LoadV8Snapshot(kNativesFileName, &g_mapped_natives, &natives_size);
+ LoadV8Snapshot(kSnapshotFileName, &g_mapped_snapshot, &snapshot_size);
+
+ v8::StartupData natives;
+ natives.data = g_mapped_natives;
+ natives.raw_size = natives_size;
+ V8::SetNativesDataBlob(&natives);
+
+ v8::StartupData snapshot;
+ snapshot.data = g_mapped_snapshot;
+ snapshot.raw_size = snapshot_size;
+ V8::SetSnapshotDataBlob(&snapshot);
+}
// Entry point for new node instances, also called directly for the main
// node instance.
@@ -4142,6 +4226,8 @@ int Start(int argc, char** argv) {
const char** exec_argv;
Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
+ LoadV8Snapshots();
+
#if HAVE_OPENSSL
// V8 on Windows doesn't have a good source of entropy. Seed it from
// OpenSSL's pool.
--
2.7.3
|