-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmksnapshot_tool.cc
More file actions
113 lines (99 loc) · 3.77 KB
/
Copy pathmksnapshot_tool.cc
File metadata and controls
113 lines (99 loc) · 3.77 KB
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
// mksnapshot_tool - bakes preload.js into a custom V8 startup snapshot.
//
// mksnapshot_tool preload.js snapshot.bin
//
// Everything the preload script defines lands on the heap at build time.
// jsvm then deserializes it instead of parsing, compiling, and constructing it
// on every run. This is the single largest startup win available.
#include <cstdio>
#include <cstdlib>
#include <memory>
#include <string>
#include "include/libplatform/libplatform.h"
#include "include/v8.h"
#include "src/bindings.h"
int main(int argc, char* argv[]) {
if (argc != 3) {
fprintf(stderr, "usage: mksnapshot_tool <preload.js> <out.bin>\n");
return 2;
}
const std::string preload_path = argv[1];
const std::string out_path = argv[2];
std::string preload;
if (!jsvm::ReadFile(preload_path, &preload)) {
fprintf(stderr, "mksnapshot_tool: cannot read %s\n", preload_path.c_str());
return 2;
}
// MUST match jsvm.cc, and must precede V8::Initialize(). V8 hashes the flag
// set into the blob; a mismatch does not fail here, it makes
// Context::FromSnapshot return an empty MaybeLocal at runtime.
v8::V8::SetFlagsFromString(jsvm::kV8Flags);
std::unique_ptr<v8::Platform> platform =
v8::platform::NewSingleThreadedDefaultPlatform();
v8::V8::InitializePlatform(platform.get());
v8::V8::Initialize();
v8::StartupData blob{nullptr, 0};
int status = 0;
{
// VERSION RISK: this is the most volatile API in the file. SnapshotCreator
// has been reshaped repeatedly. Alternatives, newest first:
//
// v8::Isolate::CreateParams p;
// p.array_buffer_allocator = ...;
// v8::SnapshotCreator creator(p, jsvm::kExternalReferences);
//
// v8::SnapshotCreator creator(isolate, jsvm::kExternalReferences);
//
// Check include/v8-snapshot.h for the constructors your checkout has.
v8::SnapshotCreator creator(jsvm::kExternalReferences);
v8::Isolate* isolate = creator.GetIsolate();
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
jsvm::InstallGlobals(isolate, global);
v8::Local<v8::Context> context =
v8::Context::New(isolate, nullptr, global);
{
v8::Context::Scope context_scope(context);
v8::TryCatch try_catch(isolate);
v8::Local<v8::String> source = jsvm::Str(isolate, preload);
v8::Local<v8::Script> script;
if (!v8::Script::Compile(context, source).ToLocal(&script) ||
script->Run(context).IsEmpty()) {
fprintf(stderr, "mksnapshot_tool: preload failed\n");
jsvm::ReportException(isolate, &try_catch);
status = 1;
}
isolate->PerformMicrotaskCheckpoint();
}
if (status == 0) {
// Index 0, which jsvm passes to Context::FromSnapshot.
creator.SetDefaultContext(context);
}
}
if (status == 0) {
// kKeep retains compiled code in the blob: larger file, faster start.
// Safe here because the same build produces both binary and snapshot.
// Switch to kClear if you need the blob to be smaller.
blob = creator.CreateBlob(
v8::SnapshotCreator::FunctionCodeHandling::kKeep);
}
}
if (status == 0) {
if (blob.data == nullptr || blob.raw_size <= 0) {
fprintf(stderr, "mksnapshot_tool: empty blob\n");
status = 1;
} else if (!jsvm::WriteFile(out_path, blob.data,
static_cast<size_t>(blob.raw_size))) {
fprintf(stderr, "mksnapshot_tool: cannot write %s\n", out_path.c_str());
status = 1;
} else {
fprintf(stderr, "mksnapshot_tool: wrote %s (%d bytes)\n",
out_path.c_str(), blob.raw_size);
}
}
delete[] blob.data;
v8::V8::Dispose();
v8::V8::DisposePlatform();
return status;
}