@@ -32,32 +32,55 @@ function setupNextTick() {
32
32
const kHasScheduled = 0 ;
33
33
const kHasPromiseRejections = 1 ;
34
34
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
+
38
47
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
+
48
52
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
54
80
tickInfo [ kHasScheduled ] = 0 ;
55
- } else {
56
- this . head = this . head . next ;
57
- }
58
- return ret ;
59
81
}
60
- } ;
82
+ return next ;
83
+ }
61
84
62
85
process . nextTick = nextTick ;
63
86
// Needs to be accessible from beyond this scope.
@@ -69,7 +92,7 @@ function setupNextTick() {
69
92
function _tickCallback ( ) {
70
93
let tock ;
71
94
do {
72
- while ( tock = nextTickQueue . shift ( ) ) {
95
+ while ( tock = shift ( ) ) {
73
96
const asyncId = tock [ async_id_symbol ] ;
74
97
emitBefore ( asyncId , tock [ trigger_async_id_symbol ] ) ;
75
98
// emitDestroy() places the async_id_symbol into an asynchronous queue
@@ -93,7 +116,7 @@ function setupNextTick() {
93
116
emitAfter ( asyncId ) ;
94
117
}
95
118
runMicrotasks ( ) ;
96
- } while ( nextTickQueue . head !== null || emitPromiseRejectionWarnings ( ) ) ;
119
+ } while ( head . top !== head . bottom || emitPromiseRejectionWarnings ( ) ) ;
97
120
tickInfo [ kHasPromiseRejections ] = 0 ;
98
121
}
99
122
@@ -139,8 +162,7 @@ function setupNextTick() {
139
162
args [ i - 1 ] = arguments [ i ] ;
140
163
}
141
164
142
- nextTickQueue . push ( new TickObject ( callback , args ,
143
- getDefaultTriggerAsyncId ( ) ) ) ;
165
+ push ( new TickObject ( callback , args , getDefaultTriggerAsyncId ( ) ) ) ;
144
166
}
145
167
146
168
// `internalNextTick()` will not enqueue any callback when the process is
@@ -168,6 +190,6 @@ function setupNextTick() {
168
190
169
191
if ( triggerAsyncId === null )
170
192
triggerAsyncId = getDefaultTriggerAsyncId ( ) ;
171
- nextTickQueue . push ( new TickObject ( callback , args , triggerAsyncId ) ) ;
193
+ push ( new TickObject ( callback , args , triggerAsyncId ) ) ;
172
194
}
173
195
}
0 commit comments