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 InlineArrayHashExplicit {
 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         @Override
 56         public int hashCode() {
 57             return f0;
 58         }
 59     }
 60 
 61     public static value class Val2  {
 62         public final int f0;
 63         public Val2(int f0) {
 64             this.f0 = f0;
 65         }
 66         @Override
 67         public int hashCode() {
 68             return f0;
 69         }
 70     }
 71 
 72     public static value class Val3  {
 73         public final int f0;
 74         public Val3(int f0) {
 75             this.f0 = f0;
 76         }
 77         @Override
 78         public int hashCode() {
 79             return f0;
 80         }
 81     }
 82 
 83     @State(Scope.Thread)
 84     public static abstract class ObjState {
 85         public Object[] arr;
 86     }
 87 
 88     @State(Scope.Thread)
 89     public static abstract class Ref1State {
 90         public Val1[] arr;
 91     }
 92 
 93     @State(Scope.Thread)
 94     public static abstract class Val1State {
 95         public Val1[] arr;
 96     }
 97 
 98     public static class Val1_as_Val extends Val1State {
 99         @Setup
100         public void setup() {
101             arr = new Val1[SIZE];
102             for (int i = 0; i < arr.length; i++) {
103                 arr[i] = new Val1(i);
104             }
105         }
106     }
107 
108     public static class Val1_as_Ref extends Ref1State {
109         @Setup
110         public void setup() {
111             arr = new Val1[SIZE];
112             for (int i = 0; i < arr.length; i++) {
113                 arr[i] = new Val1(i);
114             }
115         }
116     }
117 
118     public static class Val1_as_Obj extends ObjState {
119         @Setup
120         public void setup() {
121             arr = new Val1[SIZE];
122             for (int i = 0; i < arr.length; i++) {
123                 arr[i] = new Val1(i);
124             }
125         }
126     }
127 
128     public static class Ref1_as_Ref extends Ref1State {
129         @Setup
130         public void setup() {
131             arr = new Val1[SIZE];
132             for (int i = 0; i < arr.length; i++) {
133                 arr[i] = new Val1(i);
134             }
135         }
136     }
137 
138     public static class Ref1_as_Obj extends ObjState {
139         @Setup
140         public void setup() {
141             arr = new Val1[SIZE];
142             for (int i = 0; i < arr.length; i++) {
143                 arr[i] = new Val1(i);
144             }
145         }
146     }
147 
148     public static class Obj1_as_Obj extends ObjState {
149         @Setup
150         public void setup() {
151             arr = new Object[SIZE];
152             for (int i = 0; i < arr.length; i++) {
153                 arr[i] = new Val1(i);
154             }
155         }
156     }
157 
158     public static class Val2_as_Obj extends ObjState {
159         @Setup
160         public void setup() {
161             arr = new Val2[SIZE];
162             for (int i = 0; i < arr.length; i++) {
163                 arr[i] = new Val2(i);
164             }
165         }
166     }
167 
168     public static class Ref2_as_Obj extends ObjState {
169         @Setup
170         public void setup() {
171             arr = new Val2[SIZE];
172             for (int i = 0; i < arr.length; i++) {
173                 arr[i] = new Val2(i);
174             }
175         }
176     }
177 
178     public static class Obj2_as_Obj extends ObjState {
179         @Setup
180         public void setup() {
181             arr = new Object[SIZE];
182             for (int i = 0; i < arr.length; i++) {
183                 arr[i] = new Val2(i);
184             }
185         }
186     }
187 
188     public static class Val3_as_Obj extends ObjState {
189         @Setup
190         public void setup() {
191             arr = new Val3[SIZE];
192             for (int i = 0; i < arr.length; i++) {
193                 arr[i] = new Val3(i);
194             }
195         }
196     }
197 
198     public static class Ref3_as_Obj extends ObjState {
199         @Setup
200         public void setup() {
201             arr = new Val3[SIZE];
202             for (int i = 0; i < arr.length; i++) {
203                 arr[i] = new Val3(i);
204             }
205         }
206     }
207 
208     public static class Obj3_as_Obj extends ObjState {
209         @Setup
210         public void setup() {
211             arr = new Object[SIZE];
212             for (int i = 0; i < arr.length; i++) {
213                 arr[i] = new Val3(i);
214             }
215         }
216     }
217 
218 
219     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
220     public int reduceObj(Object[] arr) {
221         int r = 0;
222         for (int i = 0; i < arr.length; i++) {
223             r += arr[i].hashCode();
224         }
225         return r;
226     }
227 
228     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
229     public int reduceRef(Val1[] arr) {
230         int r = 0;
231         for (int i = 0; i < arr.length; i++) {
232             r += arr[i].hashCode();
233         }
234         return r;
235     }
236 
237     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
238     public int reduceVal(Val1[] arr) {
239         int r = 0;
240         for (int i = 0; i < arr.length; i++) {
241             r += arr[i].hashCode();
242         }
243         return r;
244     }
245 
246     @Benchmark
247     @OperationsPerInvocation(SIZE * 6)
248     @CompilerControl(CompilerControl.Mode.INLINE)
249     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) {
250         return reduceVal(st0.arr) +
251                reduceVal(st1.arr) +
252                reduceVal(st2.arr) +
253                reduceVal(st3.arr) +
254                reduceVal(st4.arr) +
255                reduceVal(st5.arr);
256     }
257 
258     @Benchmark
259     @OperationsPerInvocation(SIZE * 6)
260     @CompilerControl(CompilerControl.Mode.INLINE)
261     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) {
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_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) {
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_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) {
286         return reduceRef(st0.arr) +
287                reduceRef(st1.arr) +
288                reduceRef(st2.arr) +
289                reduceRef(st3.arr) +
290                reduceRef(st4.arr) +
291                reduceRef(st5.arr);
292     }
293 
294     @Benchmark
295     @OperationsPerInvocation(SIZE * 6)
296     @CompilerControl(CompilerControl.Mode.INLINE)
297     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) {
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_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) {
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_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) {
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_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) {
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_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) {
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_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) {
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 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) {
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_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) {
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_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) {
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_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) {
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_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) {
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_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) {
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_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) {
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     @Benchmark
451     @OperationsPerInvocation(SIZE * 6)
452     @CompilerControl(CompilerControl.Mode.INLINE)
453     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) {
454         return reduceObj(st0.arr) +
455                 reduceObj(st1.arr) +
456                 reduceObj(st2.arr) +
457                 reduceObj(st3.arr) +
458                 reduceObj(st4.arr) +
459                 reduceObj(st5.arr);
460     }
461 
462 
463     @Benchmark
464     @OperationsPerInvocation(SIZE * 6)
465     @CompilerControl(CompilerControl.Mode.INLINE)
466     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) {
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_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) {
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_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) {
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_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) {
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_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) {
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_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) {
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     @Benchmark
536     @OperationsPerInvocation(SIZE * 6)
537     @CompilerControl(CompilerControl.Mode.INLINE)
538     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) {
539         return reduceObj(st0.arr) +
540                 reduceObj(st1.arr) +
541                 reduceObj(st2.arr) +
542                 reduceObj(st3.arr) +
543                 reduceObj(st4.arr) +
544                 reduceObj(st5.arr);
545     }
546 
547 }