Skip to content

Commit

Permalink
stream: pre-allocate _events
Browse files Browse the repository at this point in the history
PR-URL: #50428
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
ronag authored and UlisesGascon committed Dec 11, 2023
1 parent 829b82e commit dd52068
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 4 deletions.
14 changes: 12 additions & 2 deletions lib/events.js
Expand Up @@ -86,6 +86,7 @@ const {

const kCapture = Symbol('kCapture');
const kErrorMonitor = Symbol('events.errorMonitor');
const kShapeMode = Symbol('shapeMode');
const kMaxEventTargetListeners = Symbol('events.maxEventTargetListeners');
const kMaxEventTargetListenersWarned =
Symbol('events.maxEventTargetListenersWarned');
Expand Down Expand Up @@ -343,6 +344,9 @@ EventEmitter.init = function(opts) {
this._events === ObjectGetPrototypeOf(this)._events) {
this._events = { __proto__: null };
this._eventsCount = 0;
this[kShapeMode] = false;
} else {
this[kShapeMode] = true;
}

this._maxListeners = this._maxListeners || undefined;
Expand Down Expand Up @@ -685,9 +689,13 @@ EventEmitter.prototype.removeListener =
return this;

if (list === listener || list.listener === listener) {
if (--this._eventsCount === 0)
this._eventsCount -= 1;

if (this[kShapeMode]) {
events[type] = undefined;
} else if (this._eventsCount === 0) {
this._events = { __proto__: null };
else {
} else {
delete events[type];
if (events.removeListener)
this.emit('removeListener', type, list.listener || listener);
Expand Down Expand Up @@ -749,6 +757,7 @@ EventEmitter.prototype.removeAllListeners =
else
delete events[type];
}
this[kShapeMode] = false;
return this;
}

Expand All @@ -761,6 +770,7 @@ EventEmitter.prototype.removeAllListeners =
this.removeAllListeners('removeListener');
this._events = { __proto__: null };
this._eventsCount = 0;
this[kShapeMode] = false;
return this;
}

Expand Down
18 changes: 18 additions & 0 deletions lib/internal/streams/duplex.js
Expand Up @@ -63,6 +63,24 @@ function Duplex(options) {
if (!(this instanceof Duplex))
return new Duplex(options);

this._events ??= {
close: undefined,
error: undefined,
prefinish: undefined,
finish: undefined,
drain: undefined,
data: undefined,
end: undefined,
readable: undefined,
// Skip uncommon events...
// pause: undefined,
// resume: undefined,
// pipe: undefined,
// unpipe: undefined,
// [destroyImpl.kConstruct]: undefined,
// [destroyImpl.kDestroy]: undefined,
};

this._readableState = new Readable.ReadableState(options, this, true);
this._writableState = new Writable.WritableState(options, this, true);

Expand Down
15 changes: 15 additions & 0 deletions lib/internal/streams/readable.js
Expand Up @@ -319,6 +319,21 @@ function Readable(options) {
if (!(this instanceof Readable))
return new Readable(options);

this._events ??= {
close: undefined,
error: undefined,
data: undefined,
end: undefined,
readable: undefined,
// Skip uncommon events...
// pause: undefined,
// resume: undefined,
// pipe: undefined,
// unpipe: undefined,
// [destroyImpl.kConstruct]: undefined,
// [destroyImpl.kDestroy]: undefined,
};

this._readableState = new ReadableState(options, this, false);

if (options) {
Expand Down
11 changes: 11 additions & 0 deletions lib/internal/streams/writable.js
Expand Up @@ -385,6 +385,17 @@ function Writable(options) {
if (!(this instanceof Writable))
return new Writable(options);

this._events ??= {
close: undefined,
error: undefined,
prefinish: undefined,
finish: undefined,
drain: undefined,
// Skip uncommon events...
// [destroyImpl.kConstruct]: undefined,
// [destroyImpl.kDestroy]: undefined,
};

this._writableState = new WritableState(options, this, false);

if (options) {
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-readline-interface.js
Expand Up @@ -44,7 +44,7 @@ class FakeInput extends EventEmitter {
function isWarned(emitter) {
for (const name in emitter) {
const listeners = emitter[name];
if (listeners.warned) return true;
if (listeners && listeners.warned) return true;
}
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-readline-promises-interface.js
Expand Up @@ -22,7 +22,7 @@ class FakeInput extends EventEmitter {
function isWarned(emitter) {
for (const name in emitter) {
const listeners = emitter[name];
if (listeners.warned) return true;
if (listeners && listeners.warned) return true;
}
return false;
}
Expand Down

0 comments on commit dd52068

Please sign in to comment.