Skip to content

Commit 736a04a

Browse files
joyeecheungRafaelGSS
authored andcommitted
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 <legendecas@gmail.com>
1 parent bce827e commit 736a04a

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
@@ -989,7 +989,8 @@ struct SnapshotData {
989989
enum class DataOwnership { kOwned, kNotOwned };
990990

991991
static const uint32_t kMagic = 0x143da19;
992-
static const SnapshotIndex kNodeBaseContextIndex = 0;
992+
static const SnapshotIndex kNodeVMContextIndex = 0;
993+
static const SnapshotIndex kNodeBaseContextIndex = kNodeVMContextIndex + 1;
993994
static const SnapshotIndex kNodeMainContextIndex = kNodeBaseContextIndex + 1;
994995

995996
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"
@@ -31,6 +32,7 @@ using v8::HandleScope;
3132
using v8::Isolate;
3233
using v8::Local;
3334
using v8::Object;
35+
using v8::ObjectTemplate;
3436
using v8::ScriptCompiler;
3537
using v8::ScriptOrigin;
3638
using v8::SnapshotCreator;
@@ -922,6 +924,19 @@ int SnapshotBuilder::Generate(SnapshotData* out,
922924
// The default context with only things created by V8.
923925
Local<Context> default_context = Context::New(isolate);
924926

927+
// The context used by the vm module.
928+
Local<Context> vm_context;
929+
{
930+
Local<ObjectTemplate> global_template =
931+
main_instance->isolate_data()->contextify_global_template();
932+
CHECK(!global_template.IsEmpty());
933+
if (!contextify::ContextifyContext::CreateV8Context(
934+
isolate, global_template, nullptr, nullptr)
935+
.ToLocal(&vm_context)) {
936+
return SNAPSHOT_ERROR;
937+
}
938+
}
939+
925940
// The Node.js-specific context with primodials, can be used by workers
926941
// TODO(joyeecheung): investigate if this can be used by vm contexts
927942
// without breaking compatibility.
@@ -1003,7 +1018,9 @@ int SnapshotBuilder::Generate(SnapshotData* out,
10031018
// blob is created. So initialize all the contexts before adding them.
10041019
// TODO(joyeecheung): figure out how to remove this restriction.
10051020
creator.SetDefaultContext(default_context);
1006-
size_t index = creator.AddContext(base_context);
1021+
size_t index = creator.AddContext(vm_context);
1022+
CHECK_EQ(index, SnapshotData::kNodeVMContextIndex);
1023+
index = creator.AddContext(base_context);
10071024
CHECK_EQ(index, SnapshotData::kNodeBaseContextIndex);
10081025
index = creator.AddContext(main_context,
10091026
{SerializeNodeContextInternalFields, env});

0 commit comments

Comments
 (0)