Uh oh!
There was an error while loading. Please reload this page.
child_process: fix deoptimizing use of arguments - #11535
Conversation
There was a problem hiding this comment.
It prevents named parameter from leaking in a lower scope causing deopt. See https://bugs.chromium.org/p/v8/issues/detail?id=6010
There was a problem hiding this comment.
I've just upped this line from the inner exithandler() function. It seems this does not cause any scope conflict.
There was a problem hiding this comment.
Eh… Understood.
Perhaps this deserves some kind of comment there, /cc @mscdex.
There was a problem hiding this comment.
Also /cc @nodejs/v8 and @targos.
I don't think that this is the only place that is affected by our update to V8 5.6, I expect more deopts like this.
This better should be fixed on the V8 side instead of rewriting all the places in Node.js where a named function parameter is used in a child scope.
There was a problem hiding this comment.
It happens only if arguments[i] is read, so it could not be a huge number of cases.
There was a problem hiding this comment.
I believe the whole arguments[..] and named parameter mixed usage deopt has been around for awhile, long before V8 5.6?
There was a problem hiding this comment.
@mscdex These two factors do not cause deopt in:
v8 4.5.103.45 (Node.js 4.8.0 x64)
v8 5.1.281.93 (Node.js 6.10.0 x64)
v8 5.5.372.40 (Node.js 7.6.0 x64)
And I have not seen this case in any articles on v8 optimization.
There was a problem hiding this comment.
I believe the whole arguments[..] and named parameter mixed usage deopt has been around for awhile, long before V8 5.6?
Only outside of the strict mode if I remember things correctly, but I could be mistaken.
The linked bug is about the code in the strict mode.
There was a problem hiding this comment.
@ChALkeR There was a slightly different case in the sloppy mode: reassigning a defined parameter + mentioning arguments.
cjihrig
commented
Feb 24, 2017
This seems like the wrong approach to me. It introduces more uses of |
@cjihrig I was not sure I should refactor it, I've just tried not to be very intrusive. But yes, I can try to add named parameters. |
vsemozhetbyt
commented
Feb 24, 2017
@cjihrig Fixed for |
vsemozhetbyt
commented
Feb 24, 2017
Build and tests are OK. I will launch a new benchmark run and will post the results a bit later. |
cjihrig
left a comment
There was a problem hiding this comment.
This looks better to me. One last comment though. Is there a performance hit for reassigning named parameters. It looks like we might be able to get away with not having separate variables from the parameters. I know we do that in other places in core (and it looks cleaner), but again, I'm not sure about any performance hit.
There was a problem hiding this comment.
You shouldn't need the leading options_ now, right?
There was a problem hiding this comment.
I've though it would eliminate unneeded type check / function call (isArray() below) on undefined and would be a bit faster. Should I delete them?
There was a problem hiding this comment.
It's hard to know what V8 will do from version to version, but won't the leading options_ require a conversion to a boolean and comparison against true?
There was a problem hiding this comment.
It seems so) So should I delete them?
There was a problem hiding this comment.
Same comment here about the leading args_
vsemozhetbyt
commented
Feb 24, 2017
@cjihrig If I remember right, in the ES6 named parameters and Maybe this simplification could be done as a separate PR by a more experienced contributor? It seems there are many other similar cases in the libs. |
cjihrig
commented
Feb 24, 2017
I don't think that matters. That's more of a style preference. Since we already do it in core, I think it only matters if it hurts performance.
I'd rather get this figured out in one PR than having a second PR to change the exact same thing (churn, backporting overhead, etc.). |
vsemozhetbyt
commented
Feb 24, 2017
So should I wait till some more opinions or should I remove the mediatorial params now? |
cjihrig
commented
Feb 24, 2017
@mscdex probably knows the answer :-) |
There was a problem hiding this comment.
This would be more manageable as a switch (methodName) {} structure... with each case handled in a separate function.
There was a problem hiding this comment.
This would also be better as a switch (params) {} block
vsemozhetbyt
commented
Feb 24, 2017
New benchmark with amended commits: |
cjihrig
commented
Feb 28, 2017
@vsemozhetbyt would you be OK with using your benchmark to investigate the idea from #11535 (review). Then, we can get this through the CI and landed. |
vsemozhetbyt
commented
Mar 1, 2017
@cjihrig It seems OK: |
cjihrig
commented
Mar 1, 2017
Awesome. The code looks cleaner, and has less use of |
Fixed functions: normalizeExecArgs(), exports.execFile(), normalizeSpawnArguments() Refs: #10323 Refs: https://bugs.chromium.org/p/v8/issues/detail?id=6010
vsemozhetbyt
commented
Mar 1, 2017
Squashed. |
cjihrig
commented
Mar 1, 2017
cjihrig
commented
Mar 1, 2017
Landed in dd81d53. Thanks for working through this. |
Removed or fixed use of arguments in execFile(), normalizeExecArgs(), and normalizeSpawnArguments(). Refs: #10323 Refs: https://bugs.chromium.org/p/v8/issues/detail?id=6010 PR-URL: #11535 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com>
evanlucas
commented
Mar 7, 2017
This is not landing cleanly on v7.x-staging. Mind backporting? |
vsemozhetbyt
commented
Mar 7, 2017
@evanlucas I never backported a PR. I shall try to learn how to do this and then shall try to apply if nobody does it sooner. |
vsemozhetbyt
commented
Mar 8, 2017
@evanlucas PTAL: #11748 |
Removed or fixed use of arguments in execFile(), normalizeExecArgs(), and normalizeSpawnArguments(). Refs: #10323 Refs: https://bugs.chromium.org/p/v8/issues/detail?id=6010 Backport-Of: #11535 PR-URL: #11748 Reviewed-By: James M Snell <jasnell@gmail.com>
gibfahn
commented
Jun 17, 2017
See #11748 (comment) Should this be backported to v6.x-staging? If yes please follow the guide and raise a backport PR, if no let me know or add the |
Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passesAffected core subsystem(s)
child_process, benchmarks
This is the last unaddressed case from mentioned in the #10323. PR fixes three functions.
1. Function
normalizeExecArgs()is called byexports.exec()andexports.execSync()with a variable number of parameters.To check deoptimizations, run this code with
--trace_opt --trace_deoptflags:You will see messages about
normalizeExecArgs()deoptimization.None of the current benchmarks checks this case: the only benchmark calling
exports.exec()does it once and always with 2 parameters.2. Function
exports.execFile()is called by users with a variable number of parameters. See also #10323 (comment)To check deoptimizations, run this code with
--trace_opt --trace_deoptflags:You will see messages about
exports.execFile()deoptimization.None of the current benchmarks checks
exports.execFile().3. Function
normalizeSpawnArguments()is called byexports.spawn(),exports.spawnSync(), andexports.execFileSync()with a variable number of parameters.To check deoptimizations, run this code with
--trace_opt --trace_deoptflags:You will see messages about
normalizeSpawnArguments()deoptimization.None of the current benchmarks checks
exports.spawnSync()orexports.execFileSync(). Two of them callexports.spawn()once with 3 params (not appropriate). One of them callsexports.spawn()1000 times with 2 params, but it does not cover all sub-cases.4. While fixing these cases, I've found an absolutely new deopt case in the
exports.execFile()function introduced by v8 5.6. See the fourth commit and explanation in the upstream issue.5. As changes affect almost all main
child_processmethods (except.fork()), I've added a benchmark calling these 6 methods with 1, 2, 3, and 4 params (when it is appropriate). Benchmarking is a bit murky in this case because of many external sync/async processes involved, but it seems no significant degradation is caused, moreover some tiny improvement is evident.