Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9bf9ddb

Browse filesBrowse files
joyeecheungtargos
authored andcommitted
tools: refactor snapshot builder
This patch: - Moves the snapshot building code to src/ so that we can reuse it later when generating custom snapshots from an entry point accepted by the node binary. - Create a SnapshotData struct that incorporates all the data useful for a snapshot blob, including both the V8 data and the Node.js data. PR-URL: #38902 Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
1 parent 711916a commit 9bf9ddb
Copy full SHA for 9bf9ddb

File tree

Expand file treeCollapse file tree

11 files changed

+189
-196
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

11 files changed

+189
-196
lines changed
Open diff view settings
Collapse file

‎node.gyp‎

Copy file name to clipboardExpand all lines: node.gyp
-2Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,8 +1554,6 @@
15541554
'src/node_snapshot_stub.cc',
15551555
'src/node_code_cache_stub.cc',
15561556
'tools/snapshot/node_mksnapshot.cc',
1557-
'tools/snapshot/snapshot_builder.cc',
1558-
'tools/snapshot/snapshot_builder.h',
15591557
],
15601558

15611559
'conditions': [
Collapse file

‎src/env.h‎

Copy file name to clipboardExpand all lines: src/env.h
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,13 @@ struct EnvSerializeInfo {
955955
friend std::ostream& operator<<(std::ostream& o, const EnvSerializeInfo& i);
956956
};
957957

958+
struct SnapshotData {
959+
SnapshotData() { blob.data = nullptr; }
960+
v8::StartupData blob;
961+
std::vector<size_t> isolate_data_indices;
962+
EnvSerializeInfo env_info;
963+
};
964+
958965
class Environment : public MemoryRetainer {
959966
public:
960967
Environment(const Environment&) = delete;
Collapse file

‎src/node.cc‎

Copy file name to clipboardExpand all lines: src/node.cc
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,15 +1130,15 @@ int Start(int argc, char** argv) {
11301130

11311131
{
11321132
Isolate::CreateParams params;
1133-
const std::vector<size_t>* indexes = nullptr;
1133+
const std::vector<size_t>* indices = nullptr;
11341134
const EnvSerializeInfo* env_info = nullptr;
11351135
bool force_no_snapshot =
11361136
per_process::cli_options->per_isolate->no_node_snapshot;
11371137
if (!force_no_snapshot) {
11381138
v8::StartupData* blob = NodeMainInstance::GetEmbeddedSnapshotBlob();
11391139
if (blob != nullptr) {
11401140
params.snapshot_blob = blob;
1141-
indexes = NodeMainInstance::GetIsolateDataIndexes();
1141+
indices = NodeMainInstance::GetIsolateDataIndices();
11421142
env_info = NodeMainInstance::GetEnvSerializeInfo();
11431143
}
11441144
}
@@ -1149,7 +1149,7 @@ int Start(int argc, char** argv) {
11491149
per_process::v8_platform.Platform(),
11501150
result.args,
11511151
result.exec_args,
1152-
indexes);
1152+
indices);
11531153
result.exit_code = main_instance.Run(env_info);
11541154
}
11551155

Collapse file

‎src/node_main_instance.h‎

Copy file name to clipboardExpand all lines: src/node_main_instance.h
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class NodeMainInstance {
6767

6868
// If nullptr is returned, the binary is not built with embedded
6969
// snapshot.
70-
static const std::vector<size_t>* GetIsolateDataIndexes();
70+
static const std::vector<size_t>* GetIsolateDataIndices();
7171
static v8::StartupData* GetEmbeddedSnapshotBlob();
7272
static const EnvSerializeInfo* GetEnvSerializeInfo();
7373
static const std::vector<intptr_t>& CollectExternalReferences();
Collapse file

‎src/node_snapshot_stub.cc‎

Copy file name to clipboardExpand all lines: src/node_snapshot_stub.cc
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ v8::StartupData* NodeMainInstance::GetEmbeddedSnapshotBlob() {
1010
return nullptr;
1111
}
1212

13-
const std::vector<size_t>* NodeMainInstance::GetIsolateDataIndexes() {
13+
const std::vector<size_t>* NodeMainInstance::GetIsolateDataIndices() {
1414
return nullptr;
1515
}
1616

Collapse file

‎src/node_snapshotable.cc‎

Copy file name to clipboardExpand all lines: src/node_snapshotable.cc
+165Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,181 @@
11

22
#include "node_snapshotable.h"
3+
#include <iostream>
4+
#include <sstream>
35
#include "base_object-inl.h"
46
#include "debug_utils-inl.h"
7+
#include "env-inl.h"
8+
#include "node_errors.h"
9+
#include "node_external_reference.h"
510
#include "node_file.h"
11+
#include "node_internals.h"
12+
#include "node_main_instance.h"
613
#include "node_v8.h"
14+
#include "node_v8_platform-inl.h"
715

816
namespace node {
917

18+
using v8::Context;
19+
using v8::HandleScope;
20+
using v8::Isolate;
1021
using v8::Local;
1122
using v8::Object;
1223
using v8::SnapshotCreator;
1324
using v8::StartupData;
25+
using v8::TryCatch;
26+
using v8::Value;
27+
28+
template <typename T>
29+
void WriteVector(std::ostringstream* ss, const T* vec, size_t size) {
30+
for (size_t i = 0; i < size; i++) {
31+
*ss << std::to_string(vec[i]) << (i == size - 1 ? '\n' : ',');
32+
}
33+
}
34+
35+
std::string FormatBlob(SnapshotData* data) {
36+
std::ostringstream ss;
37+
38+
ss << R"(#include <cstddef>
39+
#include "env.h"
40+
#include "node_main_instance.h"
41+
#include "v8.h"
42+
43+
// This file is generated by tools/snapshot. Do not edit.
44+
45+
namespace node {
46+
47+
static const char blob_data[] = {
48+
)";
49+
WriteVector(&ss, data->blob.data, data->blob.raw_size);
50+
ss << R"(};
51+
52+
static const int blob_size = )"
53+
<< data->blob.raw_size << R"(;
54+
static v8::StartupData blob = { blob_data, blob_size };
55+
)";
56+
57+
ss << R"(v8::StartupData* NodeMainInstance::GetEmbeddedSnapshotBlob() {
58+
return &blob;
59+
}
60+
61+
static const std::vector<size_t> isolate_data_indices {
62+
)";
63+
WriteVector(&ss,
64+
data->isolate_data_indices.data(),
65+
data->isolate_data_indices.size());
66+
ss << R"(};
67+
68+
const std::vector<size_t>* NodeMainInstance::GetIsolateDataIndices() {
69+
return &isolate_data_indices;
70+
}
71+
72+
static const EnvSerializeInfo env_info )"
73+
<< data->env_info << R"(;
74+
75+
const EnvSerializeInfo* NodeMainInstance::GetEnvSerializeInfo() {
76+
return &env_info;
77+
}
78+
79+
} // namespace node
80+
)";
81+
82+
return ss.str();
83+
}
84+
85+
void SnapshotBuilder::Generate(SnapshotData* out,
86+
const std::vector<std::string> args,
87+
const std::vector<std::string> exec_args) {
88+
Isolate* isolate = Isolate::Allocate();
89+
isolate->SetCaptureStackTraceForUncaughtExceptions(
90+
true, 10, v8::StackTrace::StackTraceOptions::kDetailed);
91+
per_process::v8_platform.Platform()->RegisterIsolate(isolate,
92+
uv_default_loop());
93+
std::unique_ptr<NodeMainInstance> main_instance;
94+
std::string result;
95+
96+
{
97+
const std::vector<intptr_t>& external_references =
98+
NodeMainInstance::CollectExternalReferences();
99+
SnapshotCreator creator(isolate, external_references.data());
100+
Environment* env;
101+
{
102+
main_instance =
103+
NodeMainInstance::Create(isolate,
104+
uv_default_loop(),
105+
per_process::v8_platform.Platform(),
106+
args,
107+
exec_args);
108+
109+
HandleScope scope(isolate);
110+
creator.SetDefaultContext(Context::New(isolate));
111+
out->isolate_data_indices =
112+
main_instance->isolate_data()->Serialize(&creator);
113+
114+
// Run the per-context scripts
115+
Local<Context> context;
116+
{
117+
TryCatch bootstrapCatch(isolate);
118+
context = NewContext(isolate);
119+
if (bootstrapCatch.HasCaught()) {
120+
PrintCaughtException(isolate, context, bootstrapCatch);
121+
abort();
122+
}
123+
}
124+
Context::Scope context_scope(context);
125+
126+
// Create the environment
127+
env = new Environment(main_instance->isolate_data(),
128+
context,
129+
args,
130+
exec_args,
131+
nullptr,
132+
node::EnvironmentFlags::kDefaultFlags,
133+
{});
134+
// Run scripts in lib/internal/bootstrap/
135+
{
136+
TryCatch bootstrapCatch(isolate);
137+
v8::MaybeLocal<Value> result = env->RunBootstrapping();
138+
if (bootstrapCatch.HasCaught()) {
139+
PrintCaughtException(isolate, context, bootstrapCatch);
140+
}
141+
result.ToLocalChecked();
142+
}
143+
144+
if (per_process::enabled_debug_list.enabled(DebugCategory::MKSNAPSHOT)) {
145+
env->PrintAllBaseObjects();
146+
printf("Environment = %p\n", env);
147+
}
148+
149+
// Serialize the native states
150+
out->env_info = env->Serialize(&creator);
151+
// Serialize the context
152+
size_t index = creator.AddContext(
153+
context, {SerializeNodeContextInternalFields, env});
154+
CHECK_EQ(index, NodeMainInstance::kNodeContextIndex);
155+
}
156+
157+
// Must be out of HandleScope
158+
out->blob =
159+
creator.CreateBlob(SnapshotCreator::FunctionCodeHandling::kClear);
160+
CHECK(out->blob.CanBeRehashed());
161+
// Must be done while the snapshot creator isolate is entered i.e. the
162+
// creator is still alive.
163+
FreeEnvironment(env);
164+
main_instance->Dispose();
165+
}
166+
167+
per_process::v8_platform.Platform()->UnregisterIsolate(isolate);
168+
}
169+
170+
std::string SnapshotBuilder::Generate(
171+
const std::vector<std::string> args,
172+
const std::vector<std::string> exec_args) {
173+
SnapshotData data;
174+
Generate(&data, args, exec_args);
175+
std::string result = FormatBlob(&data);
176+
delete[] data.blob.data;
177+
return result;
178+
}
14179

