1 /*
  2  * Copyright (c) 2020, 2024, 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;
 24 
 25 import org.openjdk.jmh.annotations.Benchmark;
 26 import org.openjdk.jmh.annotations.BenchmarkMode;
 27 import org.openjdk.jmh.annotations.CompilerControl;
 28 import org.openjdk.jmh.annotations.Fork;
 29 import org.openjdk.jmh.annotations.Measurement;
 30 import org.openjdk.jmh.annotations.Mode;
 31 import org.openjdk.jmh.annotations.OperationsPerInvocation;
 32 import org.openjdk.jmh.annotations.OutputTimeUnit;
 33 import org.openjdk.jmh.annotations.Scope;
 34 import org.openjdk.jmh.annotations.Setup;
 35 import org.openjdk.jmh.annotations.State;
 36 import org.openjdk.jmh.annotations.Warmup;
 37 
 38 import java.util.concurrent.TimeUnit;
 39 
 40 @Fork(3)
 41 @Warmup(iterations = 5, time = 1)
 42 @Measurement(iterations = 5, time = 1)
 43 @OutputTimeUnit(TimeUnit.NANOSECONDS)
 44 @BenchmarkMode(Mode.AverageTime)
 45 @State(Scope.Thread)
 46 public class InlineArrayHashImplicit {
 47 
 48     public static final int SIZE = 128;
 49 
 50     public static value class Val1  {
 51         public final int f0;
 52         public Val1(int f0) {
 53             this.f0 = f0;
 54         }
 55     }
 56 
 57     public static value class Val2  {
 58         public final int f0;
 59         public Val2(int f0) {
 60             this.f0 = f0;
 61         }
 62     }
 63 
 64     public static value class Val3  {
 65         public final int f0;
 66         public Val3(int f0) {
 67             this.f0 = f0;
 68         }
 69     }
 70 
 71     @State(Scope.Thread)
 72     public static abstract class ObjState {
 73         public Object[] arr;
 74     }
 75 
 76     @State(Scope.Thread)
 77     public static abstract class Ref1State {
 78         public Val1[] arr;
 79     }
 80 
 81     @State(Scope.Thread)
 82     public static abstract class Val1State {
 83         public Val1[] arr;
 84     }
 85 
 86     public static class Val1_as_Val extends Val1State {
 87         @Setup
 88         public void setup() {
 89             arr = new Val1[SIZE];
 90             for (int i = 0; i < arr.length; i++) {
 91                 arr[i] = new Val1(i);
 92             }
 93         }
 94     }
 95 
 96     public static class Val1_as_Ref extends Ref1State {
 97         @Setup
 98         public void setup() {
 99             arr = new Val1[SIZE];
100             for (int i = 0; i < arr.length; i++) {
101                 arr[i] = new Val1(i);
102             }
103         }
104     }
105 
106     public static class Val1_as_Obj extends ObjState {
107         @Setup
108         public void setup() {
109             arr = new Val1[SIZE];
110             for (int i = 0; i < arr.length; i++) {
111                 arr[i] = new Val1(i);
112             }
113         }
114     }
115 
116     public static class Ref1_as_Ref extends Ref1State {
117         @Setup
118         public void setup() {
119             arr = new Val1[SIZE];
120             for (int i = 0; i < arr.length; i++) {
121                 arr[i] = new Val1(i);
122             }
123         }
124     }
125 
126     public static class Ref1_as_Obj extends ObjState {
127         @Setup
128         public void setup() {
129             arr = new Val1[SIZE];
130             for (int i = 0; i < arr.length; i++) {
131                 arr[i] = new Val1(i);
132             }
133         }
134     }
135 
136     public static class Obj1_as_Obj extends ObjState {
137         @Setup
138         public void setup() {
139             arr = new Object[SIZE];
140             for (int i = 0; i < arr.length; i++) {
141                 arr[i] = new Val1(i);
142             }
143         }
144     }
145 
146     public static class Val2_as_Obj extends ObjState {
147         @Setup
148         public void setup() {
149             arr = new Val2[SIZE];
150             for (int i = 0; i < arr.length; i++) {
151                 arr[i] = new Val2(i);
152             }
153         }
154     }
155 
156     public static class Ref2_as_Obj extends ObjState {
157         @Setup
158         public void setup() {
159             arr = new Val2[SIZE];
160             for (int i = 0; i < arr.length; i++) {
161                 arr[i] = new Val2(i);
162             }
163         }
164     }
165 
166     public static class Obj2_as_Obj extends ObjState {
167         @Setup
168         public void setup() {
169             arr = new Object[SIZE];
170             for (int i = 0; i < arr.length; i++) {
171                 arr[i] = new Val2(i);
172             }
173         }
174     }
175 
176     public static class Val3_as_Obj extends ObjState {
177         @Setup
178         public void setup() {
179             arr = new Val3[SIZE];
180             for (int i = 0; i < arr.length; i++) {
181                 arr[i] = new Val3(i);
182             }
183         }
184     }
185 
186     public static class Ref3_as_Obj extends ObjState {
187         @Setup
188         public void setup() {
189             arr = new Val3[SIZE];
190             for (int i = 0; i < arr.length; i++) {
191                 arr[i] = new Val3(i);
192             }
193         }
194     }
195 
196     public static class Obj3_as_Obj extends ObjState {
197         @Setup
198         public void setup() {
199             arr = new Object[SIZE];
200             for (int i = 0; i < arr.length; i++) {
201                 arr[i] = new Val3(i);
202             }
203         }
204     }
205 
206 
207     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
208     public int reduceObj(Object[] arr) {
209         int r = 0;
210         for (int i = 0; i < arr.length; i++) {
211             r += arr[i].hashCode();
212         }
213         return r;
214     }
215 
216     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
217     public int reduceRef(Val1[] arr) {
218         int r = 0;
219         for (int i = 0; i < arr.length; i++) {
220             r += arr[i].hashCode();
221         }
222         return r;
223     }
224 
225     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
226     public int reduceVal(Val1[] arr) {
227         int r = 0;
228         for (int i = 0; i < arr.length; i++) {
229             r += arr[i].hashCode();
230         }
231         return r;
232     }
233 
234     @Benchmark
235     @OperationsPerInvocation(SIZE * 6)
236     @CompilerControl(CompilerControl.Mode.INLINE)
237     public int target1_Val_v(Val1_as_Val st0, Val1_as_Val st1, Val1_as_Val st2, Val1_as_Val st3, Val1_as_Val st4, Val1_as_Val st5) {
238         return reduceVal(st0.arr) +
239                reduceVal(st1.arr) +
240                reduceVal(st2.arr) +
241                reduceVal(st3.arr) +
242                reduceVal(st4.arr) +
243                reduceVal(st5.arr);
244     }
245 
246     @Benchmark
247     @OperationsPerInvocation(SIZE * 6)
248     @CompilerControl(CompilerControl.Mode.INLINE)
249     public int target1_Ref_v(Val1_as_Ref st0, Val1_as_Ref st1, Val1_as_Ref st2, Val1_as_Ref st3, Val1_as_Ref st4, Val1_as_Ref st5) {
250         return reduceRef(st0.arr) +
251                reduceRef(st1.arr) +
252                reduceRef(st2.arr) +
253                reduceRef(st3.arr) +
254                reduceRef(st4.arr) +
255                reduceRef(st5.arr);
256     }
257 
258     @Benchmark
259     @OperationsPerInvocation(SIZE * 6)
260     @CompilerControl(CompilerControl.Mode.INLINE)
261     public int target1_Ref_r(Ref1_as_Ref st0, Ref1_as_Ref st1, Ref1_as_Ref st2, Ref1_as_Ref st3, Ref1_as_Ref st4, Ref1_as_Ref st5) {
262         return reduceRef(st0.arr) +
263                reduceRef(st1.arr) +
264                reduceRef(st2.arr) +
265                reduceRef(st3.arr) +
266                reduceRef(st4.arr) +
267                reduceRef(st5.arr);
268     }
269 
270     @Benchmark
271     @OperationsPerInvocation(SIZE * 6)
272     @CompilerControl(CompilerControl.Mode.INLINE)
273     public int target1_Ref_vr(Val1_as_Ref st0, Ref1_as_Ref st1, Val1_as_Ref st2, Ref1_as_Ref st3, Val1_as_Ref st4, Ref1_as_Ref st5) {
274         return reduceRef(st0.arr) +
275                reduceRef(st1.arr) +
276                reduceRef(st2.arr) +
277                reduceRef(st3.arr) +
278                reduceRef(st4.arr) +
279                reduceRef(st5.arr);
280     }
281 
282     @Benchmark
283     @OperationsPerInvocation(SIZE * 6)
284     @CompilerControl(CompilerControl.Mode.INLINE)
285     public int target1_Obj_v(Val1_as_Obj st0, Val1_as_Obj st1, Val1_as_Obj st2, Val1_as_Obj st3, Val1_as_Obj st4, Val1_as_Obj st5) {
286         return reduceObj(st0.arr) +
287                reduceObj(st1.arr) +
288                reduceObj(st2.arr) +
289                reduceObj(st3.arr) +
290                reduceObj(st4.arr) +
291                reduceObj(st5.arr);
292     }
293 
294     @Benchmark
295     @OperationsPerInvocation(SIZE * 6)
296     @CompilerControl(CompilerControl.Mode.INLINE)
297     public int target1_Obj_r(Ref1_as_Obj st0, Ref1_as_Obj st1, Ref1_as_Obj st2, Ref1_as_Obj st3, Ref1_as_Obj st4, Ref1_as_Obj st5) {
298         return reduceObj(st0.arr) +
299                reduceObj(st1.arr) +
300                reduceObj(st2.arr) +
301                reduceObj(st3.arr) +
302                reduceObj(st4.arr) +
303                reduceObj(st5.arr);
304     }
305 
306     @Benchmark
307     @OperationsPerInvocation(SIZE * 6)
308     @CompilerControl(CompilerControl.Mode.INLINE)
309     public int target1_Obj_o(Obj1_as_Obj st0, Obj1_as_Obj st1, Obj1_as_Obj st2, Obj1_as_Obj st3, Obj1_as_Obj st4, Obj1_as_Obj st5) {
310         return reduceObj(st0.arr) +
311                reduceObj(st1.arr) +
312                reduceObj(st2.arr) +
313                reduceObj(st3.arr) +
314                reduceObj(st4.arr) +
315                reduceObj(st5.arr);
316     }
317 
318     @Benchmark
319     @OperationsPerInvocation(SIZE * 6)
320     @CompilerControl(CompilerControl.Mode.INLINE)
321     public int target1_Obj_vr(Val1_as_Obj st0, Ref1_as_Obj st1, Val1_as_Obj st2, Ref1_as_Obj st3, Val1_as_Obj st4, Ref1_as_Obj st5) {
322         return reduceObj(st0.arr) +
323                 reduceObj(st1.arr) +
324                 reduceObj(st2.arr) +
325                 reduceObj(st3.arr) +
326                 reduceObj(st4.arr) +
327                 reduceObj(st5.arr);
328     }
329 
330     @Benchmark
331     @OperationsPerInvocation(SIZE * 6)
332     @CompilerControl(CompilerControl.Mode.INLINE)
333     public int target1_Obj_vo(Val1_as_Obj st0, Obj1_as_Obj st1, Val1_as_Obj st2, Obj1_as_Obj st3, Val1_as_Obj st4, Obj1_as_Obj st5) {
334         return reduceObj(st0.arr) +
335                 reduceObj(st1.arr) +
336                 reduceObj(st2.arr) +
337                 reduceObj(st3.arr) +
338                 reduceObj(st4.arr) +
339                 reduceObj(st5.arr);
340     }
341 
342     @Benchmark
343     @OperationsPerInvocation(SIZE * 6)
344     @CompilerControl(CompilerControl.Mode.INLINE)
345     public int target1_Obj_ro(Ref1_as_Obj st0, Obj1_as_Obj st1, Ref1_as_Obj st2, Obj1_as_Obj st3, Ref1_as_Obj st4, Obj1_as_Obj st5) {
346         return reduceObj(st0.arr) +
347                 reduceObj(st1.arr) +
348                 reduceObj(st2.arr) +
349                 reduceObj(st3.arr) +
350                 reduceObj(st4.arr) +
351                 reduceObj(st5.arr);
352     }
353 
354     @Benchmark
355     @OperationsPerInvocation(SIZE * 6)
356     @CompilerControl(CompilerControl.Mode.INLINE)
357     public int target1_Obj_vro(Val1_as_Obj st0, Ref1_as_Obj st1, Obj1_as_Obj st2, Val1_as_Obj st3, Ref1_as_Obj st4, Obj1_as_Obj st5) {
358         return reduceObj(st0.arr) +
359                 reduceObj(st1.arr) +
360                 reduceObj(st2.arr) +
361                 reduceObj(st3.arr) +
362                 reduceObj(st4.arr) +
363                 reduceObj(st5.arr);
364     }
365 
366     @Benchmark
367     @OperationsPerInvocation(SIZE * 6)
368     @CompilerControl(CompilerControl.Mode.INLINE)
369     public int target2_Obj_v(Val1_as_Obj st0, Val2_as_Obj st1, Val1_as_Obj st2, Val2_as_Obj st3, Val1_as_Obj st4, Val2_as_Obj st5) {
370         return reduceObj(st0.arr) +
371                 reduceObj(st1.arr) +
372                 reduceObj(st2.arr) +
373                 reduceObj(st3.arr) +
374                 reduceObj(st4.arr) +
375                 reduceObj(st5.arr);
376     }
377 
378     @Benchmark
379     @OperationsPerInvocation(SIZE * 6)
380     @CompilerControl(CompilerControl.Mode.INLINE)
381     public int target2_Obj_r(Ref1_as_Obj st0, Ref2_as_Obj st1, Ref1_as_Obj st2, Ref2_as_Obj st3, Ref1_as_Obj st4, Ref2_as_Obj st5) {
382         return reduceObj(st0.arr) +
383                 reduceObj(st1.arr) +
384                 reduceObj(st2.arr) +
385                 reduceObj(st3.arr) +
386                 reduceObj(st4.arr) +
387                 reduceObj(st5.arr);
388     }
389 
390     @Benchmark
391     @OperationsPerInvocation(SIZE * 6)
392     @CompilerControl(CompilerControl.Mode.INLINE)
393     public int target2_Obj_o(Obj1_as_Obj st0, Obj2_as_Obj st1, Obj1_as_Obj st2, Obj2_as_Obj st3, Obj1_as_Obj st4, Obj2_as_Obj st5) {
394         return reduceObj(st0.arr) +
395                 reduceObj(st1.arr) +
396                 reduceObj(st2.arr) +
397                 reduceObj(st3.arr) +
398                 reduceObj(st4.arr) +
399                 reduceObj(st5.arr);
400     }
401 
402     @Benchmark
403     @OperationsPerInvocation(SIZE * 6)
404     @CompilerControl(CompilerControl.Mode.INLINE)
405     public int target2_Obj_vr(Val1_as_Obj st0, Ref2_as_Obj st1, Val2_as_Obj st2, Ref1_as_Obj st3, Val1_as_Obj st4, Ref2_as_Obj st5) {
406         return reduceObj(st0.arr) +
407                 reduceObj(st1.arr) +
408                 reduceObj(st2.arr) +
409                 reduceObj(st3.arr) +
410                 reduceObj(st4.arr) +
411                 reduceObj(st5.arr);
412     }
413 
414     @Benchmark
415     @OperationsPerInvocation(SIZE * 6)
416     @CompilerControl(CompilerControl.Mode.INLINE)
417     public int target2_Obj_vo(Val1_as_Obj st0, Obj2_as_Obj st1, Val2_as_Obj st2, Obj1_as_Obj st3, Val1_as_Obj st4, Obj2_as_Obj st5) {
418         return reduceObj(st0.arr) +
419                 reduceObj(st1.arr) +
420                 reduceObj(st2.arr) +
421                 reduceObj(st3.arr) +
422                 reduceObj(st4.arr) +
423                 reduceObj(st5.arr);
424     }
425 
426     @Benchmark
427     @OperationsPerInvocation(SIZE * 6)
428     @CompilerControl(CompilerControl.Mode.INLINE)
429     public int target2_Obj_ro(Ref1_as_Obj st0, Obj1_as_Obj st1, Ref2_as_Obj st2, Obj1_as_Obj st3, Ref1_as_Obj st4, Obj2_as_Obj st5) {
430         return reduceObj(st0.arr) +
431                 reduceObj(st1.arr) +
432                 reduceObj(st2.arr) +
433                 reduceObj(st3.arr) +
434                 reduceObj(st4.arr) +
435                 reduceObj(st5.arr);
436     }
437 
438     @Benchmark
439     @OperationsPerInvocation(SIZE * 6)
440     @CompilerControl(CompilerControl.Mode.INLINE)
441     public int target2_Obj_vro(Val1_as_Obj st0, Ref1_as_Obj st1, Obj1_as_Obj st2, Val2_as_Obj st3, Ref2_as_Obj st4, Obj2_as_Obj st5) {
442         return reduceObj(st0.arr) +
443                 reduceObj(st1.arr) +
444                 reduceObj(st2.arr) +
445                 reduceObj(st3.arr) +
446                 reduceObj(st4.arr) +
447                 reduceObj(st5.arr);
448     }
449 
450 
451     @Benchmark
452     @OperationsPerInvocation(SIZE * 6)
453     @CompilerControl(CompilerControl.Mode.INLINE)
454     public int target3_Obj_v(Val1_as_Obj st0, Val2_as_Obj st1, Val3_as_Obj st2, Val1_as_Obj st3, Val2_as_Obj st4, Val3_as_Obj st5) {
455         return reduceObj(st0.arr) +
456                 reduceObj(st1.arr) +
457                 reduceObj(st2.arr) +
458                 reduceObj(st3.arr) +
459                 reduceObj(st4.arr) +
460                 reduceObj(st5.arr);
461     }
462 
463     @Benchmark
464     @OperationsPerInvocation(SIZE * 6)
465     @CompilerControl(CompilerControl.Mode.INLINE)
466     public int target3_Obj_r(Ref1_as_Obj st0, Ref2_as_Obj st1, Ref3_as_Obj st2, Ref1_as_Obj st3, Ref2_as_Obj st4, Ref3_as_Obj st5) {
467         return reduceObj(st0.arr) +
468                 reduceObj(st1.arr) +
469                 reduceObj(st2.arr) +
470                 reduceObj(st3.arr) +
471                 reduceObj(st4.arr) +
472                 reduceObj(st5.arr);
473     }
474 
475     @Benchmark
476     @OperationsPerInvocation(SIZE * 6)
477     @CompilerControl(CompilerControl.Mode.INLINE)
478     public int target3_Obj_o(Obj1_as_Obj st0, Obj2_as_Obj st1, Obj3_as_Obj st2, Obj1_as_Obj st3, Obj2_as_Obj st4, Obj3_as_Obj st5) {
479         return reduceObj(st0.arr) +
480                 reduceObj(st1.arr) +
481                 reduceObj(st2.arr) +
482                 reduceObj(st3.arr) +
483                 reduceObj(st4.arr) +
484                 reduceObj(st5.arr);
485     }
486 
487     @Benchmark
488     @OperationsPerInvocation(SIZE * 6)
489     @CompilerControl(CompilerControl.Mode.INLINE)
490     public int target3_Obj_vr(Val1_as_Obj st0, Ref2_as_Obj st1, Val3_as_Obj st2, Ref1_as_Obj st3, Val2_as_Obj st4, Ref3_as_Obj st5) {
491         return reduceObj(st0.arr) +
492                 reduceObj(st1.arr) +
493                 reduceObj(st2.arr) +
494                 reduceObj(st3.arr) +
495                 reduceObj(st4.arr) +
496                 reduceObj(st5.arr);
497     }
498 
499     @Benchmark
500     @OperationsPerInvocation(SIZE * 6)
501     @CompilerControl(CompilerControl.Mode.INLINE)
502     public int target3_Obj_vo(Val1_as_Obj st0, Obj2_as_Obj st1, Val3_as_Obj st2, Obj1_as_Obj st3, Val3_as_Obj st4, Obj3_as_Obj st5) {
503         return reduceObj(st0.arr) +
504                 reduceObj(st1.arr) +
505                 reduceObj(st2.arr) +
506                 reduceObj(st3.arr) +
507                 reduceObj(st4.arr) +
508                 reduceObj(st5.arr);
509     }
510 
511     @Benchmark
512     @OperationsPerInvocation(SIZE * 6)
513     @CompilerControl(CompilerControl.Mode.INLINE)
514     public int target3_Obj_ro(Ref1_as_Obj st0, Obj2_as_Obj st1, Ref3_as_Obj st2, Obj1_as_Obj st3, Ref2_as_Obj st4, Obj3_as_Obj st5) {
515         return reduceObj(st0.arr) +
516                 reduceObj(st1.arr) +
517                 reduceObj(st2.arr) +
518                 reduceObj(st3.arr) +
519                 reduceObj(st4.arr) +
520                 reduceObj(st5.arr);
521     }
522 
523     @Benchmark
524     @OperationsPerInvocation(SIZE * 6)
525     @CompilerControl(CompilerControl.Mode.INLINE)
526     public int target3_Obj_vro(Val1_as_Obj st0, Ref2_as_Obj st1, Obj3_as_Obj st2, Val2_as_Obj st3, Ref3_as_Obj st4, Obj1_as_Obj st5) {
527         return reduceObj(st0.arr) +
528                 reduceObj(st1.arr) +
529                 reduceObj(st2.arr) +
530                 reduceObj(st3.arr) +
531                 reduceObj(st4.arr) +
532                 reduceObj(st5.arr);
533     }
534 
535 }