RFR: 8292301: [REDO v2] C2 crash when allocating array of size too large [v2]
Tobias Hartmann
thartmann at openjdk.org
Thu Sep 8 07:18:59 UTC 2022
On Fri, 2 Sep 2022 09:02:54 GMT, Roland Westrelin <roland at openjdk.org> wrote:
>> On top of the redo, this fixed 2 bugs:
>>
>> 8288184: the problem here is that the ValidLengthTest input of an
>> AllocateArrayNode becomes a constant. The CatchNode would then change
>> types if it was reprocessed but it's not. Custom logic is needed to
>> enqueue the CatchNode when the ValidLengthTest input of an
>> AllocateArrayNode changes. The CastII out of the AllocateArrayNode
>> becomes top but the fallthrough path doesn't die. This happens with
>> igvn in the case of the bug but could also happen with ccp. I fixed
>> both in this patch.
>>
>> 8291665: the code pattern for this is 2 AllocateArrayNodes out of loop
>> with a shared ValidLengthTest input in a loop. When the loop is cloned
>> that causes Phis to be added between the AllocateArrayNodes and the
>> BoolNode of the ValidLengthTest inputs. Split if runs next and it
>> doesn't expect the Phi at the ValidLengthTest inputs. The fix here is
>> to clone the Bool/Cmp subgraph down on loop cloning. There's logic for
>> that when the use of the bool is an If for instance so I simply added
>> a special case to run that logic for an AllocateArrayNode use as
>> well. Note that the test case I added fails reliably on 11 but not
>> with the current jdk developement branch. AFAICT, the bug is there but
>> something unrelated changed and a slightly different graph is built
>> for the test case that prevents split if.
>
> Roland Westrelin has updated the pull request incrementally with one additional commit since the last revision:
>
> undo needless change
Looks good otherwise.
src/hotspot/share/opto/loopopts.cpp line 2040:
> 2038: // loop to determine which way the loop exited.
> 2039: // Loop predicate If node connects to Bool node through Opaque1 node.
> 2040: if (use->is_If() || use->is_CMove() || C->is_predicate_opaq(use) || use->Opcode() == Op_Opaque4 ||
Please add a comment describing the new case.
src/hotspot/share/opto/loopopts.cpp line 2410:
> 2408: while (split_if_set->size()) {
> 2409: Node *iff = split_if_set->pop();
> 2410: uint input = iff->Opcode() == Op_AllocateArray ? AllocateNode::ValidLengthTest : 1;
Suggestion:
uint input = (iff->Opcode() == Op_AllocateArray) ? AllocateNode::ValidLengthTest : 1;
src/hotspot/share/opto/phaseX.cpp line 1643:
> 1641: }
> 1642: }
> 1643: if (use_op == Op_AllocateArray && n == use->in(AllocateNode::ValidLengthTest)) {
Please add a comment.
src/hotspot/share/opto/phaseX.cpp line 1853:
> 1851: // If we changed the receiver type to a call, we need to revisit the Catch node following the call. It's looking for a
> 1852: // non-NULL receiver to know when to enable the regular fall-through path in addition to the NullPtrException path.
> 1853: // Same if true if the type of a ValidLengthTest input to an AllocateArrayNode changes
Suggestion:
// Same is true if the type of a ValidLengthTest input to an AllocateArrayNode changes.
-------------
Marked as reviewed by thartmann (Reviewer).
PR: https://git.openjdk.org/jdk/pull/10038
More information about the hotspot-compiler-dev
mailing list