Skip to content

Commit a113d43

Browse files
joyeecheungjuanarbol
authored andcommitted
bootstrap: use SnapshotData to pass snapshot data around
Instead of passing the snapshot blob, the per-isolate data indices and the EnvSerializeInfo separately, use the aggregate type Snapshot to carry these around, and refactor NodeMainInstance so that it owns the v8::Isolate::CreateParams when it owns its isolate. This also gets rid of the owns_isolate_ and deserialize_mode_ booleans in NodeMainInstance since NodeMainInstance can compute these by just checking if it has pointers to the CreateParams or the SnapshotData. PR-URL: #42360 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Darshan Sen <[email protected]>
1 parent bd688f7 commit a113d43

7 files changed

+72
-95
lines changed

src/env.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "node_binding.h"
3737
#include "node_external_reference.h"
3838
#include "node_main_instance.h"
39+
#include "node_native_module.h"
3940
#include "node_options.h"
4041
#include "node_perf_common.h"
4142
#include "node_snapshotable.h"
@@ -972,7 +973,6 @@ struct EnvSerializeInfo {
972973
};
973974

974975
struct SnapshotData {
975-
SnapshotData() { blob.data = nullptr; }
976976
v8::StartupData blob;
977977
std::vector<size_t> isolate_data_indices;
978978
EnvSerializeInfo env_info;

src/node.cc

+6-15
Original file line numberDiff line numberDiff line change
@@ -1145,28 +1145,19 @@ int Start(int argc, char** argv) {
11451145
}
11461146

11471147
{
1148-
Isolate::CreateParams params;
1149-
const std::vector<size_t>* indices = nullptr;
1150-
const EnvSerializeInfo* env_info = nullptr;
11511148
bool use_node_snapshot =
11521149
per_process::cli_options->per_isolate->node_snapshot;
1153-
if (use_node_snapshot) {
1154-
v8::StartupData* blob = NodeMainInstance::GetEmbeddedSnapshotBlob();
1155-
if (blob != nullptr) {
1156-
params.snapshot_blob = blob;
1157-
indices = NodeMainInstance::GetIsolateDataIndices();
1158-
env_info = NodeMainInstance::GetEnvSerializeInfo();
1159-
}
1160-
}
1150+
const SnapshotData* snapshot_data =
1151+
use_node_snapshot ? NodeMainInstance::GetEmbeddedSnapshotData()
1152+
: nullptr;
11611153
uv_loop_configure(uv_default_loop(), UV_METRICS_IDLE_TIME);
11621154

1163-
NodeMainInstance main_instance(&params,
1155+
NodeMainInstance main_instance(snapshot_data,
11641156
uv_default_loop(),
11651157
per_process::v8_platform.Platform(),
11661158
result.args,
1167-
result.exec_args,
1168-
indices);
1169-
result.exit_code = main_instance.Run(env_info);
1159+
result.exec_args);
1160+
result.exit_code = main_instance.Run();
11701161
}
11711162

11721163
TearDownOncePerProcess();

src/node_main_instance.cc

+36-35
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ NodeMainInstance::NodeMainInstance(Isolate* isolate,
3636
isolate_(isolate),
3737
platform_(platform),
3838
isolate_data_(nullptr),
39-
owns_isolate_(false),
40-
deserialize_mode_(false) {
39+
snapshot_data_(nullptr) {
4140
isolate_data_ =
4241
std::make_unique<IsolateData>(isolate_, event_loop, platform, nullptr);
4342

@@ -61,77 +60,81 @@ std::unique_ptr<NodeMainInstance> NodeMainInstance::Create(
6160
new NodeMainInstance(isolate, event_loop, platform, args, exec_args));
6261
}
6362

64-
NodeMainInstance::NodeMainInstance(
65-
Isolate::CreateParams* params,
66-
uv_loop_t* event_loop,
67-
MultiIsolatePlatform* platform,
68-
const std::vector<std::string>& args,
69-
const std::vector<std::string>& exec_args,
70-
const std::vector<size_t>* per_isolate_data_indexes)
63+
NodeMainInstance::NodeMainInstance(const SnapshotData* snapshot_data,
64+
uv_loop_t* event_loop,
65+
MultiIsolatePlatform* platform,
66+
const std::vector<std::string>& args,
67+
const std::vector<std::string>& exec_args)
7168
: args_(args),
7269
exec_args_(exec_args),
7370
array_buffer_allocator_(ArrayBufferAllocator::Create()),
7471
isolate_(nullptr),
7572
platform_(platform),
76-
isolate_data_(nullptr),
77-
owns_isolate_(true) {
78-
params->array_buffer_allocator = array_buffer_allocator_.get();
79-
deserialize_mode_ = per_isolate_data_indexes != nullptr;
80-
if (deserialize_mode_) {
73+
isolate_data_(),
74+
isolate_params_(std::make_unique<Isolate::CreateParams>()),
75+
snapshot_data_(snapshot_data) {
76+
isolate_params_->array_buffer_allocator = array_buffer_allocator_.get();
77+
if (snapshot_data != nullptr) {
8178
// TODO(joyeecheung): collect external references and set it in
8279
// params.external_references.
8380
const std::vector<intptr_t>& external_references =
8481
CollectExternalReferences();
85-
params->external_references = external_references.data();
82+
isolate_params_->external_references = external_references.data();
83+
isolate_params_->snapshot_blob =
84+
const_cast<v8::StartupData*>(&(snapshot_data->blob));
8685
}
8786

8887
isolate_ = Isolate::Allocate();
8988
CHECK_NOT_NULL(isolate_);
9089
// Register the isolate on the platform before the isolate gets initialized,
9190
// so that the isolate can access the platform during initialization.
9291
platform->RegisterIsolate(isolate_, event_loop);
93-
SetIsolateCreateParamsForNode(params);
94-
Isolate::Initialize(isolate_, *params);
92+
SetIsolateCreateParamsForNode(isolate_params_.get());
93+
Isolate::Initialize(isolate_, *isolate_params_);
9594

9695
// If the indexes are not nullptr, we are not deserializing
97-
CHECK_IMPLIES(deserialize_mode_, params->external_references != nullptr);
98-
isolate_data_ = std::make_unique<IsolateData>(isolate_,
99-
event_loop,
100-
platform,
101-
array_buffer_allocator_.get(),
102-
per_isolate_data_indexes);
96+
isolate_data_ = std::make_unique<IsolateData>(
97+
isolate_,
98+
event_loop,
99+
platform,
100+
array_buffer_allocator_.get(),
101+
snapshot_data == nullptr ? nullptr
102+
: &(snapshot_data->isolate_data_indices));
103103
IsolateSettings s;
104104
SetIsolateMiscHandlers(isolate_, s);
105-
if (!deserialize_mode_) {
105+
if (snapshot_data == nullptr) {
106106
// If in deserialize mode, delay until after the deserialization is
107107
// complete.
108108
SetIsolateErrorHandlers(isolate_, s);
109109
}
110110
isolate_data_->max_young_gen_size =
111-
params->constraints.max_young_generation_size_in_bytes();
111+
isolate_params_->constraints.max_young_generation_size_in_bytes();
112112
}
113113

114114
void NodeMainInstance::Dispose() {
115-
CHECK(!owns_isolate_);
115+
// This should only be called on a main instance that does not own its
116+
// isolate.
117+
CHECK_NULL(isolate_params_);
116118
platform_->DrainTasks(isolate_);
117119
}
118120

119121
NodeMainInstance::~NodeMainInstance() {
120-
if (!owns_isolate_) {
122+
if (isolate_params_ == nullptr) {
121123
return;
122124
}
125+
// This should only be done on a main instance that owns its isolate.
123126
platform_->UnregisterIsolate(isolate_);
124127
isolate_->Dispose();
125128
}
126129

127-
int NodeMainInstance::Run(const EnvSerializeInfo* env_info) {
130+
int NodeMainInstance::Run() {
128131
Locker locker(isolate_);
129132
Isolate::Scope isolate_scope(isolate_);
130133
HandleScope handle_scope(isolate_);
131134

132135
int exit_code = 0;
133136
DeleteFnPtr<Environment, FreeEnvironment> env =
134-
CreateMainEnvironment(&exit_code, env_info);
137+
CreateMainEnvironment(&exit_code);
135138
CHECK_NOT_NULL(env);
136139

137140
Context::Scope context_scope(env->context());
@@ -167,8 +170,7 @@ void NodeMainInstance::Run(int* exit_code, Environment* env) {
167170
}
168171

169172
DeleteFnPtr<Environment, FreeEnvironment>
170-
NodeMainInstance::CreateMainEnvironment(int* exit_code,
171-
const EnvSerializeInfo* env_info) {
173+
NodeMainInstance::CreateMainEnvironment(int* exit_code) {
172174
*exit_code = 0; // Reset the exit code to 0
173175

174176
HandleScope handle_scope(isolate_);
@@ -179,16 +181,15 @@ NodeMainInstance::CreateMainEnvironment(int* exit_code,
179181
isolate_->GetHeapProfiler()->StartTrackingHeapObjects(true);
180182
}
181183

182-
CHECK_IMPLIES(deserialize_mode_, env_info != nullptr);
183184
Local<Context> context;
184185
DeleteFnPtr<Environment, FreeEnvironment> env;
185186

186-
if (deserialize_mode_) {
187+
if (snapshot_data_ != nullptr) {
187188
env.reset(new Environment(isolate_data_.get(),
188189
isolate_,
189190
args_,
190191
exec_args_,
191-
env_info,
192+
&(snapshot_data_->env_info),
192193
EnvironmentFlags::kDefaultFlags,
193194
{}));
194195
context = Context::FromSnapshot(isolate_,
@@ -200,7 +201,7 @@ NodeMainInstance::CreateMainEnvironment(int* exit_code,
200201
Context::Scope context_scope(context);
201202
CHECK(InitializeContextRuntime(context).IsJust());
202203
SetIsolateErrorHandlers(isolate_, {});
203-
env->InitializeMainContext(context, env_info);
204+
env->InitializeMainContext(context, &(snapshot_data_->env_info));
204205
#if HAVE_INSPECTOR
205206
env->InitializeInspector({});
206207
#endif

src/node_main_instance.h

+11-14
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace node {
1515

1616
class ExternalReferenceRegistry;
1717
struct EnvSerializeInfo;
18+
struct SnapshotData;
1819

1920
// TODO(joyeecheung): align this with the Worker/WorkerThreadData class.
2021
// We may be able to create an abstract class to reuse some of the routines.
@@ -48,29 +49,25 @@ class NodeMainInstance {
4849
void Dispose();
4950

5051
// Create a main instance that owns the isolate
51-
NodeMainInstance(
52-
v8::Isolate::CreateParams* params,
53-
uv_loop_t* event_loop,
54-
MultiIsolatePlatform* platform,
55-
const std::vector<std::string>& args,
56-
const std::vector<std::string>& exec_args,
57-
const std::vector<size_t>* per_isolate_data_indexes = nullptr);
52+
NodeMainInstance(const SnapshotData* snapshot_data,
53+
uv_loop_t* event_loop,
54+
MultiIsolatePlatform* platform,
55+
const std::vector<std::string>& args,
56+
const std::vector<std::string>& exec_args);
5857
~NodeMainInstance();
5958

6059
// Start running the Node.js instances, return the exit code when finished.
61-
int Run(const EnvSerializeInfo* env_info);
60+
int Run();
6261
void Run(int* exit_code, Environment* env);
6362

6463
IsolateData* isolate_data() { return isolate_data_.get(); }
6564

6665
DeleteFnPtr<Environment, FreeEnvironment> CreateMainEnvironment(
67-
int* exit_code, const EnvSerializeInfo* env_info);
66+
int* exit_code);
6867

6968
// If nullptr is returned, the binary is not built with embedded
7069
// snapshot.
71-
static const std::vector<size_t>* GetIsolateDataIndices();
72-
static v8::StartupData* GetEmbeddedSnapshotBlob();
73-
static const EnvSerializeInfo* GetEnvSerializeInfo();
70+
static const SnapshotData* GetEmbeddedSnapshotData();
7471
static const std::vector<intptr_t>& CollectExternalReferences();
7572

7673
static const size_t kNodeContextIndex = 0;
@@ -93,8 +90,8 @@ class NodeMainInstance {
9390
v8::Isolate* isolate_;
9491
MultiIsolatePlatform* platform_;
9592
std::unique_ptr<IsolateData> isolate_data_;
96-
bool owns_isolate_ = false;
97-
bool deserialize_mode_ = false;
93+
std::unique_ptr<v8::Isolate::CreateParams> isolate_params_;
94+
const SnapshotData* snapshot_data_ = nullptr;
9895
};
9996

10097
} // namespace node

src/node_snapshot_stub.cc

+1-9
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,7 @@
66

77
namespace node {
88

9-
v8::StartupData* NodeMainInstance::GetEmbeddedSnapshotBlob() {
10-
return nullptr;
11-
}
12-
13-
const std::vector<size_t>* NodeMainInstance::GetIsolateDataIndices() {
14-
return nullptr;
15-
}
16-
17-
const EnvSerializeInfo* NodeMainInstance::GetEnvSerializeInfo() {
9+
const SnapshotData* NodeMainInstance::GetEmbeddedSnapshotData() {
1810
return nullptr;
1911
}
2012

src/node_snapshotable.cc

+16-19
Original file line numberDiff line numberDiff line change
@@ -53,31 +53,28 @@ static const char blob_data[] = {
5353
5454
static const int blob_size = )"
5555
<< data->blob.raw_size << R"(;
56-
static v8::StartupData blob = { blob_data, blob_size };
57-
)";
58-
59-
ss << R"(v8::StartupData* NodeMainInstance::GetEmbeddedSnapshotBlob() {
60-
return &blob;
61-
}
6256
63-
static const std::vector<size_t> isolate_data_indices {
57+
SnapshotData snapshot_data {
58+
// -- blob begins --
59+
{ blob_data, blob_size },
60+
// -- blob ends --
61+
// -- isolate_data_indices begins --
62+
{
6463
)";
6564
WriteVector(&ss,
6665
data->isolate_data_indices.data(),
6766
data->isolate_data_indices.size());
68-
ss << R"(};
69-
70-
const std::vector<size_t>* NodeMainInstance::GetIsolateDataIndices() {
71-
return &isolate_data_indices;
67+
ss << R"(},
68+
// -- isolate_data_indices ends --
69+
// -- env_info begins --
70+
)" << data->env_info
71+
<< R"(
72+
// -- env_info ends --
73+
};
74+
75+
const SnapshotData* NodeMainInstance::GetEmbeddedSnapshotData() {
76+
return &snapshot_data;
7277
}
73-
74-
static const EnvSerializeInfo env_info )"
75-
<< data->env_info << R"(;
76-
77-
const EnvSerializeInfo* NodeMainInstance::GetEnvSerializeInfo() {
78-
return &env_info;
79-
}
80-
8178
} // namespace node
8279
)";
8380

tools/snapshot/README.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ In the default build of the Node.js executable, to embed a V8 startup snapshot
2222
into the Node.js executable, `libnode` is first built with these unresolved
2323
symbols:
2424

25-
- `node::NodeMainInstance::GetEmbeddedSnapshotBlob`
26-
- `node::NodeMainInstance::GetIsolateDataIndices`
25+
- `node::NodeMainInstance::GetEmbeddedSnapshotData`
2726

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

0 commit comments

Comments
 (0)