|
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