With iterative EA, we have more chances to discover dead AllocateArray nodes. however, AllocateArray is a macro node instead of a scalar, we can't use current remove useless phase to eliminate it even it's dead.
The only chance is that we do scalar replacement for the AllocateArray. That requires the length of AllocateArray is known and is not greater than EliminateAllocationArraySizeLimit(64). let alone there are other factors hinder scalar replacement.
java.util.Arrays.copyOf and copyOfRange are the common cases which generate new arrays. here is an example. the new array generated by CopyOf is dead.
import java.util.Arrays;
class ArraysCopyOfTest{
public static void foo(int[] values, int len) {
// the only chance we get AllocateArray and ArrayCopy deleted
// is that len is known and <= EliminateAllocationArraySizeLimit(64)
Arrays.copyOf(values, len);
}
public static void main(String[] args) {
int len = Integer.parseInt(args[0]);
int[] values = {1,2,3,4,5,6,7,8,9,0};
while (true) {
foo(values, len);
}
}
}
$java -Xlog:gc -XX:+PrintEscapeAnalysis -XX:+PrintEliminateAllocations -XX:+PrintCompilation -Xbatch ArraysCopyOfTest 1000000
8300 426 b 4 ArraysCopyOfTest::foo (7 bytes)
======== Connection graph for ArraysCopyOfTest::foo
invocation #0: 2 iterations and 0.000000 sec to build connection graph with 176 nodes and worklist size 11
JavaObject NoEscape(NoEscape) NSR [ [ 73 78 ]] 61 AllocateArray === 122 6 7 8 1 ( 51 32 57 11 60 1 1 10 11 1 ) [[ 62 63 64 71 72 73 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, int, bool ) Arr
ays::copyOf @ bci:1 (line 3585) ArraysCopyOfTest::foo @ bci:2 (line 7) !jvms: Arrays::copyOf @ bci:1 (line 3585) ArraysCopyOfTest::foo @ bci:2 (line 7)
LocalVar [ 61P [ 78 ]] 73 Proj === 61 [[ 74 78 ]] #5 !jvms: Arrays::copyOf @ bci:1 (line 3585) ArraysCopyOfTest::foo @ bci:2 (line 7)
LocalVar [ 73 61P [ ]] 78 CheckCastPP === 75 73 [[ 148 148 ]] #int[int:0..max-2]:NotNull:exact * !jvms: Arrays::copyOf @ bci:1 (line 3585) ArraysCopyOfTest::foo @ bci:2 (line 7)
8304 423 3 ArraysCopyOfTest::foo (7 bytes) made not entrant
[8.569s][info][gc] GC(14) Pause Young (Normal) (G1 Evacuation Pause) 1808M->0M(17664M) 105.071ms
[8.918s][info][gc] GC(15) Pause Young (Normal) (G1 Evacuation Pause) 1840M->0M(17664M) 101.638ms
[9.272s][info][gc] GC(16) Pause Young (Normal) (G1 Evacuation Pause) 1888M->0M(17664M) 101.931ms
[9.586s][info][gc] GC(17) Pause Young (Normal) (G1 Evacuation Pause) 1680M->0M(20912M) 98.580ms
...
The only chance is that we do scalar replacement for the AllocateArray. That requires the length of AllocateArray is known and is not greater than EliminateAllocationArraySizeLimit(64). let alone there are other factors hinder scalar replacement.
java.util.Arrays.copyOf and copyOfRange are the common cases which generate new arrays. here is an example. the new array generated by CopyOf is dead.
import java.util.Arrays;
class ArraysCopyOfTest{
public static void foo(int[] values, int len) {
// the only chance we get AllocateArray and ArrayCopy deleted
// is that len is known and <= EliminateAllocationArraySizeLimit(64)
Arrays.copyOf(values, len);
}
public static void main(String[] args) {
int len = Integer.parseInt(args[0]);
int[] values = {1,2,3,4,5,6,7,8,9,0};
while (true) {
foo(values, len);
}
}
}
$java -Xlog:gc -XX:+PrintEscapeAnalysis -XX:+PrintEliminateAllocations -XX:+PrintCompilation -Xbatch ArraysCopyOfTest 1000000
8300 426 b 4 ArraysCopyOfTest::foo (7 bytes)
======== Connection graph for ArraysCopyOfTest::foo
invocation #0: 2 iterations and 0.000000 sec to build connection graph with 176 nodes and worklist size 11
JavaObject NoEscape(NoEscape) NSR [ [ 73 78 ]] 61 AllocateArray === 122 6 7 8 1 ( 51 32 57 11 60 1 1 10 11 1 ) [[ 62 63 64 71 72 73 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, int, bool ) Arr
ays::copyOf @ bci:1 (line 3585) ArraysCopyOfTest::foo @ bci:2 (line 7) !jvms: Arrays::copyOf @ bci:1 (line 3585) ArraysCopyOfTest::foo @ bci:2 (line 7)
LocalVar [ 61P [ 78 ]] 73 Proj === 61 [[ 74 78 ]] #5 !jvms: Arrays::copyOf @ bci:1 (line 3585) ArraysCopyOfTest::foo @ bci:2 (line 7)
LocalVar [ 73 61P [ ]] 78 CheckCastPP === 75 73 [[ 148 148 ]] #int[int:0..max-2]:NotNull:exact * !jvms: Arrays::copyOf @ bci:1 (line 3585) ArraysCopyOfTest::foo @ bci:2 (line 7)
8304 423 3 ArraysCopyOfTest::foo (7 bytes) made not entrant
[8.569s][info][gc] GC(14) Pause Young (Normal) (G1 Evacuation Pause) 1808M->0M(17664M) 105.071ms
[8.918s][info][gc] GC(15) Pause Young (Normal) (G1 Evacuation Pause) 1840M->0M(17664M) 101.638ms
[9.272s][info][gc] GC(16) Pause Young (Normal) (G1 Evacuation Pause) 1888M->0M(17664M) 101.931ms
[9.586s][info][gc] GC(17) Pause Young (Normal) (G1 Evacuation Pause) 1680M->0M(20912M) 98.580ms
...