-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8362832: compiler/macronodes/TestTopInMacroElimination.java hits assert(false) failed: unexpected node #27903
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
base: master
Are you sure you want to change the base?
Conversation
|
👋 Welcome back bmaillard! A progress list of the required criteria for merging this PR into |
|
@benoitmaillard This change is no longer ready for integration - check the PR body for details. |
|
@benoitmaillard The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
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 agree with fix.
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.
Thanks for the fix @benoitmaillard!
This means that the safepoint will have top as data input, but this will
eventually cleaned up by the next round of IGVN.
Is it valid for safepoints to even temporarily have top as data input? Even if this gets cleaned up eventually by IGVN, it seems potentially risky to have it in this state.
Co-authored-by: Daniel Lundén <[email protected]>
|
Thanks for your review @dlunde. I would argue that this is acceptable, as we know the safepoint will be removed as soon as IGVN runs (since it is on a dead path). I see this as simply propagating dead path information and ensuring that it does not interfere with optimizing away the allocation. |
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.
Thanks for your review @dlunde. I would argue that this is acceptable, as we know the safepoint will be removed as soon as IGVN runs (since it is on a dead path). I see this as simply propagating dead path information and ensuring that it does not interfere with optimizing away the allocation.
All right, seems harmless enough then. Thanks!
|
/integrate |
|
@benoitmaillard This pull request has not yet been marked as ready for integration. |
| // The slice is on a dead path. Returning top prevents bailing out | ||
| // from the elimination, and IGVN can later clean up. |
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.
You could make it more specific, and say what you say in your PR description:
return nullptr would lead to elimination bailout, but we want to prevent that. Just forwarding the top is also legal, and IGVN can just clean things up, and remove whatever receives top.
Does this mean that there could be paths that don't get top, and so for those paths it is nice that we are able to remove the allocation, right?
This PR prevents hitting an assert caused by encountering
topwhile following the memoryslice associated with a field when eliminating allocations in macro node elimination. This situation
is the result of another elimination (boxing node elimination) that happened at the same
macro expansion iteration.
Analysis
The issue appears in the macro expansion phase. We have a nested
synchronizedblock,with the outer block synchronizing on
new A()and the inner one onTestTopInMacroElimination.class.In the inner
synchronizedblock we have anInteger.valueOfcall in a loop.In
PhaseMacroExpand::eliminate_boxing_nodewe are getting rid of theInteger.valueOfcall, as it is a non-escaping boxing node. After having eliminated the call,
PhaseMacroExpand::process_users_of_allocationtakes care of the users of the removed node.There, we replace usages of the fallthrough memory projection with
top.In the same macro expansion iteration, we later attempt to get rid of the
new A()allocationin
PhaseMacroExpand::create_scalarized_object_description. There, we have to makesure that all safepoints can still see the object fields as if the allocation was never deleted.
For this, we attempt to find the last value on the slice of each specific field (
ain this case). Because field
ais never written to, and it is not explicitely initialized,there is no
Storeassociated to it and not even a dedicated memory slice (we end uptaking the
Botinput onMergeMemnodes). By going up the memory chain, we eventuallyencounter the
MemBarReleaseLockwhose input was set totop. This is where the assertis hit.
Proposed Fix
In the end I opted for an analog fix as the similar JDK-8325030.
If we get
topfromscan_mem_chaininPhaseMacroExpand::value_from_mem, then we can safelyreturn
topas well. This means that the safepoint will havetopas data input, but this willeventually cleaned up by the next round of IGVN.
Another (tempting) option would have been to simply return
nullptrfromPhaseMacroExpand::value_from_memwhen encouteringtop. However this would result in bailingout from eliminating this allocation temporarily and effectively delaying it to a subsqequent
macro expansion round.
Testing
Thank you for reviewing!
Progress
Issue
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/27903/head:pull/27903$ git checkout pull/27903Update a local copy of the PR:
$ git checkout pull/27903$ git pull https://git.openjdk.org/jdk.git pull/27903/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 27903View PR using the GUI difftool:
$ git pr show -t 27903Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/27903.diff
Using Webrev
Link to Webrev Comment