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 a86cb0e

Browse filesBrowse files
joyeecheungcodebytere
authored andcommitted
vm: lazily initialize primordials for vm contexts
Lazily initialize primordials when cross-context support for builtins is needed to fix the performance regression in context creation. PR-URL: #31738 Fixes: #29842 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: David Carlier <devnexen@gmail.com>
1 parent 94a471a commit a86cb0e
Copy full SHA for a86cb0e

File tree

Expand file treeCollapse file tree

3 files changed

+49
-43
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

3 files changed

+49
-43
lines changed
Open diff view settings
Collapse file

‎src/api/environment.cc‎

Copy file name to clipboardExpand all lines: src/api/environment.cc
+43-41Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,8 @@ MaybeLocal<Object> GetPerContextExports(Local<Context> context) {
411411
return handle_scope.Escape(existing_value.As<Object>());
412412

413413
Local<Object> exports = Object::New(isolate);
414-
if (context->Global()->SetPrivate(context, key, exports).IsNothing())
414+
if (context->Global()->SetPrivate(context, key, exports).IsNothing() ||
415+
!InitializePrimordials(context))
415416
return MaybeLocal<Object>();
416417
return handle_scope.Escape(exports);
417418
}
@@ -467,49 +468,50 @@ bool InitializeContextForSnapshot(Local<Context> context) {
467468

468469
context->SetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration,
469470
True(isolate));
471+
return InitializePrimordials(context);
472+
}
473+
474+
bool InitializePrimordials(Local<Context> context) {
475+
// Run per-context JS files.
476+
Isolate* isolate = context->GetIsolate();
477+
Context::Scope context_scope(context);
478+
Local<Object> exports;
479+
480+
Local<String> primordials_string =
481+
FIXED_ONE_BYTE_STRING(isolate, "primordials");
482+
Local<String> global_string = FIXED_ONE_BYTE_STRING(isolate, "global");
483+
Local<String> exports_string = FIXED_ONE_BYTE_STRING(isolate, "exports");
484+
485+
// Create primordials first and make it available to per-context scripts.
486+
Local<Object> primordials = Object::New(isolate);
487+
if (!primordials->SetPrototype(context, Null(isolate)).FromJust() ||
488+
!GetPerContextExports(context).ToLocal(&exports) ||
489+
!exports->Set(context, primordials_string, primordials).FromJust()) {
490+
return false;
491+
}
470492

471-
{
472-
// Run per-context JS files.
473-
Context::Scope context_scope(context);
474-
Local<Object> exports;
475-
476-
Local<String> primordials_string =
477-
FIXED_ONE_BYTE_STRING(isolate, "primordials");
478-
Local<String> global_string = FIXED_ONE_BYTE_STRING(isolate, "global");
479-
Local<String> exports_string = FIXED_ONE_BYTE_STRING(isolate, "exports");
480-
481-
// Create primordials first and make it available to per-context scripts.
482-
Local<Object> primordials = Object::New(isolate);
483-
if (!primordials->SetPrototype(context, Null(isolate)).FromJust() ||
484-
!GetPerContextExports(context).ToLocal(&exports) ||
485-
!exports->Set(context, primordials_string, primordials).FromJust()) {
493+
static const char* context_files[] = {"internal/per_context/primordials",
494+
"internal/per_context/domexception",
495+
"internal/per_context/messageport",
496+
nullptr};
497+
498+
for (const char** module = context_files; *module != nullptr; module++) {
499+
std::vector<Local<String>> parameters = {
500+
global_string, exports_string, primordials_string};
501+
Local<Value> arguments[] = {context->Global(), exports, primordials};
502+
MaybeLocal<Function> maybe_fn =
503+
native_module::NativeModuleEnv::LookupAndCompile(
504+
context, *module, &parameters, nullptr);
505+
if (maybe_fn.IsEmpty()) {
486506
return false;
487507
}
488-
489-
static const char* context_files[] = {"internal/per_context/primordials",
490-
"internal/per_context/domexception",
491-
"internal/per_context/messageport",
492-
nullptr};
493-
494-
for (const char** module = context_files; *module != nullptr; module++) {
495-
std::vector<Local<String>> parameters = {
496-
global_string, exports_string, primordials_string};
497-
Local<Value> arguments[] = {context->Global(), exports, primordials};
498-
MaybeLocal<Function> maybe_fn =
499-
native_module::NativeModuleEnv::LookupAndCompile(
500-
context, *module, &parameters, nullptr);
501-
if (maybe_fn.IsEmpty()) {
502-
return false;
503-
}
504-
Local<Function> fn = maybe_fn.ToLocalChecked();
505-
MaybeLocal<Value> result =
506-
fn->Call(context, Undefined(isolate),
507-
arraysize(arguments), arguments);
508-
// Execution failed during context creation.
509-
// TODO(joyeecheung): deprecate this signature and return a MaybeLocal.
510-
if (result.IsEmpty()) {
511-
return false;
512-
}
508+
Local<Function> fn = maybe_fn.ToLocalChecked();
509+
MaybeLocal<Value> result =
510+
fn->Call(context, Undefined(isolate), arraysize(arguments), arguments);
511+
// Execution failed during context creation.
512+
// TODO(joyeecheung): deprecate this signature and return a MaybeLocal.
513+
if (result.IsEmpty()) {
514+
return false;
513515
}
514516
}
515517

Collapse file

‎src/node_contextify.cc‎

Copy file name to clipboardExpand all lines: src/node_contextify.cc
+5-2Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,11 @@ MaybeLocal<Context> ContextifyContext::CreateV8Context(
185185

186186
object_template->SetHandler(config);
187187
object_template->SetHandler(indexed_config);
188-
189-
Local<Context> ctx = NewContext(env->isolate(), object_template);
188+
Local<Context> ctx = Context::New(env->isolate(), nullptr, object_template);
189+
if (ctx.IsEmpty()) return MaybeLocal<Context>();
190+
// Only partially initialize the context - the primordials are left out
191+
// and only initialized when necessary.
192+
InitializeContextRuntime(ctx);
190193

191194
if (ctx.IsEmpty()) {
192195
return MaybeLocal<Context>();
Collapse file

‎src/node_internals.h‎

Copy file name to clipboardExpand all lines: src/node_internals.h
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ std::string GetProcessTitle(const char* default_title);
9999
std::string GetHumanReadableProcessName();
100100

101101
void InitializeContextRuntime(v8::Local<v8::Context>);
102+
bool InitializePrimordials(v8::Local<v8::Context> context);
102103

103104
namespace task_queue {
104105
void PromiseRejectCallback(v8::PromiseRejectMessage message);

0 commit comments

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