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.array.read;
24
25 import java.util.concurrent.TimeUnit;
26 import jdk.internal.value.ValueClass;
27 import org.openjdk.jmh.annotations.*;
28
29 @BenchmarkMode(Mode.AverageTime)
30 @OutputTimeUnit(TimeUnit.NANOSECONDS)
31 @State(Scope.Thread)
32 @Warmup(iterations = 5, time = 1)
33 @Measurement(iterations = 5, time = 1)
34 @Fork(3)
35 public class HoistArrayChecks {
36 private static final int SIZE = 1_000_000;
37
38 value record Point(byte x, byte y) {
39 static final Point DEFAULT = new Point((byte) 0, (byte) 0);
40 }
41
42 Point[] nonAtomicFlatArray = (Point[]) ValueClass.newNullRestrictedNonAtomicArray(Point.class, SIZE, Point.DEFAULT);
43 Point[] atomicFlatArray = (Point[]) ValueClass.newNullRestrictedAtomicArray(Point.class, SIZE, Point.DEFAULT);
44 Point[] nullableFlatArray = (Point[]) ValueClass.newNullableAtomicArray(Point.class, SIZE);
45
46 @Setup
47 public void setup() {
48 for (int i = 0; i < SIZE; i++) {
49 nullableFlatArray[i] = Point.DEFAULT;
50 }
51 }
52
53 @Benchmark
54 public int nonAtomicNaive() {
55 int sum = 0;
56 for (int i = 0; i < SIZE; i++) {
57 Point p = nonAtomicFlatArray[i];
58 sum += p.x + p.y;
59 }
60 return sum;
61 }
62
63 @Benchmark
64 public int nonAtomicHoisted() {
65 Point[] array = nonAtomicFlatArray;
66 int sum = 0;
67 for (int i = 0; i < SIZE; i++) {
68 Point p = array[i];
69 sum += p.x + p.y;
70 }
71 return sum;
72 }
73
74 @Benchmark
75 public int atomicNaive() {
76 int sum = 0;
77 for (int i = 0; i < SIZE; i++) {
78 Point p = atomicFlatArray[i];
79 sum += p.x + p.y;
80 }
81 return sum;
82 }
83
84 @Benchmark
85 public int atomicHoisted() {
86 Point[] array = atomicFlatArray;
87 int sum = 0;
88 for (int i = 0; i < SIZE; i++) {
89 Point p = array[i];
90 sum += p.x + p.y;
91 }
92 return sum;
93 }
94
95 @Benchmark
96 public int nullableNaive() {
97 int sum = 0;
98 for (int i = 0; i < SIZE; i++) {
99 Point p = nullableFlatArray[i];
100 sum += p.x + p.y;
101 }
102 return sum;
103 }
104
105 @Benchmark
106 public int nullableHoisted() {
107 Point[] array = nullableFlatArray;
108 int sum = 0;
109 for (int i = 0; i < SIZE; i++) {
110 Point p = array[i];
111 sum += p.x + p.y;
112 }
113 return sum;
114 }
115 }