Skip to content

Commit 78c5217

Browse files
committed
vm: don't set host-defined options when it's not necessary
This makes it possile to hit the in-isolate compilation cache when host-defined options are not necessary.
1 parent 1dc0667 commit 78c5217

File tree

3 files changed

+60
-13
lines changed

3 files changed

+60
-13
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict';
2+
3+
// This benchmarks compiling scripts that hit the in-isolate compilation
4+
// cache (by having the same source).
5+
const common = require('../common.js');
6+
const fs = require('fs');
7+
const vm = require('vm');
8+
const fixtures = require('../../test/common/fixtures.js');
9+
const scriptPath = fixtures.path('snapshot', 'typescript.js');
10+
11+
const bench = common.createBenchmark(main, {
12+
type: ['with-dynamic-import-callback', 'without-dynamic-import-callback'],
13+
n: [100],
14+
});
15+
16+
const scriptSource = fs.readFileSync(scriptPath, 'utf8');
17+
18+
function main({ n, type }) {
19+
let script;
20+
bench.start();
21+
let options = {};
22+
switch (type) {
23+
case 'with-dynamic-import-callback':
24+
// Use a dummy callback for now until we really need to benchmark it.
25+
options.importModuleDynamically = async() => {};
26+
break;
27+
case 'without-dynamic-import-callback':
28+
break;
29+
}
30+
for (let i = 0; i < n; i++) {
31+
script = new vm.Script(scriptSource, options);
32+
}
33+
bench.end(n);
34+
script.runInThisContext();
35+
}

lib/vm.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ class Script extends ContextifyScript {
8686
}
8787
validateBoolean(produceCachedData, 'options.produceCachedData');
8888

89+
if (importModuleDynamically !== undefined) {
90+
// Check that it's either undefined or a function before we pass
91+
// it into the native constructor.
92+
validateFunction(importModuleDynamically,
93+
'options.importModuleDynamically');
94+
}
8995
// Calling `ReThrow()` on a native TryCatch does not generate a new
9096
// abort-on-uncaught-exception check. A dummy try/catch in JS land
9197
// protects against that.
@@ -96,14 +102,13 @@ class Script extends ContextifyScript {
96102
columnOffset,
97103
cachedData,
98104
produceCachedData,
99-
parsingContext);
105+
parsingContext,
106+
importModuleDynamically);
100107
} catch (e) {
101108
throw e; /* node-do-not-add-exception-line */
102109
}
103110

104111
if (importModuleDynamically !== undefined) {
105-
validateFunction(importModuleDynamically,
106-
'options.importModuleDynamically');
107112
const { importModuleDynamicallyWrap } = require('internal/vm/module');
108113
const { registerModule } = require('internal/modules/esm/utils');
109114
registerModule(this, {

src/node_contextify.cc

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -771,10 +771,13 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
771771
bool produce_cached_data = false;
772772
Local<Context> parsing_context = context;
773773

774+
Local<Symbol> host_defined_options_id;
775+
Local<PrimitiveArray> host_defined_options;
774776
if (argc > 2) {
775777
// new ContextifyScript(code, filename, lineOffset, columnOffset,
776-
// cachedData, produceCachedData, parsingContext)
777-
CHECK_EQ(argc, 7);
778+
// cachedData, produceCachedData, parsingContext,
779+
// needsHostDefinedOptions)
780+
CHECK_EQ(argc, 8);
778781
CHECK(args[2]->IsNumber());
779782
line_offset = args[2].As<Int32>()->Value();
780783
CHECK(args[3]->IsNumber());
@@ -793,6 +796,13 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
793796
CHECK_NOT_NULL(sandbox);
794797
parsing_context = sandbox->context();
795798
}
799+
if (!args[7]->IsUndefined()) {
800+
host_defined_options_id = Symbol::New(isolate, filename);
801+
host_defined_options =
802+
PrimitiveArray::New(isolate, loader::HostDefinedOptions::kLength);
803+
host_defined_options->Set(
804+
isolate, loader::HostDefinedOptions::kID, host_defined_options_id);
805+
}
796806
}
797807

798808
ContextifyScript* contextify_script =
@@ -814,12 +824,6 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
814824
data + cached_data_buf->ByteOffset(), cached_data_buf->ByteLength());
815825
}
816826

817-
Local<PrimitiveArray> host_defined_options =
818-
PrimitiveArray::New(isolate, loader::HostDefinedOptions::kLength);
819-
Local<Symbol> id_symbol = Symbol::New(isolate, filename);
820-
host_defined_options->Set(
821-
isolate, loader::HostDefinedOptions::kID, id_symbol);
822-
823827
ScriptOrigin origin(isolate,
824828
filename,
825829
line_offset, // line offset
@@ -865,8 +869,11 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
865869
new_cached_data.reset(ScriptCompiler::CreateCodeCache(v8_script));
866870
}
867871

868-
if (contextify_script->object()
869-
->SetPrivate(context, env->host_defined_option_symbol(), id_symbol)
872+
if (!host_defined_options_id.IsEmpty() &&
873+
contextify_script->object()
874+
->SetPrivate(context,
875+
env->host_defined_option_symbol(),
876+
host_defined_options_id)
870877
.IsNothing()) {
871878
return;
872879
}

0 commit comments

Comments
 (0)