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 }