@@ -32,32 +32,55 @@ function setupNextTick() {
3232 const kHasScheduled = 0 ;
3333 const kHasPromiseRejections = 1 ;
3434
35- const nextTickQueue = {
36- head : null ,
37- tail : null ,
35+ // Queue size for each tick array. Must be a factor of two.
36+ const kQueueSize = 2048 ;
37+ const kQueueMask = kQueueSize - 1 ;
38+
39+ class FixedQueue {
40+ constructor ( ) {
41+ this . bottom = 0 ;
42+ this . top = 0 ;
43+ this . list = new Array ( kQueueSize ) ;
44+ this . next = null ;
45+ }
46+
3847 push ( data ) {
39- const entry = { data, next : null } ;
40- if ( this . tail !== null ) {
41- this . tail . next = entry ;
42- } else {
43- this . head = entry ;
44- tickInfo [ kHasScheduled ] = 1 ;
45- }
46- this . tail = entry ;
47- } ,
48+ this . list [ this . top ] = data ;
49+ this . top = ( this . top + 1 ) & kQueueMask ;
50+ }
51+
4852 shift ( ) {
49- if ( this . head === null )
50- return ;
51- const ret = this . head . data ;
52- if ( this . head === this . tail ) {
53- this . head = this . tail = null ;
53+ const next = this . list [ this . bottom ] ;
54+ if ( next === undefined ) return null ;
55+ this . list [ this . bottom ] = undefined ;
56+ this . bottom = ( this . bottom + 1 ) & kQueueMask ;
57+ return next ;
58+ }
59+ }
60+
61+ var head = new FixedQueue ( ) ;
62+ var tail = head ;
63+
64+ function push ( data ) {
65+ if ( head . bottom === head . top ) {
66+ if ( head . list [ head . top ] !== undefined )
67+ head = head . next = new FixedQueue ( ) ;
68+ else
69+ tickInfo [ kHasScheduled ] = 1 ;
70+ }
71+ head . push ( data ) ;
72+ }
73+
74+ function shift ( ) {
75+ const next = tail . shift ( ) ;
76+ if ( tail . top === tail . bottom ) {
77+ if ( tail . next )
78+ tail = tail . next ;
79+ else
5480 tickInfo [ kHasScheduled ] = 0 ;
55- } else {
56- this . head = this . head . next ;
57- }
58- return ret ;
5981 }
60- } ;
82+ return next ;
83+ }
6184
6285 process . nextTick = nextTick ;
6386 // Needs to be accessible from beyond this scope.
@@ -69,7 +92,7 @@ function setupNextTick() {
6992 function _tickCallback ( ) {
7093 let tock ;
7194 do {
72- while ( tock = nextTickQueue . shift ( ) ) {
95+ while ( tock = shift ( ) ) {
7396 const asyncId = tock [ async_id_symbol ] ;
7497 emitBefore ( asyncId , tock [ trigger_async_id_symbol ] ) ;
7598 // emitDestroy() places the async_id_symbol into an asynchronous queue
@@ -93,7 +116,7 @@ function setupNextTick() {
93116 emitAfter ( asyncId ) ;
94117 }
95118 runMicrotasks ( ) ;
96- } while ( nextTickQueue . head !== null || emitPromiseRejectionWarnings ( ) ) ;
119+ } while ( head . top !== head . bottom || emitPromiseRejectionWarnings ( ) ) ;
97120 tickInfo [ kHasPromiseRejections ] = 0 ;
98121 }
99122
@@ -139,8 +162,7 @@ function setupNextTick() {
139162 args [ i - 1 ] = arguments [ i ] ;
140163 }
141164
142- nextTickQueue . push ( new TickObject ( callback , args ,
143- getDefaultTriggerAsyncId ( ) ) ) ;
165+ push ( new TickObject ( callback , args , getDefaultTriggerAsyncId ( ) ) ) ;
144166 }
145167
146168 // `internalNextTick()` will not enqueue any callback when the process is
@@ -168,6 +190,6 @@ function setupNextTick() {
168190
169191 if ( triggerAsyncId === null )
170192 triggerAsyncId = getDefaultTriggerAsyncId ( ) ;
171- nextTickQueue . push ( new TickObject ( callback , args , triggerAsyncId ) ) ;
193+ push ( new TickObject ( callback , args , triggerAsyncId ) ) ;
172194 }
173195}
0 commit comments