Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src/api
diff options
context:
space:
mode:
authorJoyee Cheung <joyeec9h3@gmail.com>2020-02-11 17:49:24 +0300
committerShelley Vohr <shelley.vohr@gmail.com>2020-02-27 20:44:36 +0300
commita86cb0e480b0a47eed5cc36366d7b90737d587f4 (patch)
tree27eb16459e24b83d85ffd6b918958888ed114dda /src/api
parent94a471a42241e6c61619c3523fd8d5743223314c (diff)
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: https://github.com/nodejs/node/pull/31738 Fixes: https://github.com/nodejs/node/issues/29842 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: David Carlier <devnexen@gmail.com>
Diffstat (limited to 'src/api')
-rw-r--r--src/api/environment.cc84
1 files changed, 43 insertions, 41 deletions
diff --git a/src/api/environment.cc b/src/api/environment.cc
index f25a4cf1832..0096b498e1c 100644
--- a/src/api/environment.cc
+++ b/src/api/environment.cc
@@ -411,7 +411,8 @@ MaybeLocal<Object> GetPerContextExports(Local<Context> context) {
return handle_scope.Escape(existing_value.As<Object>());
Local<Object> exports = Object::New(isolate);
- if (context->Global()->SetPrivate(context, key, exports).IsNothing())
+ if (context->Global()->SetPrivate(context, key, exports).IsNothing() ||
+ !InitializePrimordials(context))
return MaybeLocal<Object>();
return handle_scope.Escape(exports);
}
@@ -467,49 +468,50 @@ bool InitializeContextForSnapshot(Local<Context> context) {
context->SetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration,
True(isolate));
+ return InitializePrimordials(context);
+}
+
+bool InitializePrimordials(Local<Context> context) {
+ // Run per-context JS files.
+ Isolate* isolate = context->GetIsolate();
+ Context::Scope context_scope(context);
+ Local<Object> exports;
+
+ Local<String> primordials_string =
+ FIXED_ONE_BYTE_STRING(isolate, "primordials");
+ Local<String> global_string = FIXED_ONE_BYTE_STRING(isolate, "global");
+ Local<String> exports_string = FIXED_ONE_BYTE_STRING(isolate, "exports");
+
+ // Create primordials first and make it available to per-context scripts.
+ Local<Object> primordials = Object::New(isolate);
+ if (!primordials->SetPrototype(context, Null(isolate)).FromJust() ||
+ !GetPerContextExports(context).ToLocal(&exports) ||
+ !exports->Set(context, primordials_string, primordials).FromJust()) {
+ return false;
+ }
- {
- // Run per-context JS files.
- Context::Scope context_scope(context);
- Local<Object> exports;
-
- Local<String> primordials_string =
- FIXED_ONE_BYTE_STRING(isolate, "primordials");
- Local<String> global_string = FIXED_ONE_BYTE_STRING(isolate, "global");
- Local<String> exports_string = FIXED_ONE_BYTE_STRING(isolate, "exports");
-
- // Create primordials first and make it available to per-context scripts.
- Local<Object> primordials = Object::New(isolate);
- if (!primordials->SetPrototype(context, Null(isolate)).FromJust() ||
- !GetPerContextExports(context).ToLocal(&exports) ||
- !exports->Set(context, primordials_string, primordials).FromJust()) {
+ static const char* context_files[] = {"internal/per_context/primordials",
+ "internal/per_context/domexception",
+ "internal/per_context/messageport",
+ nullptr};
+
+ for (const char** module = context_files; *module != nullptr; module++) {
+ std::vector<Local<String>> parameters = {
+ global_string, exports_string, primordials_string};
+ Local<Value> arguments[] = {context->Global(), exports, primordials};
+ MaybeLocal<Function> maybe_fn =
+ native_module::NativeModuleEnv::LookupAndCompile(
+ context, *module, &parameters, nullptr);
+ if (maybe_fn.IsEmpty()) {
return false;
}
-
- static const char* context_files[] = {"internal/per_context/primordials",
- "internal/per_context/domexception",
- "internal/per_context/messageport",
- nullptr};
-
- for (const char** module = context_files; *module != nullptr; module++) {
- std::vector<Local<String>> parameters = {
- global_string, exports_string, primordials_string};
- Local<Value> arguments[] = {context->Global(), exports, primordials};
- MaybeLocal<Function> maybe_fn =
- native_module::NativeModuleEnv::LookupAndCompile(
- context, *module, &parameters, nullptr);
- if (maybe_fn.IsEmpty()) {
- return false;
- }
- Local<Function> fn = maybe_fn.ToLocalChecked();
- MaybeLocal<Value> result =
- fn->Call(context, Undefined(isolate),
- arraysize(arguments), arguments);
- // Execution failed during context creation.
- // TODO(joyeecheung): deprecate this signature and return a MaybeLocal.
- if (result.IsEmpty()) {
- return false;
- }
+ Local<Function> fn = maybe_fn.ToLocalChecked();
+ MaybeLocal<Value> result =
+ fn->Call(context, Undefined(isolate), arraysize(arguments), arguments);
+ // Execution failed during context creation.
+ // TODO(joyeecheung): deprecate this signature and return a MaybeLocal.
+ if (result.IsEmpty()) {
+ return false;
}
}