Skip to content

Commit ec91776

Browse files
committedAug 23, 2022
vm: include vm context in the embedded snapshot
Include a minimally initialized contextify context in the embedded snapshot. This paves the way for user-land vm context snapshots. PR-URL: #44252 Refs: #44014 Refs: #37476 Reviewed-By: Chengzhong Wu <[email protected]>
1 parent cfd25e0 commit ec91776

File tree

4 files changed

+45
-11
lines changed

4 files changed

+45
-11
lines changed
 

‎src/env.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,8 @@ struct SnapshotData {
10021002
enum class DataOwnership { kOwned, kNotOwned };
10031003

10041004
static const uint32_t kMagic = 0x143da19;
1005-
static const SnapshotIndex kNodeBaseContextIndex = 0;
1005+
static const SnapshotIndex kNodeVMContextIndex = 0;
1006+
static const SnapshotIndex kNodeBaseContextIndex = kNodeVMContextIndex + 1;
10061007
static const SnapshotIndex kNodeMainContextIndex = kNodeBaseContextIndex + 1;
10071008

10081009
DataOwnership data_ownership = DataOwnership::kOwned;

‎src/node_contextify.cc

+24-9
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "node_errors.h"
2929
#include "node_external_reference.h"
3030
#include "node_internals.h"
31+
#include "node_snapshot_builder.h"
3132
#include "node_watchdog.h"
3233
#include "util-inl.h"
3334

@@ -118,14 +119,17 @@ ContextifyContext::ContextifyContext(
118119
object_template = CreateGlobalTemplate(env->isolate());
119120
env->set_contextify_global_template(object_template);
120121
}
122+
bool use_node_snapshot = per_process::cli_options->node_snapshot;
123+
const SnapshotData* snapshot_data =
124+
use_node_snapshot ? SnapshotBuilder::GetEmbeddedSnapshotData() : nullptr;
121125

122126
MicrotaskQueue* queue =
123127
microtask_queue()
124128
? microtask_queue().get()
125129
: env->isolate()->GetCurrentContext()->GetMicrotaskQueue();
126130

127131
Local<Context> v8_context;
128-
if (!(CreateV8Context(env->isolate(), object_template, queue)
132+
if (!(CreateV8Context(env->isolate(), object_template, snapshot_data, queue)
129133
.ToLocal(&v8_context)) ||
130134
!InitializeContext(v8_context, env, sandbox_obj, options)) {
131135
// Allocation failure, maximum call stack size reached, termination, etc.
@@ -190,17 +194,28 @@ Local<ObjectTemplate> ContextifyContext::CreateGlobalTemplate(
190194
MaybeLocal<Context> ContextifyContext::CreateV8Context(
191195
Isolate* isolate,
192196
Local<ObjectTemplate> object_template,
197+
const SnapshotData* snapshot_data,
193198
MicrotaskQueue* queue) {
194199
EscapableHandleScope scope(isolate);
195200

196-
Local<Context> ctx = Context::New(isolate,
197-
nullptr, // extensions
198-
object_template,
199-
{}, // global object
200-
{}, // deserialization callback
201-
queue);
202-
if (ctx.IsEmpty()) return MaybeLocal<Context>();
203-
201+
Local<Context> ctx;
202+
if (snapshot_data == nullptr) {
203+
ctx = Context::New(isolate,
204+
nullptr, // extensions
205+
object_template,
206+
{}, // global object
207+
{}, // deserialization callback
208+
queue);
209+
if (ctx.IsEmpty()) return MaybeLocal<Context>();
210+
} else if (!Context::FromSnapshot(isolate,
211+
SnapshotData::kNodeVMContextIndex,
212+
{}, // deserialization callback
213+
nullptr, // extensions
214+
{}, // global object
215+
queue)
216+
.ToLocal(&ctx)) {
217+
return MaybeLocal<Context>();
218+
}
204219
return scope.Escape(ctx);
205220
}
206221

‎src/node_contextify.h

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class ContextifyContext {
5252
static v8::MaybeLocal<v8::Context> CreateV8Context(
5353
v8::Isolate* isolate,
5454
v8::Local<v8::ObjectTemplate> object_template,
55+
const SnapshotData* snapshot_data,
5556
v8::MicrotaskQueue* queue);
5657
bool InitializeContext(v8::Local<v8::Context> ctx,
5758
Environment* env,

‎src/node_snapshotable.cc

+18-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "env-inl.h"
88
#include "node_blob.h"
99
#include "node_builtins.h"
10+
#include "node_contextify.h"
1011
#include "node_errors.h"
1112
#include "node_external_reference.h"
1213
#include "node_file.h"
@@ -32,6 +33,7 @@ using v8::HandleScope;
3233
using v8::Isolate;
3334
using v8::Local;
3435
using v8::Object;
36+
using v8::ObjectTemplate;
3537
using v8::ScriptCompiler;
3638
using v8::ScriptOrigin;
3739
using v8::SnapshotCreator;
@@ -1031,6 +1033,19 @@ int SnapshotBuilder::Generate(SnapshotData* out,
10311033
// The default context with only things created by V8.
10321034
Local<Context> default_context = Context::New(isolate);
10331035

1036+
// The context used by the vm module.
1037+
Local<Context> vm_context;
1038+
{
1039+
Local<ObjectTemplate> global_template =
1040+
main_instance->isolate_data()->contextify_global_template();
1041+
CHECK(!global_template.IsEmpty());
1042+
if (!contextify::ContextifyContext::CreateV8Context(
1043+
isolate, global_template, nullptr, nullptr)
1044+
.ToLocal(&vm_context)) {
1045+
return SNAPSHOT_ERROR;
1046+
}
1047+
}
1048+
10341049
// The Node.js-specific context with primodials, can be used by workers
10351050
// TODO(joyeecheung): investigate if this can be used by vm contexts
10361051
// without breaking compatibility.
@@ -1112,7 +1127,9 @@ int SnapshotBuilder::Generate(SnapshotData* out,
11121127
// blob is created. So initialize all the contexts before adding them.
11131128
// TODO(joyeecheung): figure out how to remove this restriction.
11141129
creator.SetDefaultContext(default_context);
1115-
size_t index = creator.AddContext(base_context);
1130+
size_t index = creator.AddContext(vm_context);
1131+
CHECK_EQ(index, SnapshotData::kNodeVMContextIndex);
1132+
index = creator.AddContext(base_context);
11161133
CHECK_EQ(index, SnapshotData::kNodeBaseContextIndex);
11171134
index = creator.AddContext(main_context,
11181135
{SerializeNodeContextInternalFields, env});

0 commit comments

Comments
 (0)
Please sign in to comment.