@ -506,7 +506,7 @@ var immediateQueue = L.create();
function processImmediate ( ) {
function processImmediate ( ) {
var queue = immediateQueue ;
const queue = immediateQueue ;
var domain , immediate ;
var domain , immediate ;
immediateQueue = L . create ( ) ;
immediateQueue = L . create ( ) ;
@ -515,9 +515,13 @@ function processImmediate() {
immediate = L . shift ( queue ) ;
immediate = L . shift ( queue ) ;
domain = immediate . domain ;
domain = immediate . domain ;
if ( ! immediate . _ onImmediate )
continue ;
if ( domain )
if ( domain )
domain . enter ( ) ;
domain . enter ( ) ;
immediate . _ callback = immediate . _ onImmediate ;
tryOnImmediate ( immediate , queue ) ;
tryOnImmediate ( immediate , queue ) ;
if ( domain )
if ( domain )
@ -538,7 +542,8 @@ function processImmediate() {
function tryOnImmediate ( immediate , queue ) {
function tryOnImmediate ( immediate , queue ) {
var threw = true ;
var threw = true ;
try {
try {
immediate . _ onImmediate ( ) ;
// make the actual call outside the try/catch to allow it to be optimized
runCallback ( immediate ) ;
threw = false ;
threw = false ;
} finally {
} finally {
if ( threw && ! L . isEmpty ( queue ) ) {
if ( threw && ! L . isEmpty ( queue ) ) {
@ -552,14 +557,36 @@ function tryOnImmediate(immediate, queue) {
}
}
}
}
function runCallback ( timer ) {
const argv = timer . _ argv ;
const argc = argv ? argv . length : 0 ;
switch ( argc ) {
// fast-path callbacks with 0-3 arguments
case 0 :
return timer . _ callback ( ) ;
case 1 :
return timer . _ callback ( argv [ 0 ] ) ;
case 2 :
return timer . _ callback ( argv [ 0 ] , argv [ 1 ] ) ;
case 3 :
return timer . _ callback ( argv [ 0 ] , argv [ 1 ] , argv [ 2 ] ) ;
// more than 3 arguments run slower with .apply
default :
return timer . _ callback . apply ( timer , argv ) ;
}
}
function Immediate ( ) { }
Immediate . prototype . domain = undefined ;
Immediate . prototype . _ onImmediate = undefined ;
Immediate . prototype . _ idleNext = undefined ;
Immediate . prototype . _ idlePrev = undefined ;
function Immediate ( ) {
// assigning the callback here can cause optimize/deoptimize thrashing
// so have caller annotate the object (node v6.0.0, v8 5.0.71.35)
this . _ idleNext = null ;
this . _ idlePrev = null ;
this . _ callback = null ;
this . _ argv = null ;
this . _ onImmediate = null ;
this . domain = process . domain ;
}
exports . setImmediate = function ( callback , arg1 , arg2 , arg3 ) {
exports . setImmediate = function ( callback , arg1 , arg2 , arg3 ) {
if ( typeof callback !== 'function' ) {
if ( typeof callback !== 'function' ) {
@ -567,52 +594,40 @@ exports.setImmediate = function(callback, arg1, arg2, arg3) {
}
}
var i , args ;
var i , args ;
var len = arguments . length ;
var immediate = new Immediate ( ) ;
L . init ( immediate ) ;
switch ( arguments . length ) {
switch ( len ) {
// fast cases
// fast cases
case 0 :
case 0 :
case 1 :
case 1 :
immediate . _ onImmediate = callback ;
break ;
break ;
case 2 :
case 2 :
immediate . _ onImmediate = function ( ) {
args = [ arg1 ] ;
callback . call ( immediate , arg1 ) ;
} ;
break ;
break ;
case 3 :
case 3 :
immediate . _ onImmediate = function ( ) {
args = [ arg1 , arg2 ] ;
callback . call ( immediate , arg1 , arg2 ) ;
} ;
break ;
break ;
case 4 :
case 4 :
immediate . _ onImmediate = function ( ) {
args = [ arg1 , arg2 , arg3 ] ;
callback . call ( immediate , arg1 , arg2 , arg3 ) ;
} ;
break ;
break ;
// slow case
// slow case
default :
default :
args = new Array ( len - 1 ) ;
args = [ arg1 , arg2 , arg3 ] ;
for ( i = 1 ; i < len ; i ++ )
for ( i = 4 ; i < arguments . length ; i ++ )
// extend array dynamically, makes .apply run much faster in v6.0.0
args [ i - 1 ] = arguments [ i ] ;
args [ i - 1 ] = arguments [ i ] ;
immediate . _ onImmediate = function ( ) {
callback . apply ( immediate , args ) ;
} ;
break ;
break ;
}
}
// declaring it `const immediate` causes v6.0.0 to deoptimize this function
var immediate = new Immediate ( ) ;
immediate . _ callback = callback ;
immediate . _ argv = args ;
immediate . _ onImmediate = callback ;
if ( ! process . _ needImmediateCallback ) {
if ( ! process . _ needImmediateCallback ) {
process . _ needImmediateCallback = true ;
process . _ needImmediateCallback = true ;
process . _ immediateCallback = processImmediate ;
process . _ immediateCallback = processImmediate ;
}
}
if ( process . domain )
immediate . domain = process . domain ;
L . append ( immediateQueue , immediate ) ;
L . append ( immediateQueue , immediate ) ;
return immediate ;
return immediate ;