[14] RFR(S): 8233164: C2 fails with assert(phase->C->get_alias_index(t) == phase->C->get_alias_index(t_adr)) failed: correct memory chain
Vladimir Ivanov
vladimir.x.ivanov at oracle.com
Fri Dec 20 11:25:30 UTC 2019
> http://cr.openjdk.java.net/~thartmann/8233164/webrev.00/
Looks good.
Best regards,
Vladimir Ivanov
> The problem is that the arraycopy ideal transformation does not correctly wire memory inputs on
> individual loads from a non-escaping src array.
>
> I was able to extract a test from the intermittently failing application that depends on indify
> string concat (test1). From that, I've created another test that does not depend on Strings (test2).
>
> Gory details based on test2:
> Two subsequent arraycopies copy data from two sources into the same destination. The ideal
> transformation replaces the first arraycopy by a forward and backward copy (because
> ArrayCopyNode::array_copy_test_overlap determines that the arrays may overlap). A PhiNode is added
> to select between the memory outputs of the forward and backward stores:
> http://hg.openjdk.java.net/jdk/jdk/file/2fbc66ef1a1d/src/hotspot/share/opto/arraycopynode.cpp#l617
>
> 574 StoreB === 559 572 553 573 [[ 568 576 ]] @byte[int:0..max-2]:NotNull:exact+any ...
> 567 StoreB === 558 562 565 566 [[ 560 576 ]] @byte[int:0..max-2]:NotNull:exact+any ...
> 575 Region === 575 558 559 [[ 575 576 ]]
> 576 Phi === 575 567 574 [[]] #memory Memory: @byte[int:>=0]:exact+any *, idx=6;
>
> The second arraycopy can't be optimized (yet) because the src operand and its length are not known
> but once Escape Analysis is executed, it determines that both source arrays are non-escaping. Now
> the ideal transformation is able to replace the second arraycopy by loads/stores as well.
>
> The memory slice for the first load is selected from the MergeMem based on its address type
> ('atp_src') which is the general byte[int:>=0] slice due to a CastPP that hides the type of the
> non-escaping source array. As a result, we wire it to the byte[int:>=0] memory Phi that was created
> when optimizing the first arraycopy:
>
> 305 CheckCastPP === 302 300 [[ 385 316 420 494 ]] #byte[int:1]:NotNull:exact *,iid=288
> 494 CastPP === 486 305 [[ 526 514 626 626 ]] #byte[int:>=0]:NotNull:exact *
> 626 AddP === _ 494 494 68 [[ 629 ]]
> 576 Phi === 575 567 574 [[ 560 628 629 ]] #memory Memory: @byte[int:>=0]:exact+any
> 629 LoadB === 508 576 626 [[]] @byte[int:>=0]:NotNull:exact+any *, idx=6; #byte
>
> That's obviously incorrect because now the LoadB has an address input into a non-escaping source
> with type byte[int:1], iid=288 and a memory input from the independent byte[int:>=0] slice:
> http://cr.openjdk.java.net/~thartmann/8233164/graph_Failure.png
>
> Basically, 629 LoadB uses memory from 47 AllocateArray when loading from an address into
> non-escaping 288 AllocateArray. We then hit an assert in MemNode::optimize_memory_chain.
>
> The fix is to use _src_type/_dest_type (introduced by JDK-8076188) as address types for the loads
> and stores. These will have the correct type if the source or destination array is non-escaping.
>
> The affected code is in there for a long time but I can only reproduce this back until JDK 13 b08
> when JDK-8217990 was fixed. I don't think that fix is related but since the crash greatly depends on
> the order in which nodes are processed by IGVN, it probably just triggers the issue (for example, if
> we process a CastPP node first, it goes away and we get the correct type from the CheckCastPP). The
> code was also changed significantly by JDK-8210887 in JDK 12.
>
> Thanks,
> Tobias
>
More information about the hotspot-compiler-dev
mailing list