1 /* 2 * Copyright (c) 2013, 2014, 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 import sun.hotspot.WhiteBox; 25 import sun.hotspot.code.NMethod; 26 27 import java.lang.reflect.Constructor; 28 import java.lang.reflect.Executable; 29 import java.lang.reflect.Method; 30 import java.util.Objects; 31 import java.util.concurrent.Callable; 32 import java.util.function.Function; 33 34 /** 35 * Abstract class for WhiteBox testing of JIT. 36 * 37 * @author igor.ignatyev@oracle.com 38 */ 39 public abstract class CompilerWhiteBoxTest { 40 /** {@code CompLevel::CompLevel_none} -- Interpreter */ 41 protected static final int COMP_LEVEL_NONE = 0; 42 /** {@code CompLevel::CompLevel_any}, {@code CompLevel::CompLevel_all} */ 43 protected static final int COMP_LEVEL_ANY = -1; 44 /** {@code CompLevel::CompLevel_simple} -- C1 */ 45 protected static final int COMP_LEVEL_SIMPLE = 1; 46 /** {@code CompLevel::CompLevel_limited_profile} -- C1, invocation & backedge counters */ 47 protected static final int COMP_LEVEL_LIMITED_PROFILE = 2; 48 /** {@code CompLevel::CompLevel_full_profile} -- C1, invocation & backedge counters + mdo */ 49 protected static final int COMP_LEVEL_FULL_PROFILE = 3; 50 /** {@code CompLevel::CompLevel_full_optimization} -- C2 or Shark */ 51 protected static final int COMP_LEVEL_FULL_OPTIMIZATION = 4; 52 /** Maximal value for CompLevel */ 53 protected static final int COMP_LEVEL_MAX = COMP_LEVEL_FULL_OPTIMIZATION; 54 55 /** Instance of WhiteBox */ 56 protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 57 /** Value of {@code -XX:CompileThreshold} */ 58 protected static final int COMPILE_THRESHOLD 59 = Integer.parseInt(getVMOption("CompileThreshold", "10000")); 60 /** Value of {@code -XX:BackgroundCompilation} */ 61 protected static final boolean BACKGROUND_COMPILATION 62 = Boolean.valueOf(getVMOption("BackgroundCompilation", "true")); 63 /** Value of {@code -XX:TieredCompilation} */ 64 protected static final boolean TIERED_COMPILATION 65 = Boolean.valueOf(getVMOption("TieredCompilation", "false")); 66 /** Value of {@code -XX:TieredStopAtLevel} */ 67 protected static final int TIERED_STOP_AT_LEVEL 68 = Integer.parseInt(getVMOption("TieredStopAtLevel", "0")); 69 /** Flag for verbose output, true if {@code -Dverbose} specified */ 70 protected static final boolean IS_VERBOSE 71 = System.getProperty("verbose") != null; 72 /** invocation count to trigger compilation */ 73 protected static final int THRESHOLD; 74 /** invocation count to trigger OSR compilation */ 75 protected static final long BACKEDGE_THRESHOLD; 76 /** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */ 77 protected static final String MODE = System.getProperty("java.vm.info"); 78 79 static { 80 if (TIERED_COMPILATION) { 81 BACKEDGE_THRESHOLD = THRESHOLD = 150000; 82 } else { 83 THRESHOLD = COMPILE_THRESHOLD; 84 BACKEDGE_THRESHOLD = COMPILE_THRESHOLD * Long.parseLong(getVMOption( 85 "OnStackReplacePercentage")); 86 } 87 } 88 89 /** 90 * Returns value of VM option. 91 * 92 * @param name option's name 93 * @return value of option or {@code null}, if option doesn't exist 94 * @throws NullPointerException if name is null 95 */ 96 protected static String getVMOption(String name) { 97 Objects.requireNonNull(name); 98 return Objects.toString(WHITE_BOX.getVMFlag(name), null); 99 } 100 101 /** 102 * Returns value of VM option or default value. 103 * 104 * @param name option's name 105 * @param defaultValue default value 106 * @return value of option or {@code defaultValue}, if option doesn't exist 107 * @throws NullPointerException if name is null 108 * @see #getVMOption(String) 109 */ 110 protected static String getVMOption(String name, String defaultValue) { 111 String result = getVMOption(name); 112 return result == null ? defaultValue : result; 113 } 114 115 /** copy of is_c1_compile(int) from utilities/globalDefinitions.hpp */ 116 protected static boolean isC1Compile(int compLevel) { 117 return (compLevel > COMP_LEVEL_NONE) 118 && (compLevel < COMP_LEVEL_FULL_OPTIMIZATION); 119 } 120 121 /** copy of is_c2_compile(int) from utilities/globalDefinitions.hpp */ 122 protected static boolean isC2Compile(int compLevel) { 123 return compLevel == COMP_LEVEL_FULL_OPTIMIZATION; 124 } 125 126 protected static void main( 127 Function<TestCase, CompilerWhiteBoxTest> constructor, 128 String[] args) { 129 if (args.length == 0) { 130 for (TestCase test : SimpleTestCase.values()) { 131 constructor.apply(test).runTest(); 132 } 133 } else { 134 for (String name : args) { 135 constructor.apply(SimpleTestCase.valueOf(name)).runTest(); 136 } 137 } 138 } 139 140 /** tested method */ 141 protected final Executable method; 142 protected final TestCase testCase; 143 144 /** 145 * Constructor. 146 * 147 * @param testCase object, that contains tested method and way to invoke it. 148 */ 149 protected CompilerWhiteBoxTest(TestCase testCase) { 150 Objects.requireNonNull(testCase); 151 System.out.println("TEST CASE:" + testCase.name()); 152 method = testCase.getExecutable(); 153 this.testCase = testCase; 154 } 155 156 /** 157 * Template method for testing. Prints tested method's info before 158 * {@linkplain #test()} and after {@linkplain #test()} or on thrown 159 * exception. 160 * 161 * @throws RuntimeException if method {@linkplain #test()} throws any 162 * exception 163 * @see #test() 164 */ 165 protected final void runTest() { 166 if (CompilerWhiteBoxTest.MODE.startsWith("interpreted ")) { 167 System.err.println( 168 "Warning: test is not applicable in interpreted mode"); 169 return; 170 } 171 System.out.println("at test's start:"); 172 printInfo(); 173 try { 174 test(); 175 } catch (Exception e) { 176 System.out.printf("on exception '%s':", e.getMessage()); 177 printInfo(); 178 e.printStackTrace(); 179 if (e instanceof RuntimeException) { 180 throw (RuntimeException) e; 181 } 182 throw new RuntimeException(e); 183 } 184 System.out.println("at test's end:"); 185 printInfo(); 186 } 187 188 /** 189 * Checks, that {@linkplain #method} is not compiled at the given compilation 190 * level or above. 191 * 192 * @param compLevel 193 * 194 * @throws RuntimeException if {@linkplain #method} is in compiler queue or 195 * is compiled, or if {@linkplain #method} has zero 196 * compilation level. 197 */ 198 protected final void checkNotCompiled(int compLevel) { 199 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { 200 throw new RuntimeException(method + " must not be in queue"); 201 } 202 if (WHITE_BOX.getMethodCompilationLevel(method, false) >= compLevel) { 203 throw new RuntimeException(method + " comp_level must be >= maxCompLevel"); 204 } 205 if (WHITE_BOX.getMethodCompilationLevel(method, true) >= compLevel) { 206 throw new RuntimeException(method + " osr_comp_level must be >= maxCompLevel"); 207 } 208 } 209 210 /** 211 * Checks, that {@linkplain #method} is not compiled. 212 * 213 * @throws RuntimeException if {@linkplain #method} is in compiler queue or 214 * is compiled, or if {@linkplain #method} has zero 215 * compilation level. 216 */ 217 protected final void checkNotCompiled() { 218 checkNotCompiled(true); 219 checkNotCompiled(false); 220 } 221 222 /** 223 * Checks, that {@linkplain #method} is not (OSR-)compiled. 224 * 225 * @param isOsr Check for OSR compilation if true 226 * @throws RuntimeException if {@linkplain #method} is in compiler queue or 227 * is compiled, or if {@linkplain #method} has zero 228 * compilation level. 229 */ 230 protected final void checkNotCompiled(boolean isOsr) { 231 waitBackgroundCompilation(); 232 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { 233 throw new RuntimeException(method + " must not be in queue"); 234 } 235 if (WHITE_BOX.isMethodCompiled(method, isOsr)) { 236 throw new RuntimeException(method + " must not be " + 237 (isOsr ? "osr_" : "") + "compiled"); 238 } 239 if (WHITE_BOX.getMethodCompilationLevel(method, isOsr) != 0) { 240 throw new RuntimeException(method + (isOsr ? " osr_" : " ") + 241 "comp_level must be == 0"); 242 } 243 } 244 245 /** 246 * Checks, that {@linkplain #method} is compiled. 247 * 248 * @throws RuntimeException if {@linkplain #method} isn't in compiler queue 249 * and isn't compiled, or if {@linkplain #method} 250 * has nonzero compilation level 251 */ 252 protected final void checkCompiled() { 253 final long start = System.currentTimeMillis(); 254 waitBackgroundCompilation(); 255 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { 256 System.err.printf("Warning: %s is still in queue after %dms%n", 257 method, System.currentTimeMillis() - start); 258 return; 259 } 260 if (!WHITE_BOX.isMethodCompiled(method, testCase.isOsr())) { 261 throw new RuntimeException(method + " must be " 262 + (testCase.isOsr() ? "osr_" : "") + "compiled"); 263 } 264 if (WHITE_BOX.getMethodCompilationLevel(method, testCase.isOsr()) 265 == 0) { 266 throw new RuntimeException(method 267 + (testCase.isOsr() ? " osr_" : " ") 268 + "comp_level must be != 0"); 269 } 270 } 271 272 protected final void deoptimize() { 273 WHITE_BOX.deoptimizeMethod(method, testCase.isOsr()); 274 if (testCase.isOsr()) { 275 WHITE_BOX.deoptimizeMethod(method, false); 276 } 277 } 278 279 protected final int getCompLevel() { 280 NMethod nm = NMethod.get(method, testCase.isOsr()); 281 return nm == null ? COMP_LEVEL_NONE : nm.comp_level; 282 } 283 284 protected final boolean isCompilable() { 285 return WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY, 286 testCase.isOsr()); 287 } 288 289 protected final boolean isCompilable(int compLevel) { 290 return WHITE_BOX 291 .isMethodCompilable(method, compLevel, testCase.isOsr()); 292 } 293 294 protected final void makeNotCompilable() { 295 WHITE_BOX.makeMethodNotCompilable(method, COMP_LEVEL_ANY, 296 testCase.isOsr()); 297 } 298 299 protected final void makeNotCompilable(int compLevel) { 300 WHITE_BOX.makeMethodNotCompilable(method, compLevel, testCase.isOsr()); 301 } 302 303 /** 304 * Waits for completion of background compilation of {@linkplain #method}. 305 */ 306 protected final void waitBackgroundCompilation() { 307 waitBackgroundCompilation(method); 308 } 309 310 /** 311 * Waits for completion of background compilation of the given executable. 312 * 313 * @param executable Executable 314 */ 315 protected static final void waitBackgroundCompilation(Executable executable) { 316 if (!BACKGROUND_COMPILATION) { 317 return; 318 } 319 final Object obj = new Object(); 320 for (int i = 0; i < 10 321 && WHITE_BOX.isMethodQueuedForCompilation(executable); ++i) { 322 synchronized (obj) { 323 try { 324 obj.wait(1000); 325 } catch (InterruptedException e) { 326 Thread.currentThread().interrupt(); 327 } 328 } 329 } 330 } 331 332 /** 333 * Prints information about {@linkplain #method}. 334 */ 335 protected final void printInfo() { 336 System.out.printf("%n%s:%n", method); 337 System.out.printf("\tcompilable:\t%b%n", 338 WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY, false)); 339 boolean isCompiled = WHITE_BOX.isMethodCompiled(method, false); 340 System.out.printf("\tcompiled:\t%b%n", isCompiled); 341 if (isCompiled) { 342 System.out.printf("\tcompile_id:\t%d%n", 343 NMethod.get(method, false).compile_id); 344 } 345 System.out.printf("\tcomp_level:\t%d%n", 346 WHITE_BOX.getMethodCompilationLevel(method, false)); 347 System.out.printf("\tosr_compilable:\t%b%n", 348 WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY, true)); 349 isCompiled = WHITE_BOX.isMethodCompiled(method, true); 350 System.out.printf("\tosr_compiled:\t%b%n", isCompiled); 351 if (isCompiled) { 352 System.out.printf("\tosr_compile_id:\t%d%n", 353 NMethod.get(method, true).compile_id); 354 } 355 System.out.printf("\tosr_comp_level:\t%d%n", 356 WHITE_BOX.getMethodCompilationLevel(method, true)); 357 System.out.printf("\tin_queue:\t%b%n", 358 WHITE_BOX.isMethodQueuedForCompilation(method)); 359 System.out.printf("compile_queues_size:\t%d%n%n", 360 WHITE_BOX.getCompileQueuesSize()); 361 } 362 363 /** 364 * Executes testing. 365 */ 366 protected abstract void test() throws Exception; 367 368 /** 369 * Tries to trigger compilation of {@linkplain #method} by call 370 * {@linkplain TestCase#getCallable()} enough times. 371 * 372 * @return accumulated result 373 * @see #compile(int) 374 */ 375 protected final int compile() { 376 if (testCase.isOsr()) { 377 return compile(1); 378 } else { 379 return compile(THRESHOLD); 380 } 381 } 382 383 /** 384 * Tries to trigger compilation of {@linkplain #method} by call 385 * {@linkplain TestCase#getCallable()} specified times. 386 * 387 * @param count invocation count 388 * @return accumulated result 389 */ 390 protected final int compile(int count) { 391 int result = 0; 392 Integer tmp; 393 for (int i = 0; i < count; ++i) { 394 try { 395 tmp = testCase.getCallable().call(); 396 } catch (Exception e) { 397 tmp = null; 398 } 399 result += tmp == null ? 0 : tmp; 400 } 401 if (IS_VERBOSE) { 402 System.out.println("method was invoked " + count + " times"); 403 } 404 return result; 405 } 406 407 /** 408 * Utility interface provides tested method and object to invoke it. 409 */ 410 public interface TestCase { 411 /** the name of test case */ 412 String name(); 413 414 /** tested method */ 415 Executable getExecutable(); 416 417 /** object to invoke {@linkplain #getExecutable()} */ 418 Callable<Integer> getCallable(); 419 420 /** flag for OSR test case */ 421 boolean isOsr(); 422 } 423 424 /** 425 * @return {@code true} if the current test case is OSR and the mode is 426 * Xcomp, otherwise {@code false} 427 */ 428 protected boolean skipXcompOSR() { 429 boolean result = testCase.isOsr() 430 && CompilerWhiteBoxTest.MODE.startsWith("compiled "); 431 if (result && IS_VERBOSE) { 432 System.err.printf("Warning: %s is not applicable in %s%n", 433 testCase.name(), CompilerWhiteBoxTest.MODE); 434 } 435 return result; 436 } 437 438 /** 439 * Skip the test for the specified value of Tiered Compilation 440 * @param value of TieredCompilation the test should not run with 441 * @return {@code true} if the test should be skipped, 442 * {@code false} otherwise 443 */ 444 protected static boolean skipOnTieredCompilation(boolean value) { 445 if (value == CompilerWhiteBoxTest.TIERED_COMPILATION) { 446 System.err.println("Test isn't applicable w/ " 447 + (value ? "enabled" : "disabled") 448 + "TieredCompilation. Skip test."); 449 return true; 450 } 451 return false; 452 } 453 } 454 455 enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase { 456 /** constructor test case */ 457 CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false), 458 /** method test case */ 459 METHOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false), 460 /** static method test case */ 461 STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false), 462 /** OSR constructor test case */ 463 OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR, 464 Helper.OSR_CONSTRUCTOR_CALLABLE, true), 465 /** OSR method test case */ 466 OSR_METHOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true), 467 /** OSR static method test case */ 468 OSR_STATIC_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true); 469 470 private final Executable executable; 471 private final Callable<Integer> callable; 472 private final boolean isOsr; 473 474 private SimpleTestCase(Executable executable, Callable<Integer> callable, 475 boolean isOsr) { 476 this.executable = executable; 477 this.callable = callable; 478 this.isOsr = isOsr; 479 } 480 481 @Override 482 public Executable getExecutable() { 483 return executable; 484 } 485 486 @Override 487 public Callable<Integer> getCallable() { 488 return callable; 489 } 490 491 @Override 492 public boolean isOsr() { 493 return isOsr; 494 } 495 496 private static class Helper { 497 498 private static final Callable<Integer> CONSTRUCTOR_CALLABLE 499 = new Callable<Integer>() { 500 @Override 501 public Integer call() throws Exception { 502 return new Helper(1337).hashCode(); 503 } 504 }; 505 506 private static final Callable<Integer> METHOD_CALLABLE 507 = new Callable<Integer>() { 508 private final Helper helper = new Helper(); 509 510 @Override 511 public Integer call() throws Exception { 512 return helper.method(); 513 } 514 }; 515 516 private static final Callable<Integer> STATIC_CALLABLE 517 = new Callable<Integer>() { 518 @Override 519 public Integer call() throws Exception { 520 return staticMethod(); 521 } 522 }; 523 524 private static final Callable<Integer> OSR_CONSTRUCTOR_CALLABLE 525 = new Callable<Integer>() { 526 @Override 527 public Integer call() throws Exception { 528 return new Helper(null, CompilerWhiteBoxTest.BACKEDGE_THRESHOLD).hashCode(); 529 } 530 }; 531 532 private static final Callable<Integer> OSR_METHOD_CALLABLE 533 = new Callable<Integer>() { 534 private final Helper helper = new Helper(); 535 536 @Override 537 public Integer call() throws Exception { 538 return helper.osrMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD); 539 } 540 }; 541 542 private static final Callable<Integer> OSR_STATIC_CALLABLE 543 = new Callable<Integer>() { 544 @Override 545 public Integer call() throws Exception { 546 return osrStaticMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD); 547 } 548 }; 549 550 private static final Constructor CONSTRUCTOR; 551 private static final Constructor OSR_CONSTRUCTOR; 552 private static final Method METHOD; 553 private static final Method STATIC; 554 private static final Method OSR_METHOD; 555 private static final Method OSR_STATIC; 556 557 static { 558 try { 559 CONSTRUCTOR = Helper.class.getDeclaredConstructor(int.class); 560 } catch (NoSuchMethodException | SecurityException e) { 561 throw new RuntimeException( 562 "exception on getting method Helper.<init>(int)", e); 563 } 564 try { 565 OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor( 566 Object.class, long.class); 567 } catch (NoSuchMethodException | SecurityException e) { 568 throw new RuntimeException( 569 "exception on getting method Helper.<init>(Object, long)", e); 570 } 571 METHOD = getMethod("method"); 572 STATIC = getMethod("staticMethod"); 573 OSR_METHOD = getMethod("osrMethod", long.class); 574 OSR_STATIC = getMethod("osrStaticMethod", long.class); 575 } 576 577 private static Method getMethod(String name, Class<?>... parameterTypes) { 578 try { 579 return Helper.class.getDeclaredMethod(name, parameterTypes); 580 } catch (NoSuchMethodException | SecurityException e) { 581 throw new RuntimeException( 582 "exception on getting method Helper." + name, e); 583 } 584 } 585 586 private static int staticMethod() { 587 return 1138; 588 } 589 590 private int method() { 591 return 42; 592 } 593 594 /** 595 * Deoptimizes all non-osr versions of the given executable after 596 * compilation finished. 597 * 598 * @param e Executable 599 * @throws Exception 600 */ 601 private static void waitAndDeoptimize(Executable e) { 602 CompilerWhiteBoxTest.waitBackgroundCompilation(e); 603 if (WhiteBox.getWhiteBox().isMethodQueuedForCompilation(e)) { 604 throw new RuntimeException(e + " must not be in queue"); 605 } 606 // Deoptimize non-osr versions of executable 607 WhiteBox.getWhiteBox().deoptimizeMethod(e, false); 608 } 609 610 /** 611 * Executes the method multiple times to make sure we have 612 * enough profiling information before triggering an OSR 613 * compilation. Otherwise the C2 compiler may add uncommon traps. 614 * 615 * @param m Method to be executed 616 * @return Number of times the method was executed 617 * @throws Exception 618 */ 619 private static int warmup(Method m) throws Exception { 620 waitAndDeoptimize(m); 621 Helper helper = new Helper(); 622 int result = 0; 623 for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) { 624 result += (int)m.invoke(helper, 1); 625 } 626 // Wait to make sure OSR compilation is not blocked by 627 // non-OSR compilation in the compile queue 628 CompilerWhiteBoxTest.waitBackgroundCompilation(m); 629 return result; 630 } 631 632 /** 633 * Executes the constructor multiple times to make sure we 634 * have enough profiling information before triggering an OSR 635 * compilation. Otherwise the C2 compiler may add uncommon traps. 636 * 637 * @param c Constructor to be executed 638 * @return Number of times the constructor was executed 639 * @throws Exception 640 */ 641 private static int warmup(Constructor c) throws Exception { 642 waitAndDeoptimize(c); 643 int result = 0; 644 for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) { 645 result += c.newInstance(null, 1).hashCode(); 646 } 647 // Wait to make sure OSR compilation is not blocked by 648 // non-OSR compilation in the compile queue 649 CompilerWhiteBoxTest.waitBackgroundCompilation(c); 650 return result; 651 } 652 653 private static int osrStaticMethod(long limit) throws Exception { 654 int result = 0; 655 if (limit != 1) { 656 result = warmup(OSR_STATIC); 657 } 658 // Trigger osr compilation 659 for (long i = 0; i < limit; ++i) { 660 result += staticMethod(); 661 } 662 return result; 663 } 664 665 private int osrMethod(long limit) throws Exception { 666 int result = 0; 667 if (limit != 1) { 668 result = warmup(OSR_METHOD); 669 } 670 // Trigger osr compilation 671 for (long i = 0; i < limit; ++i) { 672 result += method(); 673 } 674 return result; 675 } 676 677 private final int x; 678 679 // for method and OSR method test case 680 public Helper() { 681 x = 0; 682 } 683 684 // for OSR constructor test case 685 private Helper(Object o, long limit) throws Exception { 686 int result = 0; 687 if (limit != 1) { 688 result = warmup(OSR_CONSTRUCTOR); 689 } 690 // Trigger osr compilation 691 for (long i = 0; i < limit; ++i) { 692 result += method(); 693 } 694 x = result; 695 } 696 697 // for constructor test case 698 private Helper(int x) { 699 this.x = x; 700 } 701 702 @Override 703 public int hashCode() { 704 return x; 705 } 706 } 707 }