1 /*
  2  * Copyright (c) 2020, 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 IdentityArray {
 47 
 48     public static final int SIZE = 128;
 49 
 50     public interface MyInterface {
 51         public int my_method();
 52     }
 53 
 54     public static class Ref1 implements MyInterface {
 55         public final int f0;
 56         public Ref1(int f0) {
 57             this.f0 = f0;
 58         }
 59         @Override
 60         public int my_method() {
 61             return f0;
 62         }
 63     }
 64 
 65     public static class Ref2 implements MyInterface {
 66         public final int f0;
 67         public Ref2(int f0) {
 68             this.f0 = f0;
 69         }
 70         @Override
 71         public int my_method() {
 72             return f0;
 73         }
 74     }
 75 
 76     public static class Ref3 implements MyInterface {
 77         public final int f0;
 78         public Ref3(int f0) {
 79             this.f0 = f0;
 80         }
 81         @Override
 82         public int my_method() {
 83             return f0;
 84         }
 85     }
 86 
 87     @State(Scope.Thread)
 88     public static abstract class IntState {
 89         public MyInterface[] arr;
 90     }
 91 
 92     @State(Scope.Thread)
 93     public static abstract class Ref1State {
 94         public Ref1[] arr;
 95     }
 96 
 97     public static class Ref1_as_Ref extends Ref1State {
 98         @Setup
 99         public void setup() {
100             arr = new Ref1[SIZE];
101             for (int i = 0; i < arr.length; i++) {
102                 arr[i] = new Ref1(i);
103             }
104         }
105     }
106 
107     public static class Ref1_as_Int extends IntState {
108         @Setup
109         public void setup() {
110             arr = new Ref1[SIZE];
111             for (int i = 0; i < arr.length; i++) {
112                 arr[i] = new Ref1(i);
113             }
114         }
115     }
116 
117     public static class Int1_as_Int extends IntState {
118         @Setup
119         public void setup() {
120             arr = new MyInterface[SIZE];
121             for (int i = 0; i < arr.length; i++) {
122                 arr[i] = new Ref1(i);
123             }
124         }
125     }
126 
127     public static class Ref2_as_Int extends IntState {
128         @Setup
129         public void setup() {
130             arr = new Ref2[SIZE];
131             for (int i = 0; i < arr.length; i++) {
132                 arr[i] = new Ref2(i);
133             }
134         }
135     }
136 
137     public static class Int2_as_Int extends IntState {
138         @Setup
139         public void setup() {
140             arr = new MyInterface[SIZE];
141             for (int i = 0; i < arr.length; i++) {
142                 arr[i] = new Ref2(i);
143             }
144         }
145     }
146 
147     public static class Ref3_as_Int extends IntState {
148         @Setup
149         public void setup() {
150             arr = new Ref3[SIZE];
151             for (int i = 0; i < arr.length; i++) {
152                 arr[i] = new Ref3(i);
153             }
154         }
155     }
156 
157     public static class Int3_as_Int extends IntState {
158         @Setup
159         public void setup() {
160             arr = new MyInterface[SIZE];
161             for (int i = 0; i < arr.length; i++) {
162                 arr[i] = new Ref3(i);
163             }
164         }
165     }
166 
167 
168     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
169     public int reduceInt(MyInterface[] arr) {
170         int r = 0;
171         for (int i = 0; i < arr.length; i++) {
172             r += arr[i].my_method();
173         }
174         return r;
175     }
176 
177     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
178     public int reduceRef(Ref1[] arr) {
179         int r = 0;
180         for (int i = 0; i < arr.length; i++) {
181             r += arr[i].my_method();
182         }
183         return r;
184     }
185 
186     @Benchmark
187     @OperationsPerInvocation(SIZE * 6)
188     @CompilerControl(CompilerControl.Mode.INLINE)
189     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) {
190         return reduceRef(st0.arr) +
191                reduceRef(st1.arr) +
192                reduceRef(st2.arr) +
193                reduceRef(st3.arr) +
194                reduceRef(st4.arr) +
195                reduceRef(st5.arr);
196     }
197 
198     @Benchmark
199     @OperationsPerInvocation(SIZE * 6)
200     @CompilerControl(CompilerControl.Mode.INLINE)
201     public int target1_Int_r(Ref1_as_Int st0, Ref1_as_Int st1, Ref1_as_Int st2, Ref1_as_Int st3, Ref1_as_Int st4, Ref1_as_Int st5) {
202         return reduceInt(st0.arr) +
203                reduceInt(st1.arr) +
204                reduceInt(st2.arr) +
205                reduceInt(st3.arr) +
206                reduceInt(st4.arr) +
207                reduceInt(st5.arr);
208     }
209 
210     @Benchmark
211     @OperationsPerInvocation(SIZE * 6)
212     @CompilerControl(CompilerControl.Mode.INLINE)
213     public int target1_Int_i(Int1_as_Int st0, Int1_as_Int st1, Int1_as_Int st2, Int1_as_Int st3, Int1_as_Int st4, Int1_as_Int st5) {
214         return reduceInt(st0.arr) +
215                reduceInt(st1.arr) +
216                reduceInt(st2.arr) +
217                reduceInt(st3.arr) +
218                reduceInt(st4.arr) +
219                reduceInt(st5.arr);
220     }
221 
222     @Benchmark
223     @OperationsPerInvocation(SIZE * 6)
224     @CompilerControl(CompilerControl.Mode.INLINE)
225     public int target1_Int_ri(Ref1_as_Int st0, Int1_as_Int st1, Ref1_as_Int st2, Int1_as_Int st3, Ref1_as_Int st4, Int1_as_Int st5) {
226         return reduceInt(st0.arr) +
227                 reduceInt(st1.arr) +
228                 reduceInt(st2.arr) +
229                 reduceInt(st3.arr) +
230                 reduceInt(st4.arr) +
231                 reduceInt(st5.arr);
232     }
233 
234     @Benchmark
235     @OperationsPerInvocation(SIZE * 6)
236     @CompilerControl(CompilerControl.Mode.INLINE)
237     public int target2_Int_r(Ref1_as_Int st0, Ref2_as_Int st1, Ref1_as_Int st2, Ref2_as_Int st3, Ref1_as_Int st4, Ref2_as_Int st5) {
238         return reduceInt(st0.arr) +
239                 reduceInt(st1.arr) +
240                 reduceInt(st2.arr) +
241                 reduceInt(st3.arr) +
242                 reduceInt(st4.arr) +
243                 reduceInt(st5.arr);
244     }
245 
246     @Benchmark
247     @OperationsPerInvocation(SIZE * 6)
248     @CompilerControl(CompilerControl.Mode.INLINE)
249     public int target2_Int_i(Int1_as_Int st0, Int2_as_Int st1, Int1_as_Int st2, Int2_as_Int st3, Int1_as_Int st4, Int2_as_Int st5) {
250         return reduceInt(st0.arr) +
251                 reduceInt(st1.arr) +
252                 reduceInt(st2.arr) +
253                 reduceInt(st3.arr) +
254                 reduceInt(st4.arr) +
255                 reduceInt(st5.arr);
256     }
257 
258     @Benchmark
259     @OperationsPerInvocation(SIZE * 6)
260     @CompilerControl(CompilerControl.Mode.INLINE)
261     public int target2_Int_ri(Ref1_as_Int st0, Int1_as_Int st1, Ref2_as_Int st2, Int1_as_Int st3, Ref1_as_Int st4, Int2_as_Int st5) {
262         return reduceInt(st0.arr) +
263                 reduceInt(st1.arr) +
264                 reduceInt(st2.arr) +
265                 reduceInt(st3.arr) +
266                 reduceInt(st4.arr) +
267                 reduceInt(st5.arr);
268     }
269 
270     @Benchmark
271     @OperationsPerInvocation(SIZE * 6)
272     @CompilerControl(CompilerControl.Mode.INLINE)
273     public int target3_Int_r(Ref1_as_Int st0, Ref2_as_Int st1, Ref3_as_Int st2, Ref1_as_Int st3, Ref2_as_Int st4, Ref3_as_Int st5) {
274         return reduceInt(st0.arr) +
275                 reduceInt(st1.arr) +
276                 reduceInt(st2.arr) +
277                 reduceInt(st3.arr) +
278                 reduceInt(st4.arr) +
279                 reduceInt(st5.arr);
280     }
281 
282     @Benchmark
283     @OperationsPerInvocation(SIZE * 6)
284     @CompilerControl(CompilerControl.Mode.INLINE)
285     public int target3_Int_i(Int1_as_Int st0, Int2_as_Int st1, Int3_as_Int st2, Int1_as_Int st3, Int2_as_Int st4, Int3_as_Int st5) {
286         return reduceInt(st0.arr) +
287                 reduceInt(st1.arr) +
288                 reduceInt(st2.arr) +
289                 reduceInt(st3.arr) +
290                 reduceInt(st4.arr) +
291                 reduceInt(st5.arr);
292     }
293 
294     @Benchmark
295     @OperationsPerInvocation(SIZE * 6)
296     @CompilerControl(CompilerControl.Mode.INLINE)
297     public int target3_Int_ri(Ref1_as_Int st0, Int2_as_Int st1, Ref3_as_Int st2, Int1_as_Int st3, Ref2_as_Int st4, Int3_as_Int st5) {
298         return reduceInt(st0.arr) +
299                 reduceInt(st1.arr) +
300                 reduceInt(st2.arr) +
301                 reduceInt(st3.arr) +
302                 reduceInt(st4.arr) +
303                 reduceInt(st5.arr);
304     }
305 
306 }