15180
SnapshotableObject::SnapshotableObject(Environment* env,
16181
Local<Object> wrap,
Collapse file

‎src/node_snapshotable.h‎

Copy file name to clipboardExpand all lines: src/node_snapshotable.h
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace node {
1111

1212
class Environment;
1313
struct EnvSerializeInfo;
14+
struct SnapshotData;
1415

1516
#define SERIALIZABLE_OBJECT_TYPES(V) \
1617
V(fs_binding_data, fs::BindingData) \
@@ -119,6 +120,15 @@ void SerializeBindingData(Environment* env,
119120
EnvSerializeInfo* info);
120121

121122
bool IsSnapshotableType(FastStringKey key);
123+
124+
class SnapshotBuilder {
125+
public:
126+
static std::string Generate(const std::vector<std::string> args,
127+
const std::vector<std::string> exec_args);
128+
static void Generate(SnapshotData* out,
129+
const std::vector<std::string> args,
130+
const std::vector<std::string> exec_args);
131+
};
122132
} // namespace node
123133

124134
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
Collapse file

‎tools/snapshot/README.md‎

Copy file name to clipboardExpand all lines: tools/snapshot/README.md
+1-1Lines changed: 1 addition & 1 deletion
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ into the Node.js executable, `libnode` is first built with these unresolved
2323
symbols:
2424

2525
- `node::NodeMainInstance::GetEmbeddedSnapshotBlob`
26-
- `node::NodeMainInstance::GetIsolateDataIndexes`
26+
- `node::NodeMainInstance::GetIsolateDataIndices`
2727

2828
Then the `node_mksnapshot` executable is built with C++ files in this
2929
directory, as well as `src/node_snapshot_stub.cc` which defines the unresolved
Collapse file

‎tools/snapshot/node_mksnapshot.cc‎

Copy file name to clipboardExpand all lines: tools/snapshot/node_mksnapshot.cc
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#include "libplatform/libplatform.h"
99
#include "node_internals.h"
10-
#include "snapshot_builder.h"
10+
#include "node_snapshotable.h"
1111
#include "util-inl.h"
1212
#include "v8.h"
1313

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.