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