Skip to content

Commit 7900f65

Browse files
committed
vm: avoid unnecessary property getter interceptor calls
Access to the global object from within a vm context is intercepted so it's slow, therefore we should try to avoid unnecessary access to it during the initialization of vm contexts. - Remove the Atomics.wake deletion as V8 now does not install it anymore. - Move the Intl.v8BreakIterator deletion into the snapshot. - Do not query the Object prototype if --disable-proto is not set. This should speed up the creation of vm contexts by about ~12%. PR-URL: #44252 Refs: #44014 Refs: #37476 Reviewed-By: Chengzhong Wu <[email protected]>
1 parent ec91776 commit 7900f65

File tree

3 files changed

+44
-53
lines changed

3 files changed

+44
-53
lines changed

src/api/environment.cc

+33-46
Original file line numberDiff line numberDiff line change
@@ -556,50 +556,8 @@ Maybe<bool> InitializeContextRuntime(Local<Context> context) {
556556
Isolate* isolate = context->GetIsolate();
557557
HandleScope handle_scope(isolate);
558558

559-
// Delete `Intl.v8BreakIterator`
560-
// https://github.com/nodejs/node/issues/14909
561-
{
562-
Local<String> intl_string =
563-
FIXED_ONE_BYTE_STRING(isolate, "Intl");
564-
Local<String> break_iter_string =
565-
FIXED_ONE_BYTE_STRING(isolate, "v8BreakIterator");
566-
567-
Local<Value> intl_v;
568-
if (!context->Global()
569-
->Get(context, intl_string)
570-
.ToLocal(&intl_v)) {
571-
return Nothing<bool>();
572-
}
573-
574-
if (intl_v->IsObject() &&
575-
intl_v.As<Object>()
576-
->Delete(context, break_iter_string)
577-
.IsNothing()) {
578-
return Nothing<bool>();
579-
}
580-
}
581-
582-
// Delete `Atomics.wake`
583-
// https://github.com/nodejs/node/issues/21219
584-
{
585-
Local<String> atomics_string =
586-
FIXED_ONE_BYTE_STRING(isolate, "Atomics");
587-
Local<String> wake_string =
588-
FIXED_ONE_BYTE_STRING(isolate, "wake");
589-
590-
Local<Value> atomics_v;
591-
if (!context->Global()
592-
->Get(context, atomics_string)
593-
.ToLocal(&atomics_v)) {
594-
return Nothing<bool>();
595-
}
596-
597-
if (atomics_v->IsObject() &&
598-
atomics_v.As<Object>()
599-
->Delete(context, wake_string)
600-
.IsNothing()) {
601-
return Nothing<bool>();
602-
}
559+
if (per_process::cli_options->disable_proto == "") {
560+
return Just(true);
603561
}
604562

605563
// Remove __proto__
@@ -661,7 +619,32 @@ Maybe<bool> InitializeContextRuntime(Local<Context> context) {
661619
return Just(true);
662620
}
663621

664-
Maybe<bool> InitializeContextForSnapshot(Local<Context> context) {
622+
Maybe<bool> InitializeBaseContextForSnapshot(Local<Context> context) {
623+
Isolate* isolate = context->GetIsolate();
624+
HandleScope handle_scope(isolate);
625+
626+
// Delete `Intl.v8BreakIterator`
627+
// https://github.com/nodejs/node/issues/14909
628+
{
629+
Context::Scope context_scope(context);
630+
Local<String> intl_string = FIXED_ONE_BYTE_STRING(isolate, "Intl");
631+
Local<String> break_iter_string =
632+
FIXED_ONE_BYTE_STRING(isolate, "v8BreakIterator");
633+
634+
Local<Value> intl_v;
635+
if (!context->Global()->Get(context, intl_string).ToLocal(&intl_v)) {
636+
return Nothing<bool>();
637+
}
638+
639+
if (intl_v->IsObject() &&
640+
intl_v.As<Object>()->Delete(context, break_iter_string).IsNothing()) {
641+
return Nothing<bool>();
642+
}
643+
}
644+
return Just(true);
645+
}
646+
647+
Maybe<bool> InitializeMainContextForSnapshot(Local<Context> context) {
665648
Isolate* isolate = context->GetIsolate();
666649
HandleScope handle_scope(isolate);
667650

@@ -671,6 +654,9 @@ Maybe<bool> InitializeContextForSnapshot(Local<Context> context) {
671654
context->SetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration,
672655
True(isolate));
673656

657+
if (InitializeBaseContextForSnapshot(context).IsNothing()) {
658+
return Nothing<bool>();
659+
}
674660
return InitializePrimordials(context);
675661
}
676662

@@ -717,8 +703,9 @@ Maybe<bool> InitializePrimordials(Local<Context> context) {
717703
return Just(true);
718704
}
719705

706+
// This initializes the main context (i.e. vm contexts are not included).
720707
Maybe<bool> InitializeContext(Local<Context> context) {
721-
if (InitializeContextForSnapshot(context).IsNothing()) {
708+
if (InitializeMainContextForSnapshot(context).IsNothing()) {
722709
return Nothing<bool>();
723710
}
724711

src/node_contextify.cc

+9-7
Original file line numberDiff line numberDiff line change
@@ -206,14 +206,16 @@ MaybeLocal<Context> ContextifyContext::CreateV8Context(
206206
{}, // global object
207207
{}, // deserialization callback
208208
queue);
209-
if (ctx.IsEmpty()) return MaybeLocal<Context>();
209+
if (ctx.IsEmpty() || InitializeBaseContextForSnapshot(ctx).IsNothing()) {
210+
return MaybeLocal<Context>();
211+
}
210212
} else if (!Context::FromSnapshot(isolate,
211-
SnapshotData::kNodeVMContextIndex,
212-
{}, // deserialization callback
213-
nullptr, // extensions
214-
{}, // global object
215-
queue)
216-
.ToLocal(&ctx)) {
213+
SnapshotData::kNodeVMContextIndex,
214+
{}, // deserialization callback
215+
nullptr, // extensions
216+
{}, // global object
217+
queue)
218+
.ToLocal(&ctx)) {
217219
return MaybeLocal<Context>();
218220
}
219221
return scope.Escape(ctx);

src/node_internals.h

+2
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ void SignalExit(int signal, siginfo_t* info, void* ucontext);
9292
std::string GetProcessTitle(const char* default_title);
9393
std::string GetHumanReadableProcessName();
9494

95+
v8::Maybe<bool> InitializeBaseContextForSnapshot(
96+
v8::Local<v8::Context> context);
9597
v8::Maybe<bool> InitializeContextRuntime(v8::Local<v8::Context> context);
9698
v8::Maybe<bool> InitializePrimordials(v8::Local<v8::Context> context);
9799

0 commit comments

Comments
 (0)