Browse Source

lib: don't penalize setInterval() common case

The common case is where setInterval() is called with two arguments,
the callback and the timeout.  Specifying optional arguments in
the parameter list forces common case calls to go through an arguments
adaptor stack frame.

PR-URL: https://github.com/iojs/io.js/pull/1221
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
v1.8.0-commit
Ben Noordhuis 10 years ago
parent
commit
33fea6ed5f
  1. 56
      lib/timers.js

56
lib/timers.js

@ -229,52 +229,50 @@ exports.clearTimeout = function(timer) {
};
exports.setInterval = function(callback, repeat, arg1, arg2, arg3) {
exports.setInterval = function(callback, repeat) {
repeat *= 1; // coalesce to number or NaN
if (!(repeat >= 1 && repeat <= TIMEOUT_MAX)) {
repeat = 1; // schedule on next tick, follows browser behaviour
}
var args, i;
var timer = new Timeout(repeat);
var len = arguments.length - 2;
timer._onTimeout = wrapper;
timer._repeat = true;
// Initialize args once for repeated invocation of slow case below
if (len > 3) {
args = new Array(len);
for (i = 0; i < len; i++)
args[i] = arguments[i + 2];
}
if (process.domain) timer.domain = process.domain;
exports.active(timer);
return timer;
function wrapper() {
switch (len) {
// fast cases
var length = arguments.length;
var ontimeout = callback;
switch (length) {
case 0:
callback.call(this);
break;
case 1:
callback.call(this, arg1);
break;
case 2:
callback.call(this, arg1, arg2);
break;
case 3:
callback.call(this, arg1, arg2, arg3);
ontimeout = callback.bind(timer, arguments[2]);
break;
case 4:
ontimeout = callback.bind(timer, arguments[2], arguments[3]);
break;
case 5:
ontimeout =
callback.bind(timer, arguments[2], arguments[3], arguments[4]);
break;
// slow case
default:
callback.apply(this, args);
var args = new Array(length - 2);
for (var i = 2; i < length; i += 1)
args[i - 2] = arguments[i];
ontimeout = callback.apply.bind(callback, timer, args);
break;
}
timer._onTimeout = wrapper;
timer._repeat = ontimeout;
if (process.domain) timer.domain = process.domain;
exports.active(timer);
return timer;
function wrapper() {
timer._repeat.call(this);
// If callback called clearInterval().
if (timer._repeat === false) return;
if (timer._repeat === null) return;
// If timer is unref'd (or was - it's permanently removed from the list.)
if (this._handle) {
this._handle.start(repeat, 0);

Loading…
Cancel
Save