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