1 /*
2 * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package org.openjdk.bench.vm.compiler.x86;
24
25 import org.openjdk.jmh.annotations.*;
26
27 import java.util.concurrent.TimeUnit;
28
29 @BenchmarkMode(Mode.AverageTime)
30 @OutputTimeUnit(TimeUnit.NANOSECONDS)
31 @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
32 @Measurement(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
33 // Fix heap size since the StoreN benchmarks are allocating a lot and dependent on GC selection and compressed oop mode.
34 @Fork(value = 3, jvmArgsAppend = {"-Xms1g", "-Xmx1g"})
35 @State(Scope.Thread)
36 public class RedundantLeaPeephole {
37 @State(Scope.Thread)
38 public class StoreNHelper {
39 Object o1;
40 Object o2;
41
42 public StoreNHelper(Object o1, Object o2) {
43 this.o1 = o1;
44 this.o2 = o2;
45 }
46 }
47
48 @State(Scope.Thread)
49 public class StringEqualsHelper {
50 private String str;
51
52 public StringEqualsHelper(String str) {
53 this.str = str;
54 }
55
56 @CompilerControl(CompilerControl.Mode.INLINE)
57 public boolean doEquals(String other) {
58 return this.str.equals(other);
59 }
60 }
61
62 private static final int SIZE = 42;
63 private static final int SMALL_IDX = 3;
64 private static final int BIG_IDX = 33;
65
66 private static final Object O1 = new Object();
67 private static final Object O2 = new Object();
68
69 private Object[] arr1 = new Object[SIZE];
70 private Object[] arr2 = new Object[SIZE];
71 private StoreNHelper[] arrH1 = new StoreNHelper[SIZE];
72 private StoreNHelper[] arrH2 = new StoreNHelper[SIZE];
73
74 private StringEqualsHelper strEqHelper = new StringEqualsHelper("foo");
75
76 @Benchmark
77 @Fork(jvmArgsAppend = {"-XX:+UseSerialGC"})
78 public void benchStoreNRemoveSpillSerial() {
79 this.arrH1[SMALL_IDX] = new StoreNHelper(O1, O2);
80 this.arrH2[BIG_IDX] = new StoreNHelper(O2, O1);
81 }
82
83 @Benchmark
84 @Fork(jvmArgsAppend = {"-XX:+UseParallelGC"})
85 public void benchStoreNRemoveSpillParallel() {
86 this.arrH1[SMALL_IDX] = new StoreNHelper(O1, O2);
87 this.arrH2[BIG_IDX] = new StoreNHelper(O2, O1);
88 }
89
90 @Benchmark
91 @Fork(jvmArgsAppend = {"-XX:+UseSerialGC"})
92 public void benchStoreNNoAllocSerial() {
93 this.arr1[SMALL_IDX] = O1;
94 this.arr1[BIG_IDX] = O2;
95 this.arr2[SMALL_IDX] = O1;
96 this.arr2[BIG_IDX] = O2;
97 }
98
99 @Benchmark
100 @Fork(jvmArgsAppend = {"-XX:+UseParallelGC"})
101 public void benchStoreNNoAllocParallel() {
102 this.arr1[SMALL_IDX] = O1;
103 this.arr1[BIG_IDX] = O2;
104 this.arr2[SMALL_IDX] = O1;
105 this.arr2[BIG_IDX] = O2;
106 }
107
108 @Benchmark
109 public boolean benchStringEquals() {
110 return this.strEqHelper.doEquals("bar");
111 }
112 }