[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
Tobias Hartmann
tobias.hartmann at oracle.com
Fri Dec 20 11:13:15 UTC 2019
Hi,
please review the following patch:
https://bugs.openjdk.java.net/browse/JDK-8233164
http://cr.openjdk.java.net/~thartmann/8233164/webrev.00/
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