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 }