-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
timers: do not use user object call/apply #12960
Conversation
Will have to run a benchmark to see performance impact... |
|
Working on it... |
FWIW it used to be common with this sort of code to put at the top of the file: var apply = (function(){}).apply; And then use that (as it has no dependencies on even someone overriding the global |
lib/timers.js
Outdated
break; | ||
case 3: | ||
callback.call(timer, args[0], args[1], args[2]); | ||
Function.prototype.call.call(callback, timer, | ||
args[0], args[1], args[2]); | ||
break; | ||
default: | ||
callback.apply(timer, args); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed the .apply
case.
Make sure to add a test with >3 arguments.
5ab342a
to
aeb5af9
Compare
Timers should work even if the user has monkey-patched `.call()` and `.apply()` to undesirable values. Refs: nodejs#12956
Looks good now :) |
Had to alter the implementation a bit from the initial attempt to get the benchmark to be neutral. Current implementation in this PR compares like this against master: improvement confidence p.value
timers/immediate.js type="breadth" thousands=2000 -0.43 % 0.67056272
timers/immediate.js type="breadth1" thousands=2000 0.10 % 0.92761906
timers/immediate.js type="breadth4" thousands=2000 -1.59 % 0.19085909
timers/immediate.js type="clear" thousands=2000 0.11 % 0.89212673
timers/immediate.js type="depth" thousands=2000 -1.63 % 0.07178678
timers/immediate.js type="depth1" thousands=2000 0.90 % 0.35150859
timers/set-immediate-breadth-args.js millions=5 0.49 % 0.50576472
timers/set-immediate-breadth.js millions=10 -0.34 % 0.36237802
timers/set-immediate-depth-args.js millions=10 -1.44 % 0.10138701
timers/set-immediate-depth.js millions=10 -0.81 % 0.42620317
timers/timers-breadth.js thousands=500 -0.18 % 0.80576168
timers/timers-cancel-pooled.js thousands=500 1.10 % 0.27800863
timers/timers-cancel-unpooled.js thousands=100 0.31 % 0.22503088
timers/timers-depth.js thousands=1 0.02 % 0.95753131
timers/timers-insert-pooled.js thousands=500 -0.21 % 0.85337983
timers/timers-insert-unpooled.js thousands=100 0.06 % 0.93189629
timers/timers-timeout-pooled.js thousands=500 -0.77 % 0.48345237 |
Well, for perfect robustness (and Web IDL compliance, which I know we don't particularly care for) we need to get the initial value of |
I think we should leak C++ helpers for |
They are equivalent, and the C++ helpers will be much slower than JS. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM pending some benchmark / profiling output, which is the reason this code was this way.
Benchmark results are included above. They show no significant performance change. No changes have been applied to this PR since those benchmarks have been run. |
How about hiding the defaults behind symbols on |
The benchmark results look ok to me, but I am also concerned about this being a slippery slope. Just how far down the rabbit hole of protecting against userland do we have to go? |
I'd like us to go this far down the rabbit hole:
If the answer to both questions is "yes" (or at least "seems likely"), then I'm good with it. On the "affect actual users", I should note that I may be making an incorrect assumption here. I assumed that because @daurnimator opened an issue about this behavior, it is something that affected them. |
@TimothyGu I followed up on your suggestion #12981 |
Just noting... I've been stewing over an internal module that captures the original exports for key items like |
Indeed. And this was just the first thing I ran into, as |
Timers should work even if the user has monkey-patched `.call()` and `.apply()` to undesirable values. PR-URL: nodejs#12960 Ref: nodejs#12956 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
Landed in 98609fc. |
Timers should work even if the user has monkey-patched `.call()` and `.apply()` to undesirable values. PR-URL: nodejs#12960 Ref: nodejs#12956 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
is this applicable to lts v6.x? |
@MylesBorins Yes. |
Failures on v6.x
Can you please backport |
@MylesBorins Needs #12027 to land first, then that error should go away. |
(Removing |
Timers should work even if the user has monkey-patched `.call()` and `.apply()` to undesirable values. PR-URL: #12960 Ref: #12956 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
Timers should work even if the user has monkey-patched `.call()` and `.apply()` to undesirable values. PR-URL: #12960 Ref: #12956 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
setTimeout()
andsetInterval()
should work even if the user hasmonkey-patched
.call()
and.apply()
to undesirable values. (This istrue for
setImmediate()
as well, butsetImmediate()
works just finein the current implementation. The test added here nonetheless adds a
test for
setImmediate()
as well assetTimeout()
andsetInterval()
.Refs: #12956
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
timers