diff options
author | Joyee Cheung <joyeec9h3@gmail.com> | 2020-02-11 17:49:24 +0300 |
---|---|---|
committer | Shelley Vohr <shelley.vohr@gmail.com> | 2020-02-27 20:44:36 +0300 |
commit | a86cb0e480b0a47eed5cc36366d7b90737d587f4 (patch) | |
tree | 27eb16459e24b83d85ffd6b918958888ed114dda /src/api | |
parent | 94a471a42241e6c61619c3523fd8d5743223314c (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.cc | 84 |
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, ¶meters, 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, ¶meters, 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; } } |