-
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
child_process: fix deoptimizing use of arguments #11535
Closed
vsemozhetbyt
wants to merge
1
commit into
nodejs:master
from
vsemozhetbyt:fix-child-process-arguments-1
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
'use strict'; | ||
|
||
const common = require('../common.js'); | ||
const cp = require('child_process'); | ||
|
||
const command = 'echo'; | ||
const args = ['hello']; | ||
const options = {}; | ||
const cb = () => {}; | ||
|
||
const configs = { | ||
n: [1e3], | ||
methodName: [ | ||
'exec', 'execSync', | ||
'execFile', 'execFileSync', | ||
'spawn', 'spawnSync', | ||
], | ||
params: [1, 2, 3, 4], | ||
}; | ||
|
||
const bench = common.createBenchmark(main, configs); | ||
|
||
function main(conf) { | ||
const n = +conf.n; | ||
const methodName = conf.methodName; | ||
const params = +conf.params; | ||
|
||
const method = cp[methodName]; | ||
|
||
switch (methodName) { | ||
case 'exec': | ||
switch (params) { | ||
case 1: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command).kill(); | ||
bench.end(n); | ||
break; | ||
case 2: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command, options).kill(); | ||
bench.end(n); | ||
break; | ||
case 3: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command, options, cb).kill(); | ||
bench.end(n); | ||
break; | ||
} | ||
break; | ||
case 'execSync': | ||
switch (params) { | ||
case 1: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command); | ||
bench.end(n); | ||
break; | ||
case 2: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command, options); | ||
bench.end(n); | ||
break; | ||
} | ||
break; | ||
case 'execFile': | ||
switch (params) { | ||
case 1: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command).kill(); | ||
bench.end(n); | ||
break; | ||
case 2: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command, args).kill(); | ||
bench.end(n); | ||
break; | ||
case 3: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command, args, options).kill(); | ||
bench.end(n); | ||
break; | ||
case 4: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command, args, options, cb).kill(); | ||
bench.end(n); | ||
break; | ||
} | ||
break; | ||
case 'execFileSync': | ||
switch (params) { | ||
case 1: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command); | ||
bench.end(n); | ||
break; | ||
case 2: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command, args); | ||
bench.end(n); | ||
break; | ||
case 3: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command, args, options); | ||
bench.end(n); | ||
break; | ||
} | ||
break; | ||
case 'spawn': | ||
switch (params) { | ||
case 1: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command).kill(); | ||
bench.end(n); | ||
break; | ||
case 2: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command, args).kill(); | ||
bench.end(n); | ||
break; | ||
case 3: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command, args, options).kill(); | ||
bench.end(n); | ||
break; | ||
} | ||
break; | ||
case 'spawnSync': | ||
switch (params) { | ||
case 1: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command); | ||
bench.end(n); | ||
break; | ||
case 2: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command, args); | ||
bench.end(n); | ||
break; | ||
case 3: | ||
bench.start(); | ||
for (let i = 0; i < n; i++) method(command, args, options); | ||
bench.end(n); | ||
break; | ||
} | ||
break; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Why is this change needed?
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eh… Understood.
Perhaps this deserves some kind of comment there, /cc @mscdex.
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mscdex
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ChALkeR There was a slightly different case in the sloppy mode: reassigning a defined parameter + mentioning
arguments
.