Scalar replacement issue in JDK 14.0.1
David Holmes
david.holmes at oracle.com
Fri Jun 26 13:57:05 UTC 2020
Hi Sergie,
This seems like a question for hotspot-compiler-dev rather than
core-libs-dev.
Thanks,
David
On 26/06/2020 10:06 pm, Сергей Цыпанов wrote:
> Hello,
>
> while looking into an issue I've found out that scalar replacement is not working in trivial case on JDK 14.0.1.
>
> This benchmark illustrates the issue:
>
> @State(Scope.Thread)
> @BenchmarkMode(Mode.AverageTime)
> @OutputTimeUnit(TimeUnit.NANOSECONDS)
> @Fork(jvmArgsAppend = {"-Xms2g", "-Xmx2g"})
> public class StringCompositeKeyBenchmark {
> @Benchmark
> public Object compositeKey(Data data) {
> return data.keyObjectMap.get(new Key(data.code, data.locale));
> }
>
>
> @State(Scope.Thread)
> public static class Data {
> private final String code = "code1";
> private final Locale locale = Locale.getDefault();
>
> private final HashMap<Key, Object> keyObjectMap = new HashMap<>();
>
> @Setup
> public void setUp() {
> keyObjectMap.put(new Key(code, locale), new Object());
> }
> }
>
> private static final class Key {
> private final String code;
> private final Locale locale;
>
> private Key(String code, Locale locale) {
> this.code = code;
> this.locale = locale;
> }
>
> @Override
> public boolean equals(Object o) {
> if (this == o) return true;
> if (o == null || getClass() != o.getClass()) return false;
>
> Key key = (Key) o;
>
> if (!code.equals(key.code)) return false;
> return locale.equals(key.locale);
> }
>
> @Override
> public int hashCode() {
> return 31 * code.hashCode() + locale.hashCode();
> }
> }
> }
>
> When I run this on JDK 11 (JDK 11.0.7, OpenJDK 64-Bit Server VM, 11.0.7+10-post-Ubuntu-2ubuntu218.04) I get this output:
>
> Benchmark Mode Cnt Score Error Units
> StringCompositeKeyBenchmark.compositeKey avgt 10 5.510 ± 0.121 ns/op
> StringCompositeKeyBenchmark.compositeKey:·gc.alloc.rate avgt 10 ≈ 10⁻⁴ MB/sec
> StringCompositeKeyBenchmark.compositeKey:·gc.alloc.rate.norm avgt 10 ≈ 10⁻⁶ B/op
> StringCompositeKeyBenchmark.compositeKey:·gc.count avgt 10 ≈ 0 counts
>
> As I understand Java runtime erases object allocation here and we don't use additional memory.
>
> Same run on JDK 14 (JDK 14.0.1, Java HotSpot(TM) 64-Bit Server VM, 14.0.1+7) demonstrate object allocation per each method call:
>
> Benchmark Mode Cnt Score Error Units
> StringCompositeKeyBenchmark.compositeKey avgt 10 7.958 ± 1.360 ns/op
> StringCompositeKeyBenchmark.compositeKey:·gc.alloc.rate avgt 10 1937.551 ± 320.718 MB/sec
> StringCompositeKeyBenchmark.compositeKey:·gc.alloc.rate.norm avgt 10 24.001 ± 0.001 B/op
> StringCompositeKeyBenchmark.compositeKey:·gc.churn.G1_Eden_Space avgt 10 1879.111 ± 596.770 MB/sec
> StringCompositeKeyBenchmark.compositeKey:·gc.churn.G1_Eden_Space.norm avgt 10 23.244 ± 5.509 B/op
> StringCompositeKeyBenchmark.compositeKey:·gc.churn.G1_Survivor_Space avgt 10 0.267 ± 0.750 MB/sec
> StringCompositeKeyBenchmark.compositeKey:·gc.churn.G1_Survivor_Space.norm avgt 10 0.003 ± 0.009 B/op
> StringCompositeKeyBenchmark.compositeKey:·gc.count avgt 10 23.000 counts
> StringCompositeKeyBenchmark.compositeKey:·gc.time avgt 10 44.000 ms
>
> At the same time in more trivial scenario like
>
> @Benchmark
> public int compositeKey(Data data) {
> return new Key(data.code, data.locale).hashCode();
> }
>
> scalar replacement again eliminates allocation of object.
>
> So I'm curious whether this is normal behaviour or a bug?
>
> Regards,
> Sergey Tsypanov
>
More information about the core-libs-dev
mailing list