Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
events: fix potential permanent deopt
PR-URL: #13384
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
  • Loading branch information
mscdex committed Jun 5, 2017
commit e374e44a8a1bed599379fdcf4b5fe142c5e5187d
19 changes: 17 additions & 2 deletions lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,25 @@ EventEmitter.prototype.prependListener =
};

function onceWrapper() {
this.target.removeListener(this.type, this.wrapFn);
if (!this.fired) {
this.target.removeListener(this.type, this.wrapFn);
this.fired = true;
this.listener.apply(this.target, arguments);
switch (arguments.length) {
case 0:
return this.listener.call(this.target);
case 1:
return this.listener.call(this.target, arguments[0]);
case 2:
return this.listener.call(this.target, arguments[0], arguments[1]);
case 3:
return this.listener.call(this.target, arguments[0], arguments[1],
arguments[2]);
default:
const args = new Array(arguments.length);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can arrayClone() be reused here or does it have a negative performance impact?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, because you cannot pass arguments without penalty except in only one or two cases. apply() is supposed to be one of those cases (which is what was used here before) but for some reason it can still cause a deopt (noticed this in some net benchmarks and tests).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does (...args) work (for everything) any better?
Ref: #12183

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rest parameters are still slower than fast path cases like those used above. I think rest params in general are getting faster, but still not quite where they need to be to replace fast paths.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

for (var i = 0; i < args.length; ++i)
args[i] = arguments[i];
this.listener.apply(this.target, args);
}
}
}

Expand Down