Browse Source

lib: copy arguments object instead of leaking it

Instead of leaking the arguments object by passing it as an
argument to a function, copy it's contents to a new array,
then pass the array. This allows V8 to optimize the function
that contains this code, improving performance.

PR-URL: https://github.com/nodejs/node/pull/4361
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Brian White <mscdex@mscdex.net>
process-exit-stdio-flushing
Nathan Woltman 9 years ago
committed by James M Snell
parent
commit
d0582ef9e1
  1. 12
      lib/_http_client.js
  2. 6
      lib/_tls_wrap.js
  3. 22
      lib/assert.js
  4. 5
      lib/console.js
  5. 12
      lib/net.js

12
lib/_http_client.js

@ -608,10 +608,18 @@ ClientRequest.prototype.setTimeout = function(msecs, callback) {
}; };
ClientRequest.prototype.setNoDelay = function() { ClientRequest.prototype.setNoDelay = function() {
this._deferToConnect('setNoDelay', arguments); const argsLen = arguments.length;
const args = new Array(argsLen);
for (var i = 0; i < argsLen; i++)
args[i] = arguments[i];
this._deferToConnect('setNoDelay', args);
}; };
ClientRequest.prototype.setSocketKeepAlive = function() { ClientRequest.prototype.setSocketKeepAlive = function() {
this._deferToConnect('setKeepAlive', arguments); const argsLen = arguments.length;
const args = new Array(argsLen);
for (var i = 0; i < argsLen; i++)
args[i] = arguments[i];
this._deferToConnect('setKeepAlive', args);
}; };
ClientRequest.prototype.clearTimeout = function(cb) { ClientRequest.prototype.clearTimeout = function(cb) {

6
lib/_tls_wrap.js

@ -960,7 +960,11 @@ function normalizeConnectArgs(listArgs) {
} }
exports.connect = function(/* [port, host], options, cb */) { exports.connect = function(/* [port, host], options, cb */) {
var args = normalizeConnectArgs(arguments); const argsLen = arguments.length;
var args = new Array(argsLen);
for (var i = 0; i < argsLen; i++)
args[i] = arguments[i];
args = normalizeConnectArgs(args);
var options = args[0]; var options = args[0];
var cb = args[1]; var cb = args[1];

22
lib/assert.js

@ -290,6 +290,16 @@ function expectedException(actual, expected) {
return expected.call({}, actual) === true; return expected.call({}, actual) === true;
} }
function _tryBlock(block) {
var error;
try {
block();
} catch (e) {
error = e;
}
return error;
}
function _throws(shouldThrow, block, expected, message) { function _throws(shouldThrow, block, expected, message) {
var actual; var actual;
@ -302,11 +312,7 @@ function _throws(shouldThrow, block, expected, message) {
expected = null; expected = null;
} }
try { actual = _tryBlock(block);
block();
} catch (e) {
actual = e;
}
message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
(message ? ' ' + message : '.'); (message ? ' ' + message : '.');
@ -329,12 +335,12 @@ function _throws(shouldThrow, block, expected, message) {
// assert.throws(block, Error_opt, message_opt); // assert.throws(block, Error_opt, message_opt);
assert.throws = function(block, /*optional*/error, /*optional*/message) { assert.throws = function(block, /*optional*/error, /*optional*/message) {
_throws.apply(this, [true].concat(pSlice.call(arguments))); _throws(true, block, error, message);
}; };
// EXTENSION! This is annoying to write outside this module. // EXTENSION! This is annoying to write outside this module.
assert.doesNotThrow = function(block, /*optional*/message) { assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
_throws.apply(this, [false].concat(pSlice.call(arguments))); _throws(false, block, error, message);
}; };
assert.ifError = function(err) { if (err) throw err; }; assert.ifError = function(err) { if (err) throw err; };

5
lib/console.js

@ -85,7 +85,10 @@ Console.prototype.trace = function trace() {
Console.prototype.assert = function(expression) { Console.prototype.assert = function(expression) {
if (!expression) { if (!expression) {
var arr = Array.prototype.slice.call(arguments, 1); const argsLen = arguments.length || 1;
const arr = new Array(argsLen - 1);
for (var i = 1; i < argsLen; i++)
arr[i - 1] = arguments[i];
require('assert').ok(false, util.format.apply(null, arr)); require('assert').ok(false, util.format.apply(null, arr));
} }
}; };

12
lib/net.js

@ -59,7 +59,11 @@ exports.createServer = function(options, connectionListener) {
// connect(path, [cb]); // connect(path, [cb]);
// //
exports.connect = exports.createConnection = function() { exports.connect = exports.createConnection = function() {
var args = normalizeConnectArgs(arguments); const argsLen = arguments.length;
var args = new Array(argsLen);
for (var i = 0; i < argsLen; i++)
args[i] = arguments[i];
args = normalizeConnectArgs(args);
debug('createConnection', args); debug('createConnection', args);
var s = new Socket(args[0]); var s = new Socket(args[0]);
return Socket.prototype.connect.apply(s, args); return Socket.prototype.connect.apply(s, args);
@ -858,7 +862,11 @@ Socket.prototype.connect = function(options, cb) {
// Old API: // Old API:
// connect(port, [host], [cb]) // connect(port, [host], [cb])
// connect(path, [cb]); // connect(path, [cb]);
var args = normalizeConnectArgs(arguments); const argsLen = arguments.length;
var args = new Array(argsLen);
for (var i = 0; i < argsLen; i++)
args[i] = arguments[i];
args = normalizeConnectArgs(args);
return Socket.prototype.connect.apply(this, args); return Socket.prototype.connect.apply(this, args);
} }

Loading…
Cancel
Save