From 95e90a049225b2b582b004b8511634bdd8b999b0 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sat, 14 Jan 2017 19:43:08 -0800 Subject: [PATCH 1/3] benchmark: add benchmark for vm.runIn*() Introduce benchmarks for vm.runInContext() and vm.runInThisContext(). --- benchmark/vm/run-in-context.js | 32 +++++++++++++++++++++++++++++ benchmark/vm/run-in-this-context.js | 29 ++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 benchmark/vm/run-in-context.js create mode 100644 benchmark/vm/run-in-this-context.js diff --git a/benchmark/vm/run-in-context.js b/benchmark/vm/run-in-context.js new file mode 100644 index 00000000000000..62ebe29146e705 --- /dev/null +++ b/benchmark/vm/run-in-context.js @@ -0,0 +1,32 @@ +'use strict'; + +const common = require('../common.js'); + +const bench = common.createBenchmark(main, { + n: [1], + breakOnSigint: [0, 1], + withSigintListener: [0, 1] +}); + +const vm = require('vm'); + +function main(conf) { + const n = +conf.n; + const options = conf.breakOnSigint ? {breakOnSigint: true} : {}; + const withSigintListener = !!conf.withSigintListener; + + process.removeAllListeners('SIGINT'); + if (withSigintListener) + process.on('SIGINT', () => {}); + + var i = 0; + + const contextifiedSandbox = vm.createContext(); + + common.v8ForceOptimization(vm.runInContext, + '0', contextifiedSandbox, options); + bench.start(); + for (; i < n; i++) + vm.runInContext('0', contextifiedSandbox, options); + bench.end(n); +} diff --git a/benchmark/vm/run-in-this-context.js b/benchmark/vm/run-in-this-context.js new file mode 100644 index 00000000000000..f66fd31a1a949e --- /dev/null +++ b/benchmark/vm/run-in-this-context.js @@ -0,0 +1,29 @@ +'use strict'; + +const common = require('../common.js'); + +const bench = common.createBenchmark(main, { + n: [1], + breakOnSigint: [0, 1], + withSigintListener: [0, 1] +}); + +const vm = require('vm'); + +function main(conf) { + const n = +conf.n; + const options = conf.breakOnSigint ? {breakOnSigint: true} : {}; + const withSigintListener = !!conf.withSigintListener; + + process.removeAllListeners('SIGINT'); + if (withSigintListener) + process.on('SIGINT', () => {}); + + var i = 0; + + common.v8ForceOptimization(vm.runInThisContext, '0', options); + bench.start(); + for (; i < n; i++) + vm.runInThisContext('0', options); + bench.end(n); +} From ffdc0821c8443b9f71129420f58099363b9a8eab Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sat, 14 Jan 2017 19:43:33 -0800 Subject: [PATCH 2/3] vm: improve performance of vm.runIn*() Optimize for common cases in vm.runInContext() and vm.runInThisContext(). --- lib/vm.js | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/lib/vm.js b/lib/vm.js index 4869d368807665..295e874c6ab530 100644 --- a/lib/vm.js +++ b/lib/vm.js @@ -18,10 +18,7 @@ const realRunInContext = Script.prototype.runInContext; Script.prototype.runInThisContext = function(options) { if (options && options.breakOnSigint) { - const realRunInThisContextScript = () => { - return realRunInThisContext.call(this, options); - }; - return sigintHandlersWrap(realRunInThisContextScript); + return sigintHandlersWrap(realRunInThisContext, this, [options]); } else { return realRunInThisContext.call(this, options); } @@ -29,10 +26,8 @@ Script.prototype.runInThisContext = function(options) { Script.prototype.runInContext = function(contextifiedSandbox, options) { if (options && options.breakOnSigint) { - const realRunInContextScript = () => { - return realRunInContext.call(this, contextifiedSandbox, options); - }; - return sigintHandlersWrap(realRunInContextScript); + return sigintHandlersWrap(realRunInContext, this, + [contextifiedSandbox, options]); } else { return realRunInContext.call(this, contextifiedSandbox, options); } @@ -83,19 +78,22 @@ exports.isContext = binding.isContext; // Remove all SIGINT listeners and re-attach them after the wrapped function // has executed, so that caught SIGINT are handled by the listeners again. -function sigintHandlersWrap(fn) { +function sigintHandlersWrap(fn, thisArg, argsArray) { // Using the internal list here to make sure `.once()` wrappers are used, // not the original ones. let sigintListeners = process._events.SIGINT; - if (!Array.isArray(sigintListeners)) - sigintListeners = sigintListeners ? [sigintListeners] : []; - else + if (!sigintListeners) + return fn.apply(thisArg, argsArray); + + if (Array.isArray(sigintListeners)) sigintListeners = sigintListeners.slice(); + else + sigintListeners = [sigintListeners]; process.removeAllListeners('SIGINT'); try { - return fn(); + return fn.apply(thisArg, argsArray); } finally { // Add using the public methods so that the `newListener` handler of // process can re-attach the listeners. From 3967c08570d56dc47bb543a616bcc5425d79d1be Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sun, 15 Jan 2017 08:57:30 -0800 Subject: [PATCH 3/3] squash --- lib/vm.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/vm.js b/lib/vm.js index 295e874c6ab530..cf672fbbc14871 100644 --- a/lib/vm.js +++ b/lib/vm.js @@ -17,7 +17,7 @@ const realRunInThisContext = Script.prototype.runInThisContext; const realRunInContext = Script.prototype.runInContext; Script.prototype.runInThisContext = function(options) { - if (options && options.breakOnSigint) { + if (options && options.breakOnSigint && process._events.SIGINT) { return sigintHandlersWrap(realRunInThisContext, this, [options]); } else { return realRunInThisContext.call(this, options); @@ -25,7 +25,7 @@ Script.prototype.runInThisContext = function(options) { }; Script.prototype.runInContext = function(contextifiedSandbox, options) { - if (options && options.breakOnSigint) { + if (options && options.breakOnSigint && process._events.SIGINT) { return sigintHandlersWrap(realRunInContext, this, [contextifiedSandbox, options]); } else { @@ -82,8 +82,6 @@ function sigintHandlersWrap(fn, thisArg, argsArray) { // Using the internal list here to make sure `.once()` wrappers are used, // not the original ones. let sigintListeners = process._events.SIGINT; - if (!sigintListeners) - return fn.apply(thisArg, argsArray); if (Array.isArray(sigintListeners)) sigintListeners = sigintListeners.slice();