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 }