8258393: Shenandoah: "graph should be schedulable" assert failure #41
Conversation
👋 Welcome back roland! A progress list of the required criteria for merging this PR into |
/label add hotspot-compiler |
@rwestrel |
/label remove hotspot |
@rwestrel |
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.
As far as I can tell, the change looks good. I'm not very familiar with the code, it would be good to have somebody else check it too.
I verified that the tests that failed before are passing now and also have run some additional tests.
@rwestrel This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been no new commits pushed to the ➡️ To integrate this PR with the above commit message to the |
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.
Otherwise looks reasonable to me.
|
||
/** | ||
* @test | ||
* |
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.
Missing @requires vm.gc.Shenandoah
@@ -0,0 +1,70 @@ | |||
/* | |||
* Copyright (c) 2020, Red Hat, Inc. All rights reserved. |
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.
Copyright should be updated to 2021.
assert(!ctrl->is_Call() || ctrl == n, "projection expected"); | ||
#ifdef ASSERT | ||
if ((ctrl->is_Proj() && ctrl->in(0)->is_Call()) || | ||
(ctrl->is_Catch() && ctrl->in(0)->in(0)->is_Call())){ |
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.
Indentation is wrong and whitespace is missing here ))){
for (uint j = 1; j < s->req(); j++) { | ||
Node* in = s->in(j); | ||
Node* r_in = r->in(j); | ||
if (worklist.member(in) && is_dominator(early, r_in)) { |
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.
Above we check for !sctrl->is_top()
, do we need the same check for r_in
?
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 don't think a Region can have a top input at this point (previous IGVN should have taken care of it).
Thanks for the review. I took care of your comments (except for the is_top() check that I don't think is 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.
Thanks for updating, looks good to me.
thanks for the review and running tests. |
/integrate |
This is a shenandoah bug but the fix is in shared code.
At barrier expansion time, we need the raw memory state for the
control at which the barrier is expanded. Before expansion, the memory
graph is traversed and memory state for each control is recorded. In
that process, if opportunities to improve the memory graph are found,
the graph is modified. In the case of the failure, a raw memory load
was assigned a call projection as control but for that control, no
memory state was recorded and the fall back is to use the call's input
memory state. As a consequence the load's memory input is updated to a
wrong memory state. This causes the assert failure.
The call has 2 memory projections: one for the fallthrough and one for
the exception path. One projection is the memory state for the
CatchProj for the fallthrough, the other one for the CatchProj of the
exception path. For the control projection out of the call, there's no
memory state that makes sense and assigning the control projection of
the call as control for the load is the root cause of the
problem. This happens because anti-dependence analysis is too
conservative: a memory Phi that merges states from the exception and
fallthrough path is considered a dependency and that pushed the load
right after the call.
I propose to be less conservative in anti-dependence analysis for
Phis. For a Phi, when computing the LCA, I think it's sufficient to
only consider region's inputs that we actually reach by following the
memory edges and that's what I propose here.
Progress
Issue
Reviewers
Download
$ git fetch https://git.openjdk.java.net/jdk16 pull/41/head:pull/41
$ git checkout pull/41