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.callconv;
 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 PrimitiveInt {
 47 
 48     public static final int SIZE = 96;  // must be divisible by 2 and 3 and around 100
 49 
 50     public abstract static class InvocationLogic {
 51         public abstract int compute(int v1);
 52         public abstract int compute(int v1, int v2);
 53         public abstract int compute(int v1, int v2, int v3, int v4);
 54         public abstract int compute(int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8);
 55     }
 56 
 57     public static class InvokeImpl1 extends InvocationLogic {
 58 
 59         @Override
 60         public int compute(int v1) {
 61             return v1;
 62         }
 63 
 64         @Override
 65         public int compute(int v1, int v2) {
 66             return v1;
 67         }
 68 
 69         @Override
 70         public int compute(int v1, int v2, int v3, int v4) {
 71             return v1;
 72         }
 73 
 74         @Override
 75         public int compute(int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8) {
 76             return v1;
 77         }
 78 
 79     }
 80 
 81     public static class InvokeImpl2 extends InvocationLogic {
 82 
 83         @Override
 84         public int compute(int v1) {
 85             return v1;
 86         }
 87 
 88         @Override
 89         public int compute(int v1, int v2) {
 90             return v1;
 91         }
 92 
 93         @Override
 94         public int compute(int v1, int v2, int v3, int v4) {
 95             return v1;
 96         }
 97 
 98         @Override
 99         public int compute(int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8) {
100             return v1;
101         }
102     }
103 
104     public static class InvokeImpl3 extends InvocationLogic {
105 
106         @Override
107         public int compute(int v1) {
108             return v1;
109         }
110 
111         @Override
112         public int compute(int v1, int v2) {
113             return v1;
114         }
115 
116         @Override
117         public int compute(int v1, int v2, int v3, int v4) {
118             return v1;
119         }
120 
121         @Override
122         public int compute(int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8) {
123             return v1;
124         }
125     }
126 
127     private static InvocationLogic getImpl(int i, int targets) {
128         switch (i % targets) {
129             case 0:
130                 return new InvokeImpl1();
131             case 1:
132                 return new InvokeImpl2();
133             case 2:
134                 return new InvokeImpl3();
135         }
136         return null;
137     }
138 
139     @State(Scope.Thread)
140     public static class StateTargets0 {
141         InvokeImpl1[] arr;
142         @Setup
143         public void setup() {
144             arr = new InvokeImpl1[SIZE];
145             for(int i=0; i < arr.length; i++) {
146                 arr[i] = new InvokeImpl1();
147             }
148         }
149     }
150 
151     @State(Scope.Thread)
152     public static abstract class StateTargets {
153         InvocationLogic[] arr;
154 
155         public void init(int targets) {
156             arr = new InvocationLogic[SIZE];
157             for(int i=0; i < arr.length; i++) {
158                 arr[i] = getImpl(i, targets);
159             }
160         }
161     }
162 
163     public static class StateTargets1 extends StateTargets {
164         @Setup
165         public void setup() {
166             init(1);
167         }
168     }
169 
170     public static class StateTargets2 extends StateTargets {
171         @Setup
172         public void setup() {
173             init(2);
174         }
175     }
176 
177     public static class StateTargets3 extends StateTargets {
178         @Setup
179         public void setup() {
180             init(3);
181         }
182     }
183 
184     int a0 = 42;
185     int a1 = 43;
186     int a2 = 44;
187     int a3 = 45;
188     int a4 = 46;
189     int a5 = 47;
190     int a6 = 48;
191     int a7 = 49;
192 
193     @CompilerControl(CompilerControl.Mode.INLINE)
194     public int args1(InvocationLogic[] logic) {
195         int r = 0;
196         for(InvocationLogic t : logic) {
197             r += t.compute(a0);
198         }
199         return r;
200     }
201 
202     @CompilerControl(CompilerControl.Mode.INLINE)
203     public int args2(InvocationLogic[] logic) {
204         int r = 0;
205         for(InvocationLogic t : logic) {
206             r += t.compute(a0, a1);
207         }
208         return r;
209     }
210 
211     @CompilerControl(CompilerControl.Mode.INLINE)
212     public int args4(InvocationLogic[] logic) {
213         int r = 0;
214         for(InvocationLogic t : logic) {
215             r += t.compute(a0, a1, a2, a3);
216         }
217         return r;
218     }
219 
220     @CompilerControl(CompilerControl.Mode.INLINE)
221     public int args8(InvocationLogic[] logic) {
222         int r = 0;
223         for(InvocationLogic t : logic) {
224             r += t.compute(a0, a1, a2, a3, a4, a5, a6, a7);
225         }
226         return r;
227     }
228 
229     @Benchmark
230     @OperationsPerInvocation(SIZE)
231     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
232     public int int_args1_targets0(StateTargets0 st) {
233         InvokeImpl1[] arr = st.arr;
234         int r = 0;
235         for(InvocationLogic t : arr) {
236             r += t.compute(a0);
237         }
238         return r;
239     }
240 
241     @Benchmark
242     @OperationsPerInvocation(SIZE)
243     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
244     public int int_args2_targets0(StateTargets0 st) {
245         InvokeImpl1[] arr = st.arr;
246         int r = 0;
247         for(InvocationLogic t : arr) {
248             r += t.compute(a0, a1);
249         }
250         return r;
251     }
252 
253     @Benchmark
254     @OperationsPerInvocation(SIZE)
255     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
256     public int int_args4_targets0(StateTargets0 st) {
257         InvokeImpl1[] arr = st.arr;
258         int r = 0;
259         for(InvocationLogic t : arr) {
260             r += t.compute(a0, a1, a2, a3);
261         }
262         return r;
263     }
264 
265     @Benchmark
266     @OperationsPerInvocation(SIZE)
267     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
268     public int int_args8_targets0(StateTargets0 st) {
269         InvokeImpl1[] arr = st.arr;
270         int r = 0;
271         for(InvocationLogic t : arr) {
272             r += t.compute(a0, a1, a2, a3, a4, a5, a6, a7);
273         }
274         return r;
275     }
276 
277     @Benchmark
278     @OperationsPerInvocation(SIZE)
279     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
280     public int int_args1_targets1(StateTargets1 st) {
281         return args1(st.arr);
282     }
283 
284     @Benchmark
285     @OperationsPerInvocation(SIZE)
286     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
287     public int int_args2_targets1(StateTargets1 st) {
288         return args2(st.arr);
289     }
290 
291     @Benchmark
292     @OperationsPerInvocation(SIZE)
293     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
294     public int int_args4_targets1(StateTargets1 st) {
295         return args4(st.arr);
296     }
297 
298     @Benchmark
299     @OperationsPerInvocation(SIZE)
300     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
301     public int int_args8_targets1(StateTargets1 st) {
302         return args8(st.arr);
303     }
304 
305     @Benchmark
306     @OperationsPerInvocation(SIZE)
307     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
308     public int int_args1_targets2(StateTargets2 st) {
309         return args1(st.arr);
310     }
311 
312     @Benchmark
313     @OperationsPerInvocation(SIZE)
314     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
315     public int int_args2_targets2(StateTargets2 st) {
316         return args2(st.arr);
317     }
318 
319     @Benchmark
320     @OperationsPerInvocation(SIZE)
321     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
322     public int int_args4_targets2(StateTargets2 st) {
323         return args4(st.arr);
324     }
325 
326     @Benchmark
327     @OperationsPerInvocation(SIZE)
328     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
329     public int int_args8_targets2(StateTargets2 st) {
330         return args8(st.arr);
331     }
332 
333     @Benchmark
334     @OperationsPerInvocation(SIZE)
335     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
336     public int int_args1_targets3(StateTargets3 st) {
337         return args1(st.arr);
338     }
339 
340     @Benchmark
341     @OperationsPerInvocation(SIZE)
342     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
343     public int int_args2_targets3(StateTargets3 st) {
344         return args2(st.arr);
345     }
346 
347     @Benchmark
348     @OperationsPerInvocation(SIZE)
349     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
350     public int int_args4_targets3(StateTargets3 st) {
351         return args4(st.arr);
352     }
353 
354     @Benchmark
355     @OperationsPerInvocation(SIZE)
356     @CompilerControl(CompilerControl.Mode.DONT_INLINE)
357     public int int_args8_targets3(StateTargets3 st) {
358         return args8(st.arr);
359     }
360 
361 
362 }