|
328 | 328 | // Run callbacks that have no domain. |
329 | 329 | // Using domains will cause this to be overridden. |
330 | 330 | function _tickCallback() { |
331 | | - var callback, threw, tock; |
| 331 | + var callback, args, tock; |
332 | 332 |
|
333 | 333 | do { |
334 | 334 | while (tickInfo[kIndex] < tickInfo[kLength]) { |
335 | 335 | tock = nextTickQueue[tickInfo[kIndex]++]; |
336 | 336 | callback = tock.callback; |
337 | | - threw = true; |
338 | | - try { |
339 | | - if (tock.args === undefined) |
340 | | - callback(); |
341 | | - else |
342 | | - callback.apply(null, tock.args); |
343 | | - threw = false; |
344 | | - } finally { |
345 | | - if (threw) |
346 | | - tickDone(); |
| 337 | + args = tock.args; |
| 338 | + // Using separate callback execution functions helps to limit the |
| 339 | + // scope of DEOPTs caused by using try blocks and allows direct |
| 340 | + // callback invocation with small numbers of arguments to avoid the |
| 341 | + // performance hit associated with using `fn.apply()` |
| 342 | + if (args === undefined) { |
| 343 | + doNTCallback0(callback); |
| 344 | + } else { |
| 345 | + switch (args.length) { |
| 346 | + case 1: |
| 347 | + doNTCallback1(callback, args[0]); |
| 348 | + break; |
| 349 | + case 2: |
| 350 | + doNTCallback2(callback, args[0], args[1]); |
| 351 | + break; |
| 352 | + case 3: |
| 353 | + doNTCallback3(callback, args[0], args[1], args[2]); |
| 354 | + break; |
| 355 | + default: |
| 356 | + doNTCallbackMany(callback, args); |
| 357 | + } |
347 | 358 | } |
348 | 359 | if (1e4 < tickInfo[kIndex]) |
349 | 360 | tickDone(); |
|
355 | 366 | } |
356 | 367 |
|
357 | 368 | function _tickDomainCallback() { |
358 | | - var callback, domain, threw, tock; |
| 369 | + var callback, domain, args, tock; |
359 | 370 |
|
360 | 371 | do { |
361 | 372 | while (tickInfo[kIndex] < tickInfo[kLength]) { |
362 | 373 | tock = nextTickQueue[tickInfo[kIndex]++]; |
363 | 374 | callback = tock.callback; |
364 | 375 | domain = tock.domain; |
| 376 | + args = tock.args; |
365 | 377 | if (domain) |
366 | 378 | domain.enter(); |
367 | | - threw = true; |
368 | | - try { |
369 | | - if (tock.args === undefined) |
370 | | - callback(); |
371 | | - else |
372 | | - callback.apply(null, tock.args); |
373 | | - threw = false; |
374 | | - } finally { |
375 | | - if (threw) |
376 | | - tickDone(); |
| 379 | + // Using separate callback execution functions helps to limit the |
| 380 | + // scope of DEOPTs caused by using try blocks and allows direct |
| 381 | + // callback invocation with small numbers of arguments to avoid the |
| 382 | + // performance hit associated with using `fn.apply()` |
| 383 | + if (args === undefined) { |
| 384 | + doNTCallback0(callback); |
| 385 | + } else { |
| 386 | + switch (args.length) { |
| 387 | + case 1: |
| 388 | + doNTCallback1(callback, args[0]); |
| 389 | + break; |
| 390 | + case 2: |
| 391 | + doNTCallback2(callback, args[0], args[1]); |
| 392 | + break; |
| 393 | + case 3: |
| 394 | + doNTCallback3(callback, args[0], args[1], args[2]); |
| 395 | + break; |
| 396 | + default: |
| 397 | + doNTCallbackMany(callback, args); |
| 398 | + } |
377 | 399 | } |
378 | 400 | if (1e4 < tickInfo[kIndex]) |
379 | 401 | tickDone(); |
|
386 | 408 | } while (tickInfo[kLength] !== 0); |
387 | 409 | } |
388 | 410 |
|
| 411 | + function doNTCallback0(callback) { |
| 412 | + var threw = true; |
| 413 | + try { |
| 414 | + callback(); |
| 415 | + threw = false; |
| 416 | + } finally { |
| 417 | + if (threw) |
| 418 | + tickDone(); |
| 419 | + } |
| 420 | + } |
| 421 | + |
| 422 | + function doNTCallback1(callback, arg1) { |
| 423 | + var threw = true; |
| 424 | + try { |
| 425 | + callback(arg1); |
| 426 | + threw = false; |
| 427 | + } finally { |
| 428 | + if (threw) |
| 429 | + tickDone(); |
| 430 | + } |
| 431 | + } |
| 432 | + |
| 433 | + function doNTCallback2(callback, arg1, arg2) { |
| 434 | + var threw = true; |
| 435 | + try { |
| 436 | + callback(arg1, arg2); |
| 437 | + threw = false; |
| 438 | + } finally { |
| 439 | + if (threw) |
| 440 | + tickDone(); |
| 441 | + } |
| 442 | + } |
| 443 | + |
| 444 | + function doNTCallback3(callback, arg1, arg2, arg3) { |
| 445 | + var threw = true; |
| 446 | + try { |
| 447 | + callback(arg1, arg2, arg3); |
| 448 | + threw = false; |
| 449 | + } finally { |
| 450 | + if (threw) |
| 451 | + tickDone(); |
| 452 | + } |
| 453 | + } |
| 454 | + |
| 455 | + function doNTCallbackMany(callback, args) { |
| 456 | + var threw = true; |
| 457 | + try { |
| 458 | + callback.apply(null, args); |
| 459 | + threw = false; |
| 460 | + } finally { |
| 461 | + if (threw) |
| 462 | + tickDone(); |
| 463 | + } |
| 464 | + } |
| 465 | + |
389 | 466 | function TickObject(c, args) { |
390 | 467 | this.callback = c; |
391 | 468 | this.domain = process.domain || null; |
|
0 commit comments