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.valhalla.invoke.field; 24 25 import jdk.internal.vm.annotation.LooselyConsistentValue; 26 import jdk.internal.vm.annotation.NullRestricted; 27 import jdk.internal.vm.annotation.Strict; 28 import org.openjdk.jmh.annotations.Benchmark; 29 import org.openjdk.jmh.annotations.BenchmarkMode; 30 import org.openjdk.jmh.annotations.CompilerControl; 31 import org.openjdk.jmh.annotations.Fork; 32 import org.openjdk.jmh.annotations.Measurement; 33 import org.openjdk.jmh.annotations.Mode; 34 import org.openjdk.jmh.annotations.OperationsPerInvocation; 35 import org.openjdk.jmh.annotations.OutputTimeUnit; 36 import org.openjdk.jmh.annotations.Scope; 37 import org.openjdk.jmh.annotations.Setup; 38 import org.openjdk.jmh.annotations.State; 39 import org.openjdk.jmh.annotations.Warmup; 40 41 import java.util.concurrent.TimeUnit; 42 43 @Fork(value = 3, jvmArgsAppend = {"--enable-preview"}) 44 @Warmup(iterations = 5, time = 1) 45 @Measurement(iterations = 5, time = 1) 46 @OutputTimeUnit(TimeUnit.NANOSECONDS) 47 @BenchmarkMode(Mode.AverageTime) 48 @State(Scope.Thread) 49 public class ValueNullFreeNonAtomic { 50 51 /* 52 virtual method invocations: 53 target0 - statically known target method. 54 target1 - the single invoked method (should be inlined) 55 target2 - two invoked method (should be inlined, cache-inline) 56 target3 - thee invoked method (shouldn't be inlined) 57 58 */ 59 60 61 public static final int SIZE = 128; 62 63 public interface InterfaceInt { 64 public int value(); 65 } 66 67 @LooselyConsistentValue 68 public static value class ValueInt0 implements InterfaceInt { 69 public final int value; 70 public ValueInt0(int value) { 71 this.value = value; 72 } 73 @Override 74 public int value() { 75 return value; 76 } 77 } 78 79 @LooselyConsistentValue 80 public static value class ValueInt1 implements InterfaceInt { 81 public final int value; 82 public ValueInt1(int value) { 83 this.value = value; 84 } 85 @Override 86 public int value() { 87 return value; 88 } 89 } 90 91 @LooselyConsistentValue 92 public static value class ValueInt2 implements InterfaceInt { 93 public final int value; 94 public ValueInt2(int value) { 95 this.value = value; 96 } 97 @Override 98 public int value() { 99 return value; 100 } 101 } 102 103 public static class IntWrapper { 104 final InterfaceInt f; 105 106 public IntWrapper(InterfaceInt f) { 107 this.f = f; 108 } 109 } 110 111 public static class ValWrapper { 112 @Strict 113 @NullRestricted 114 final ValueInt0 f; 115 116 public ValWrapper(ValueInt0 f) { 117 this.f = f; 118 } 119 } 120 121 @State(Scope.Thread) 122 public static class Int0State { 123 public IntWrapper[] arr; 124 @Setup 125 public void setup() { 126 arr = new IntWrapper[SIZE]; 127 for (int i = 0; i < arr.length; i++) { 128 arr[i] = new IntWrapper(new ValueInt0(i)); 129 } 130 } 131 } 132 133 @State(Scope.Thread) 134 public static class Int1State { 135 public IntWrapper[] arr; 136 @Setup 137 public void setup() { 138 arr = new IntWrapper[SIZE]; 139 for (int i = 0; i < arr.length; i++) { 140 arr[i] = new IntWrapper(new ValueInt1(i)); 141 } 142 } 143 } 144 145 @State(Scope.Thread) 146 public static class Int2State { 147 public IntWrapper[] arr; 148 @Setup 149 public void setup() { 150 arr = new IntWrapper[SIZE]; 151 for (int i = 0; i < arr.length; i++) { 152 arr[i] = new IntWrapper(new ValueInt2(i)); 153 } 154 } 155 } 156 157 @State(Scope.Thread) 158 public static class Ref0State { 159 public ValWrapper[] arr; 160 @Setup 161 public void setup() { 162 arr = new ValWrapper[SIZE]; 163 for (int i = 0; i < arr.length; i++) { 164 arr[i] = new ValWrapper(new ValueInt0(i)); 165 } 166 } 167 } 168 169 170 @CompilerControl(CompilerControl.Mode.DONT_INLINE) 171 public int reduce_int(IntWrapper[] arr) { 172 int r = 0; 173 for (int i = 0; i < arr.length; i++) { 174 r += arr[i].f.value(); 175 } 176 return r; 177 } 178 179 @CompilerControl(CompilerControl.Mode.DONT_INLINE) 180 public int reduce_val(ValWrapper[] arr) { 181 int r = 0; 182 for (int i = 0; i < arr.length; i++) { 183 r += arr[i].f.value(); 184 } 185 return r; 186 } 187 188 @Benchmark 189 @OperationsPerInvocation(SIZE * 6) 190 @CompilerControl(CompilerControl.Mode.INLINE) 191 public int target0(Ref0State st0, Ref0State st1, Ref0State st2, Ref0State st3, Ref0State st4, Ref0State st5) { 192 return reduce_val(st0.arr) + 193 reduce_val(st1.arr) + 194 reduce_val(st2.arr) + 195 reduce_val(st3.arr) + 196 reduce_val(st4.arr) + 197 reduce_val(st5.arr); 198 } 199 200 @Benchmark 201 @OperationsPerInvocation(SIZE * 6) 202 @CompilerControl(CompilerControl.Mode.INLINE) 203 public int target1(Int0State st0, Int0State st1, Int0State st2, Int0State st3, Int0State st4, Int0State st5) { 204 return reduce_int(st0.arr) + 205 reduce_int(st1.arr) + 206 reduce_int(st2.arr) + 207 reduce_int(st3.arr) + 208 reduce_int(st4.arr) + 209 reduce_int(st5.arr); 210 } 211 212 @Benchmark 213 @OperationsPerInvocation(SIZE * 6) 214 @CompilerControl(CompilerControl.Mode.INLINE) 215 public int target2(Int0State st0, Int0State st1, Int0State st2, Int1State st3, Int1State st4, Int1State st5) { 216 return reduce_int(st0.arr) + 217 reduce_int(st1.arr) + 218 reduce_int(st2.arr) + 219 reduce_int(st3.arr) + 220 reduce_int(st4.arr) + 221 reduce_int(st5.arr); 222 } 223 224 @Benchmark 225 @OperationsPerInvocation(SIZE * 6) 226 @CompilerControl(CompilerControl.Mode.INLINE) 227 public int target3(Int0State st0, Int0State st1, Int1State st2, Int1State st3, Int2State st4, Int2State st5) { 228 return reduce_int(st0.arr) + 229 reduce_int(st1.arr) + 230 reduce_int(st2.arr) + 231 reduce_int(st3.arr) + 232 reduce_int(st4.arr) + 233 reduce_int(st5.arr); 234 } 235 236 }