1 /* 2 * Copyright (c) 2019, 2024, 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 24 /** 25 * @test 26 * @key randomness 27 * @summary Test value class calling convention with compiled to compiled calls. 28 * @library /test/lib /compiler/whitebox / 29 * @enablePreview 30 * @build jdk.test.whitebox.WhiteBox 31 * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox 32 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI 33 * TestC2CCalls 34 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI 35 * -XX:-UseBimorphicInlining -Xbatch 36 * -XX:CompileCommand=compileonly,TestC2CCalls*::test* 37 * -XX:CompileCommand=dontinline,TestC2CCalls*::test* 38 * TestC2CCalls 39 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI 40 * -XX:-UseBimorphicInlining -Xbatch -XX:-ProfileInterpreter 41 * -XX:CompileCommand=compileonly,TestC2CCalls*::test* 42 * -XX:CompileCommand=dontinline,TestC2CCalls*::test* 43 * TestC2CCalls 44 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI 45 * -XX:-UseBimorphicInlining -Xbatch 46 * -XX:CompileCommand=compileonly,TestC2CCalls::test* 47 * -XX:CompileCommand=dontinline,TestC2CCalls*::test* 48 * TestC2CCalls 49 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI 50 * -XX:-UseBimorphicInlining -Xbatch -XX:-ProfileInterpreter 51 * -XX:CompileCommand=compileonly,TestC2CCalls::test* 52 * -XX:CompileCommand=dontinline,TestC2CCalls*::test* 53 * TestC2CCalls 54 */ 55 56 import java.lang.reflect.Method; 57 import java.util.ArrayList; 58 import java.util.Collections; 59 60 import jdk.test.lib.Asserts; 61 import jdk.test.lib.Utils; 62 63 import jdk.test.whitebox.WhiteBox; 64 65 public class TestC2CCalls { 66 public static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 67 public static final int COMP_LEVEL_FULL_OPTIMIZATION = 4; // C2 or JVMCI 68 public static final int rI = Utils.getRandomInstance().nextInt() % 1000; 69 70 static value class OtherVal { 71 public int x; 72 73 private OtherVal(int x) { 74 this.x = x; 75 } 76 } 77 78 static interface MyInterface1 { 79 public MyInterface1 test1(OtherVal other, int y); 80 public MyInterface1 test2(OtherVal other1, OtherVal other2, int y); 81 public MyInterface1 test3(OtherVal other1, OtherVal other2, int y, boolean deopt); 82 public MyInterface1 test4(OtherVal other1, OtherVal other2, int y); 83 public MyInterface1 test5(OtherVal other1, OtherVal other2, int y); 84 public MyInterface1 test6(); 85 public MyInterface1 test7(int i1, int i2, int i3, int i4, int i5, int i6); 86 public MyInterface1 test8(int i1, int i2, int i3, int i4, int i5, int i6, int i7); 87 public MyInterface1 test9(MyValue3 other, int i1, int i2, int i3, int i4, int i5, int i6); 88 public MyInterface1 test10(MyValue4 other, int i1, int i2, int i3, int i4, int i5, int i6); 89 90 public int getValue(); 91 } 92 93 static value class MyValue1 implements MyInterface1 { 94 public int x; 95 96 private MyValue1(int x) { 97 this.x = x; 98 } 99 100 @Override 101 public int getValue() { 102 return x; 103 } 104 105 @Override 106 public MyValue1 test1(OtherVal other, int y) { 107 return new MyValue1(x + other.x + y); 108 } 109 110 @Override 111 public MyValue1 test2(OtherVal other1, OtherVal other2, int y) { 112 return new MyValue1(x + other1.x + other2.x + y); 113 } 114 115 @Override 116 public MyValue1 test3(OtherVal other1, OtherVal other2, int y, boolean deopt) { 117 if (!deopt) { 118 return new MyValue1(x + other1.x + other2.x + y); 119 } else { 120 // Uncommon trap 121 return test1(other1, y); 122 } 123 } 124 125 @Override 126 public MyValue1 test4(OtherVal other1, OtherVal other2, int y) { 127 return new MyValue1(x + other1.x + other2.x + y); 128 } 129 130 @Override 131 public MyValue1 test5(OtherVal other1, OtherVal other2, int y) { 132 return new MyValue1(x + other1.x + other2.x + y); 133 } 134 135 @Override 136 public MyValue1 test6() { 137 return this; 138 } 139 140 @Override 141 public MyValue1 test7(int i1, int i2, int i3, int i4, int i5, int i6) { 142 return new MyValue1(x + i1 + i2 + i3 + i4 + i5 + i6); 143 } 144 145 @Override 146 public MyValue1 test8(int i1, int i2, int i3, int i4, int i5, int i6, int i7) { 147 return new MyValue1(x + i1 + i2 + i3 + i4 + i5 + i6 + i7); 148 } 149 150 public MyValue1 test9(MyValue3 other, int i1, int i2, int i3, int i4, int i5, int i6) { 151 return new MyValue1(x + (int)(other.d1 + other.d2 + other.d3 + other.d4) + i1 + i2 + i3 + i4 + i5 + i6); 152 } 153 154 public MyValue1 test10(MyValue4 other, int i1, int i2, int i3, int i4, int i5, int i6) { 155 return new MyValue1(x + other.x1 + other.x2 + other.x3 + other.x4 + i1 + i2 + i3 + i4 + i5 + i6); 156 } 157 } 158 159 static value class MyValue2 implements MyInterface1 { 160 public int x; 161 162 private MyValue2(int x) { 163 this.x = x; 164 } 165 166 @Override 167 public int getValue() { 168 return x; 169 } 170 171 @Override 172 public MyValue2 test1(OtherVal other, int y) { 173 return new MyValue2(x + other.x + y); 174 } 175 176 @Override 177 public MyValue2 test2(OtherVal other1, OtherVal other2, int y) { 178 return new MyValue2(x + other1.x + other2.x + y); 179 } 180 181 @Override 182 public MyValue2 test3(OtherVal other1, OtherVal other2, int y, boolean deopt) { 183 if (!deopt) { 184 return new MyValue2(x + other1.x + other2.x + y); 185 } else { 186 // Uncommon trap 187 return test1(other1, y); 188 } 189 } 190 191 @Override 192 public MyValue2 test4(OtherVal other1, OtherVal other2, int y) { 193 return new MyValue2(x + other1.x + other2.x + y); 194 } 195 196 @Override 197 public MyValue2 test5(OtherVal other1, OtherVal other2, int y) { 198 return new MyValue2(x + other1.x + other2.x + y); 199 } 200 201 @Override 202 public MyValue2 test6() { 203 return this; 204 } 205 206 @Override 207 public MyValue2 test7(int i1, int i2, int i3, int i4, int i5, int i6) { 208 return new MyValue2(x + i1 + i2 + i3 + i4 + i5 + i6); 209 } 210 211 @Override 212 public MyValue2 test8(int i1, int i2, int i3, int i4, int i5, int i6, int i7) { 213 return new MyValue2(x + i1 + i2 + i3 + i4 + i5 + i6 + i7); 214 } 215 216 public MyValue2 test9(MyValue3 other, int i1, int i2, int i3, int i4, int i5, int i6) { 217 return new MyValue2(x + (int)(other.d1 + other.d2 + other.d3 + other.d4) + i1 + i2 + i3 + i4 + i5 + i6); 218 } 219 220 public MyValue2 test10(MyValue4 other, int i1, int i2, int i3, int i4, int i5, int i6) { 221 return new MyValue2(x + other.x1 + other.x2 + other.x3 + other.x4 + i1 + i2 + i3 + i4 + i5 + i6); 222 } 223 } 224 225 static value class MyValue3 implements MyInterface1 { 226 public double d1; 227 public double d2; 228 public double d3; 229 public double d4; 230 231 private MyValue3(double d) { 232 this.d1 = d; 233 this.d2 = d; 234 this.d3 = d; 235 this.d4 = d; 236 } 237 238 @Override 239 public int getValue() { 240 return (int)d4; 241 } 242 243 @Override 244 public MyValue3 test1(OtherVal other, int y) { return new MyValue3(0); } 245 @Override 246 public MyValue3 test2(OtherVal other1, OtherVal other2, int y) { return new MyValue3(0); } 247 @Override 248 public MyValue3 test3(OtherVal other1, OtherVal other2, int y, boolean deopt) { return new MyValue3(0); } 249 @Override 250 public MyValue3 test4(OtherVal other1, OtherVal other2, int y) { return new MyValue3(0); } 251 @Override 252 public MyValue3 test5(OtherVal other1, OtherVal other2, int y) { return new MyValue3(0); } 253 @Override 254 public MyValue3 test6() { return new MyValue3(0); } 255 256 @Override 257 public MyValue3 test7(int i1, int i2, int i3, int i4, int i5, int i6) { 258 return new MyValue3(d1 + d2 + d3 + d4 + i1 + i2 + i3 + i4 + i5 + i6); 259 } 260 261 @Override 262 public MyValue3 test8(int i1, int i2, int i3, int i4, int i5, int i6, int i7) { 263 return new MyValue3(d1 + d2 + d3 + d4 + i1 + i2 + i3 + i4 + i5 + i6 + i7); 264 } 265 266 public MyValue3 test9(MyValue3 other, int i1, int i2, int i3, int i4, int i5, int i6) { 267 return new MyValue3(d1 + d2 + d3 + d4 + other.d1 + other.d2 + other.d3 + other.d4 + i1 + i2 + i3 + i4 + i5 + i6); 268 } 269 270 public MyValue3 test10(MyValue4 other, int i1, int i2, int i3, int i4, int i5, int i6) { 271 return new MyValue3(d1 + d2 + d3 + d4 + other.x1 + other.x2 + other.x3 + other.x4 + i1 + i2 + i3 + i4 + i5 + i6); 272 } 273 } 274 275 static value class MyValue4 implements MyInterface1 { 276 public int x1; 277 public int x2; 278 public int x3; 279 public int x4; 280 281 private MyValue4(int i) { 282 this.x1 = i; 283 this.x2 = i; 284 this.x3 = i; 285 this.x4 = i; 286 } 287 288 @Override 289 public int getValue() { 290 return x4; 291 } 292 293 @Override 294 public MyValue4 test1(OtherVal other, int y) { return new MyValue4(0); } 295 @Override 296 public MyValue4 test2(OtherVal other1, OtherVal other2, int y) { return new MyValue4(0); } 297 @Override 298 public MyValue4 test3(OtherVal other1, OtherVal other2, int y, boolean deopt) { return new MyValue4(0); } 299 @Override 300 public MyValue4 test4(OtherVal other1, OtherVal other2, int y) { return new MyValue4(0); } 301 @Override 302 public MyValue4 test5(OtherVal other1, OtherVal other2, int y) { return new MyValue4(0); } 303 @Override 304 public MyValue4 test6() { return new MyValue4(0); } 305 306 @Override 307 public MyValue4 test7(int i1, int i2, int i3, int i4, int i5, int i6) { 308 return new MyValue4(x1 + x2 + x3 + x4 + i1 + i2 + i3 + i4 + i5 + i6); 309 } 310 311 @Override 312 public MyValue4 test8(int i1, int i2, int i3, int i4, int i5, int i6, int i7) { 313 return new MyValue4(x1 + x2 + x3 + x4 + i1 + i2 + i3 + i4 + i5 + i6 + i7); 314 } 315 316 public MyValue4 test9(MyValue3 other, int i1, int i2, int i3, int i4, int i5, int i6) { 317 return new MyValue4(x1 + x2 + x3 + x4 + (int)(other.d1 + other.d2 + other.d3 + other.d4) + i1 + i2 + i3 + i4 + i5 + i6); 318 } 319 320 public MyValue4 test10(MyValue4 other, int i1, int i2, int i3, int i4, int i5, int i6) { 321 return new MyValue4(x1 + x2 + x3 + x4 + other.x1 + other.x2 + other.x3 + other.x4 + i1 + i2 + i3 + i4 + i5 + i6); 322 } 323 } 324 325 static class MyObject implements MyInterface1 { 326 private final int x; 327 328 private MyObject(int x) { 329 this.x = x; 330 } 331 332 @Override 333 public int getValue() { 334 return x; 335 } 336 337 @Override 338 public MyObject test1(OtherVal other, int y) { 339 return new MyObject(x + other.x + y); 340 } 341 342 @Override 343 public MyObject test2(OtherVal other1, OtherVal other2, int y) { 344 return new MyObject(x + other1.x + other2.x + y); 345 } 346 347 @Override 348 public MyObject test3(OtherVal other1, OtherVal other2, int y, boolean deopt) { 349 if (!deopt) { 350 return new MyObject(x + other1.x + other2.x + y); 351 } else { 352 // Uncommon trap 353 return test1(other1, y); 354 } 355 } 356 357 @Override 358 public MyObject test4(OtherVal other1, OtherVal other2, int y) { 359 return new MyObject(x + other1.x + other2.x + y); 360 } 361 362 @Override 363 public MyObject test5(OtherVal other1, OtherVal other2, int y) { 364 return new MyObject(x + other1.x + other2.x + y); 365 } 366 367 @Override 368 public MyObject test6() { 369 return this; 370 } 371 372 @Override 373 public MyObject test7(int i1, int i2, int i3, int i4, int i5, int i6) { 374 return new MyObject(x + i1 + i2 + i3 + i4 + i5 + i6); 375 } 376 377 @Override 378 public MyObject test8(int i1, int i2, int i3, int i4, int i5, int i6, int i7) { 379 return new MyObject(x + i1 + i2 + i3 + i4 + i5 + i6 + i7); 380 } 381 382 public MyObject test9(MyValue3 other, int i1, int i2, int i3, int i4, int i5, int i6) { 383 return new MyObject(x + (int)(other.d1 + other.d2 + other.d3 + other.d4) + i1 + i2 + i3 + i4 + i5 + i6); 384 } 385 386 public MyObject test10(MyValue4 other, int i1, int i2, int i3, int i4, int i5, int i6) { 387 return new MyObject(x + other.x1 + other.x2 + other.x3 + other.x4 + i1 + i2 + i3 + i4 + i5 + i6); 388 } 389 } 390 391 // Test calling methods with value class arguments through an interface 392 public static int test1(MyInterface1 intf, OtherVal other, int y) { 393 return intf.test1(other, y).getValue(); 394 } 395 396 public static int test2(MyInterface1 intf, OtherVal other, int y) { 397 return intf.test2(other, other, y).getValue(); 398 } 399 400 // Test mixing null-tolerant and null-free value class arguments 401 public static int test3(MyValue1 vt, OtherVal other, int y) { 402 return vt.test2(other, other, y).getValue(); 403 } 404 405 public static int test4(MyObject obj, OtherVal other, int y) { 406 return obj.test2(other, other, y).getValue(); 407 } 408 409 // Optimized interface call with value class receiver 410 public static int test5(MyInterface1 intf, OtherVal other, int y) { 411 return intf.test1(other, y).getValue(); 412 } 413 414 public static int test6(MyInterface1 intf, OtherVal other, int y) { 415 return intf.test2(other, other, y).getValue(); 416 } 417 418 // Optimized interface call with object receiver 419 public static int test7(MyInterface1 intf, OtherVal other, int y) { 420 return intf.test1(other, y).getValue(); 421 } 422 423 public static int test8(MyInterface1 intf, OtherVal other, int y) { 424 return intf.test2(other, other, y).getValue(); 425 } 426 427 // Interface calls with deoptimized callee 428 public static int test9(MyInterface1 intf, OtherVal other, int y, boolean deopt) { 429 return intf.test3(other, other, y, deopt).getValue(); 430 } 431 432 public static int test10(MyInterface1 intf, OtherVal other, int y, boolean deopt) { 433 return intf.test3(other, other, y, deopt).getValue(); 434 } 435 436 // Optimized interface calls with deoptimized callee 437 public static int test11(MyInterface1 intf, OtherVal other, int y, boolean deopt) { 438 return intf.test3(other, other, y, deopt).getValue(); 439 } 440 441 public static int test12(MyInterface1 intf, OtherVal other, int y, boolean deopt) { 442 return intf.test3(other, other, y, deopt).getValue(); 443 } 444 445 public static int test13(MyInterface1 intf, OtherVal other, int y, boolean deopt) { 446 return intf.test3(other, other, y, deopt).getValue(); 447 } 448 449 public static int test14(MyInterface1 intf, OtherVal other, int y, boolean deopt) { 450 return intf.test3(other, other, y, deopt).getValue(); 451 } 452 453 // Interface calls without warmed up / compiled callees 454 public static int test15(MyInterface1 intf, OtherVal other, int y) { 455 return intf.test4(other, other, y).getValue(); 456 } 457 458 public static int test16(MyInterface1 intf, OtherVal other, int y) { 459 return intf.test5(other, other, y).getValue(); 460 } 461 462 // Interface call with no arguments 463 public static int test17(MyInterface1 intf) { 464 return intf.test6().getValue(); 465 } 466 467 // Calls that require stack extension 468 public static int test18(MyInterface1 intf, int y) { 469 return intf.test7(y, y, y, y, y, y).getValue(); 470 } 471 472 public static int test19(MyInterface1 intf, int y) { 473 return intf.test8(y, y, y, y, y, y, y).getValue(); 474 } 475 476 public static int test20(MyInterface1 intf, MyValue3 v, int y) { 477 return intf.test9(v, y, y, y, y, y, y).getValue(); 478 } 479 480 public static int test21(MyInterface1 intf, MyValue4 v, int y) { 481 return intf.test10(v, y, y, y, y, y, y).getValue(); 482 } 483 484 public static void main(String[] args) { 485 // Sometimes, exclude some methods from compilation with C2 to stress test the calling convention 486 if (Utils.getRandomInstance().nextBoolean()) { 487 ArrayList<Method> methods = new ArrayList<Method>(); 488 Collections.addAll(methods, MyValue1.class.getDeclaredMethods()); 489 Collections.addAll(methods, MyValue2.class.getDeclaredMethods()); 490 Collections.addAll(methods, MyValue3.class.getDeclaredMethods()); 491 Collections.addAll(methods, MyValue4.class.getDeclaredMethods()); 492 Collections.addAll(methods, MyObject.class.getDeclaredMethods()); 493 Collections.addAll(methods, TestC2CCalls.class.getDeclaredMethods()); 494 System.out.println("Excluding methods from C2 compilation:"); 495 for (Method m : methods) { 496 if (Utils.getRandomInstance().nextBoolean()) { 497 System.out.println(m); 498 WHITE_BOX.makeMethodNotCompilable(m, COMP_LEVEL_FULL_OPTIMIZATION, false); 499 } 500 } 501 } 502 503 MyValue1 val1 = new MyValue1(rI); 504 MyValue2 val2 = new MyValue2(rI+1); 505 MyValue3 val3 = new MyValue3(rI+2); 506 MyValue4 val4 = new MyValue4(rI+3); 507 OtherVal other = new OtherVal(rI+4); 508 MyObject obj = new MyObject(rI+5); 509 510 // Make sure callee methods are compiled 511 for (int i = 0; i < 10_000; ++i) { 512 Asserts.assertEQ(val1.test1(other, rI).getValue(), val1.x + other.x + rI); 513 Asserts.assertEQ(val2.test1(other, rI).getValue(), val2.x + other.x + rI); 514 Asserts.assertEQ(obj.test1(other, rI).getValue(), obj.x + other.x + rI); 515 Asserts.assertEQ(val1.test2(other, other, rI).getValue(), val1.x + 2*other.x + rI); 516 Asserts.assertEQ(val2.test2(other, other, rI).getValue(), val2.x + 2*other.x + rI); 517 Asserts.assertEQ(obj.test2(other, other, rI).getValue(), obj.x + 2*other.x + rI); 518 Asserts.assertEQ(val1.test3(other, other, rI, false).getValue(), val1.x + 2*other.x + rI); 519 Asserts.assertEQ(val2.test3(other, other, rI, false).getValue(), val2.x + 2*other.x + rI); 520 Asserts.assertEQ(obj.test3(other, other, rI, false).getValue(), obj.x + 2*other.x + rI); 521 Asserts.assertEQ(val1.test7(rI, rI, rI, rI, rI, rI).getValue(), val1.x + 6*rI); 522 Asserts.assertEQ(val2.test7(rI, rI, rI, rI, rI, rI).getValue(), val2.x + 6*rI); 523 Asserts.assertEQ(val3.test7(rI, rI, rI, rI, rI, rI).getValue(), (int)(4*val3.d1 + 6*rI)); 524 Asserts.assertEQ(val4.test7(rI, rI, rI, rI, rI, rI).getValue(), (int)(4*val4.x1 + 6*rI)); 525 Asserts.assertEQ(obj.test7(rI, rI, rI, rI, rI, rI).getValue(), obj.x + 6*rI); 526 Asserts.assertEQ(val1.test8(rI, rI, rI, rI, rI, rI, rI).getValue(), val1.x + 7*rI); 527 Asserts.assertEQ(val2.test8(rI, rI, rI, rI, rI, rI, rI).getValue(), val2.x + 7*rI); 528 Asserts.assertEQ(val3.test8(rI, rI, rI, rI, rI, rI, rI).getValue(), (int)(4*val3.d1 + 7*rI)); 529 Asserts.assertEQ(val4.test8(rI, rI, rI, rI, rI, rI, rI).getValue(), (int)(4*val4.x1 + 7*rI)); 530 Asserts.assertEQ(obj.test8(rI, rI, rI, rI, rI, rI, rI).getValue(), obj.x + 7*rI); 531 Asserts.assertEQ(val1.test9(val3, rI, rI, rI, rI, rI, rI).getValue(), (int)(val1.x + 4*val3.d1 + 6*rI)); 532 Asserts.assertEQ(val2.test9(val3, rI, rI, rI, rI, rI, rI).getValue(), (int)(val2.x + 4*val3.d1 + 6*rI)); 533 Asserts.assertEQ(val3.test9(val3, rI, rI, rI, rI, rI, rI).getValue(), (int)(4*val3.d1 + 4*val3.d1 + 6*rI)); 534 Asserts.assertEQ(val4.test9(val3, rI, rI, rI, rI, rI, rI).getValue(), (int)(4*val4.x1 + 4*val3.d1 + 6*rI)); 535 Asserts.assertEQ(obj.test9(val3, rI, rI, rI, rI, rI, rI).getValue(), (int)(obj.x + 4*val3.d1 + 6*rI)); 536 Asserts.assertEQ(val1.test10(val4, rI, rI, rI, rI, rI, rI).getValue(), (int)(val1.x + 4*val4.x1 + 6*rI)); 537 Asserts.assertEQ(val2.test10(val4, rI, rI, rI, rI, rI, rI).getValue(), (int)(val2.x + 4*val4.x1 + 6*rI)); 538 Asserts.assertEQ(val3.test10(val4, rI, rI, rI, rI, rI, rI).getValue(), (int)(4*val3.d1 + 4*val4.x1 + 6*rI)); 539 Asserts.assertEQ(val4.test10(val4, rI, rI, rI, rI, rI, rI).getValue(), (int)(4*val4.x1 + 4*val4.x1 + 6*rI)); 540 Asserts.assertEQ(obj.test10(val4, rI, rI, rI, rI, rI, rI).getValue(), (int)(obj.x + 4*val4.x1 + 6*rI)); 541 } 542 543 // Polute call profile 544 for (int i = 0; i < 100; ++i) { 545 Asserts.assertEQ(test15(val1, other, rI), val1.x + 2*other.x + rI); 546 Asserts.assertEQ(test16(obj, other, rI), obj.x + 2*other.x + rI); 547 Asserts.assertEQ(test17(obj), obj.x); 548 } 549 550 // Trigger compilation of caller methods 551 for (int i = 0; i < 100_000; ++i) { 552 val1 = new MyValue1(rI+i); 553 val2 = new MyValue2(rI+i+1); 554 val3 = new MyValue3(rI+i+2); 555 val4 = new MyValue4(rI+i+3); 556 other = new OtherVal(rI+i+4); 557 obj = new MyObject(rI+i+5); 558 559 Asserts.assertEQ(test1(val1, other, rI), val1.x + other.x + rI); 560 Asserts.assertEQ(test1(obj, other, rI), obj.x + other.x + rI); 561 Asserts.assertEQ(test2(obj, other, rI), obj.x + 2*other.x + rI); 562 Asserts.assertEQ(test2(val1, other, rI), val1.x + 2*other.x + rI); 563 Asserts.assertEQ(test3(val1, other, rI), val1.x + 2*other.x + rI); 564 Asserts.assertEQ(test4(obj, other, rI), obj.x + 2*other.x + rI); 565 Asserts.assertEQ(test5(val1, other, rI), val1.x + other.x + rI); 566 Asserts.assertEQ(test6(val1, other, rI), val1.x + 2*other.x + rI); 567 Asserts.assertEQ(test7(obj, other, rI), obj.x + other.x + rI); 568 Asserts.assertEQ(test8(obj, other, rI), obj.x + 2*other.x + rI); 569 Asserts.assertEQ(test9(val1, other, rI, false), val1.x + 2*other.x + rI); 570 Asserts.assertEQ(test9(obj, other, rI, false), obj.x + 2*other.x + rI); 571 Asserts.assertEQ(test10(val1, other, rI, false), val1.x + 2*other.x + rI); 572 Asserts.assertEQ(test10(obj, other, rI, false), obj.x + 2*other.x + rI); 573 Asserts.assertEQ(test11(val1, other, rI, false), val1.x + 2*other.x + rI); 574 Asserts.assertEQ(test12(val1, other, rI, false), val1.x + 2*other.x + rI); 575 Asserts.assertEQ(test13(obj, other, rI, false), obj.x + 2*other.x + rI); 576 Asserts.assertEQ(test14(obj, other, rI, false), obj.x + 2*other.x + rI); 577 Asserts.assertEQ(test15(obj, other, rI), obj.x + 2*other.x + rI); 578 Asserts.assertEQ(test16(val1, other, rI), val1.x + 2*other.x + rI); 579 Asserts.assertEQ(test17(val1), val1.x); 580 Asserts.assertEQ(test18(val1, rI), val1.x + 6*rI); 581 Asserts.assertEQ(test18(val2, rI), val2.x + 6*rI); 582 Asserts.assertEQ(test18(val3, rI), (int)(4*val3.d1 + 6*rI)); 583 Asserts.assertEQ(test18(val4, rI), 4*val4.x1 + 6*rI); 584 Asserts.assertEQ(test18(obj, rI), obj.x + 6*rI); 585 Asserts.assertEQ(test19(val1, rI), val1.x + 7*rI); 586 Asserts.assertEQ(test19(val2, rI), val2.x + 7*rI); 587 Asserts.assertEQ(test19(val3, rI), (int)(4*val3.d1 + 7*rI)); 588 Asserts.assertEQ(test19(val4, rI), 4*val4.x1 + 7*rI); 589 Asserts.assertEQ(test19(obj, rI), obj.x + 7*rI); 590 Asserts.assertEQ(test20(val1, val3, rI), (int)(val1.x + 4*val3.d1 + 6*rI)); 591 Asserts.assertEQ(test20(val2, val3, rI), (int)(val2.x + 4*val3.d1 + 6*rI)); 592 Asserts.assertEQ(test20(val3, val3, rI), (int)(4*val3.d1 + 4*val3.d1 + 6*rI)); 593 Asserts.assertEQ(test20(val4, val3, rI), (int)(4*val4.x1 + 4*val3.d1 + 6*rI)); 594 Asserts.assertEQ(test20(obj, val3, rI), (int)(obj.x + 4*val3.d1 + 6*rI)); 595 Asserts.assertEQ(test21(val1, val4, rI), val1.x + 4*val4.x1 + 6*rI); 596 Asserts.assertEQ(test21(val2, val4, rI), val2.x + 4*val4.x1 + 6*rI); 597 Asserts.assertEQ(test21(val3, val4, rI), (int)(4*val3.d1 + 4*val4.x1 + 6*rI)); 598 Asserts.assertEQ(test21(val4, val4, rI), 4*val4.x1 + 4*val4.x1 + 6*rI); 599 Asserts.assertEQ(test21(obj, val4, rI), obj.x + 4*val4.x1 + 6*rI); 600 } 601 602 // Trigger deoptimization 603 Asserts.assertEQ(val1.test3(other, other, rI, true).getValue(), val1.x + other.x + rI); 604 Asserts.assertEQ(obj.test3(other, other, rI, true).getValue(), obj.x + other.x + rI); 605 606 // Check results of methods still calling the deoptimized methods 607 Asserts.assertEQ(test9(val1, other, rI, false), val1.x + 2*other.x + rI); 608 Asserts.assertEQ(test9(obj, other, rI, false), obj.x + 2*other.x + rI); 609 Asserts.assertEQ(test10(obj, other, rI, false), obj.x + 2*other.x + rI); 610 Asserts.assertEQ(test10(val1, other, rI, false), val1.x + 2*other.x + rI); 611 Asserts.assertEQ(test11(val1, other, rI, false), val1.x + 2*other.x + rI); 612 Asserts.assertEQ(test11(obj, other, rI, false), obj.x + 2*other.x + rI); 613 Asserts.assertEQ(test12(obj, other, rI, false), obj.x + 2*other.x + rI); 614 Asserts.assertEQ(test12(val1, other, rI, false), val1.x + 2*other.x + rI); 615 Asserts.assertEQ(test13(val1, other, rI, false), val1.x + 2*other.x + rI); 616 Asserts.assertEQ(test13(obj, other, rI, false), obj.x + 2*other.x + rI); 617 Asserts.assertEQ(test14(obj, other, rI, false), obj.x + 2*other.x + rI); 618 Asserts.assertEQ(test14(val1, other, rI, false), val1.x + 2*other.x + rI); 619 620 // Check with unexpected arguments 621 Asserts.assertEQ(test1(val2, other, rI), val2.x + other.x + rI); 622 Asserts.assertEQ(test2(val2, other, rI), val2.x + 2*other.x + rI); 623 Asserts.assertEQ(test5(val2, other, rI), val2.x + other.x + rI); 624 Asserts.assertEQ(test6(val2, other, rI), val2.x + 2*other.x + rI); 625 Asserts.assertEQ(test7(val1, other, rI), val1.x + other.x + rI); 626 Asserts.assertEQ(test8(val1, other, rI), val1.x + 2*other.x + rI); 627 Asserts.assertEQ(test15(val1, other, rI), val1.x + 2*other.x + rI); 628 Asserts.assertEQ(test16(obj, other, rI), obj.x + 2*other.x + rI); 629 Asserts.assertEQ(test17(obj), obj.x); 630 } 631 }