Mercurial > hg > truffle
comparison test/compiler/whitebox/CompilerWhiteBoxTest.java @ 12073:f99558245e5c
8022832: Add WB APIs for OSR compilation
Reviewed-by: kvn
author | iignatyev |
---|---|
date | Wed, 14 Aug 2013 23:50:23 +0400 |
parents | 11237ee74aae |
children | 303826f477c6 |
comparison
equal
deleted
inserted
replaced
12072:6c72125a2f40 | 12073:f99558245e5c |
---|---|
42 protected static int COMP_LEVEL_NONE = 0; | 42 protected static int COMP_LEVEL_NONE = 0; |
43 /** {@code CompLevel::CompLevel_any}, {@code CompLevel::CompLevel_all} */ | 43 /** {@code CompLevel::CompLevel_any}, {@code CompLevel::CompLevel_all} */ |
44 protected static int COMP_LEVEL_ANY = -1; | 44 protected static int COMP_LEVEL_ANY = -1; |
45 /** {@code CompLevel::CompLevel_simple} -- C1 */ | 45 /** {@code CompLevel::CompLevel_simple} -- C1 */ |
46 protected static int COMP_LEVEL_SIMPLE = 1; | 46 protected static int COMP_LEVEL_SIMPLE = 1; |
47 /** {@code CompLevel::CompLevel_limited_profile} -- C1, invocation & backedge counters */ | |
48 protected static int COMP_LEVEL_LIMITED_PROFILE = 2; | |
49 /** {@code CompLevel::CompLevel_full_profile} -- C1, invocation & backedge counters + mdo */ | |
50 protected static int COMP_LEVEL_FULL_PROFILE = 3; | |
47 /** {@code CompLevel::CompLevel_full_optimization} -- C2 or Shark */ | 51 /** {@code CompLevel::CompLevel_full_optimization} -- C2 or Shark */ |
48 protected static int COMP_LEVEL_FULL_OPTIMIZATION = 4; | 52 protected static int COMP_LEVEL_FULL_OPTIMIZATION = 4; |
53 /** Maximal value for CompLeveL */ | |
54 protected static int COMP_LEVEL_MAX = COMP_LEVEL_FULL_OPTIMIZATION; | |
49 | 55 |
50 /** Instance of WhiteBox */ | 56 /** Instance of WhiteBox */ |
51 protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); | 57 protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); |
52 /** Value of {@code -XX:CompileThreshold} */ | 58 /** Value of {@code -XX:CompileThreshold} */ |
53 protected static final int COMPILE_THRESHOLD | 59 protected static final int COMPILE_THRESHOLD |
62 protected static final int TIERED_STOP_AT_LEVEL | 68 protected static final int TIERED_STOP_AT_LEVEL |
63 = Integer.parseInt(getVMOption("TieredStopAtLevel", "0")); | 69 = Integer.parseInt(getVMOption("TieredStopAtLevel", "0")); |
64 /** Flag for verbose output, true if {@code -Dverbose} specified */ | 70 /** Flag for verbose output, true if {@code -Dverbose} specified */ |
65 protected static final boolean IS_VERBOSE | 71 protected static final boolean IS_VERBOSE |
66 = System.getProperty("verbose") != null; | 72 = System.getProperty("verbose") != null; |
73 /** count of invocation to triger compilation */ | |
74 protected static final int THRESHOLD; | |
75 /** count of invocation to triger OSR compilation */ | |
76 protected static final long BACKEDGE_THRESHOLD; | |
77 | |
78 static { | |
79 if (TIERED_COMPILATION) { | |
80 THRESHOLD = 150000; | |
81 BACKEDGE_THRESHOLD = 0xFFFFFFFFL; | |
82 } else { | |
83 THRESHOLD = COMPILE_THRESHOLD; | |
84 BACKEDGE_THRESHOLD = COMPILE_THRESHOLD * Long.parseLong(getVMOption( | |
85 "OnStackReplacePercentage")); | |
86 } | |
87 } | |
67 | 88 |
68 /** | 89 /** |
69 * Returns value of VM option. | 90 * Returns value of VM option. |
70 * | 91 * |
71 * @param name option's name | 92 * @param name option's name |
110 return compLevel == COMP_LEVEL_FULL_OPTIMIZATION; | 131 return compLevel == COMP_LEVEL_FULL_OPTIMIZATION; |
111 } | 132 } |
112 | 133 |
113 /** tested method */ | 134 /** tested method */ |
114 protected final Executable method; | 135 protected final Executable method; |
115 private final Callable<Integer> callable; | 136 protected final TestCase testCase; |
116 | 137 |
117 /** | 138 /** |
118 * Constructor. | 139 * Constructor. |
119 * | 140 * |
120 * @param testCase object, that contains tested method and way to invoke it. | 141 * @param testCase object, that contains tested method and way to invoke it. |
121 */ | 142 */ |
122 protected CompilerWhiteBoxTest(TestCase testCase) { | 143 protected CompilerWhiteBoxTest(TestCase testCase) { |
123 Objects.requireNonNull(testCase); | 144 Objects.requireNonNull(testCase); |
124 System.out.println("TEST CASE:" + testCase.name()); | 145 System.out.println("TEST CASE:" + testCase.name()); |
125 method = testCase.executable; | 146 method = testCase.executable; |
126 callable = testCase.callable; | 147 this.testCase = testCase; |
127 } | 148 } |
128 | 149 |
129 /** | 150 /** |
130 * Template method for testing. Prints tested method's info before | 151 * Template method for testing. Prints tested method's info before |
131 * {@linkplain #test()} and after {@linkplain #test()} or on thrown | 152 * {@linkplain #test()} and after {@linkplain #test()} or on thrown |
167 */ | 188 */ |
168 protected final void checkNotCompiled() { | 189 protected final void checkNotCompiled() { |
169 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { | 190 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { |
170 throw new RuntimeException(method + " must not be in queue"); | 191 throw new RuntimeException(method + " must not be in queue"); |
171 } | 192 } |
172 if (WHITE_BOX.isMethodCompiled(method)) { | 193 if (WHITE_BOX.isMethodCompiled(method, false)) { |
173 throw new RuntimeException(method + " must be not compiled"); | 194 throw new RuntimeException(method + " must be not compiled"); |
174 } | 195 } |
175 if (WHITE_BOX.getMethodCompilationLevel(method) != 0) { | 196 if (WHITE_BOX.getMethodCompilationLevel(method, false) != 0) { |
176 throw new RuntimeException(method + " comp_level must be == 0"); | 197 throw new RuntimeException(method + " comp_level must be == 0"); |
198 } | |
199 if (WHITE_BOX.isMethodCompiled(method, true)) { | |
200 throw new RuntimeException(method + " must be not osr_compiled"); | |
201 } | |
202 if (WHITE_BOX.getMethodCompilationLevel(method, true) != 0) { | |
203 throw new RuntimeException(method + " osr_comp_level must be == 0"); | |
177 } | 204 } |
178 } | 205 } |
179 | 206 |
180 /** | 207 /** |
181 * Checks, that {@linkplain #method} is compiled. | 208 * Checks, that {@linkplain #method} is compiled. |
190 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { | 217 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { |
191 System.err.printf("Warning: %s is still in queue after %dms%n", | 218 System.err.printf("Warning: %s is still in queue after %dms%n", |
192 method, System.currentTimeMillis() - start); | 219 method, System.currentTimeMillis() - start); |
193 return; | 220 return; |
194 } | 221 } |
195 if (!WHITE_BOX.isMethodCompiled(method)) { | 222 if (!WHITE_BOX.isMethodCompiled(method, testCase.isOsr)) { |
196 throw new RuntimeException(method + " must be compiled"); | 223 throw new RuntimeException(method + " must be " |
197 } | 224 + (testCase.isOsr ? "osr_" : "") + "compiled"); |
198 if (WHITE_BOX.getMethodCompilationLevel(method) == 0) { | 225 } |
199 throw new RuntimeException(method + " comp_level must be != 0"); | 226 if (WHITE_BOX.getMethodCompilationLevel(method, testCase.isOsr) == 0) { |
200 } | 227 throw new RuntimeException(method |
228 + (testCase.isOsr ? " osr_" : " ") | |
229 + "comp_level must be != 0"); | |
230 } | |
231 } | |
232 | |
233 protected final void deoptimize() { | |
234 WHITE_BOX.deoptimizeMethod(method, testCase.isOsr); | |
235 if (testCase.isOsr) { | |
236 WHITE_BOX.deoptimizeMethod(method, false); | |
237 } | |
238 } | |
239 | |
240 protected final int getCompLevel() { | |
241 return WHITE_BOX.getMethodCompilationLevel(method, testCase.isOsr); | |
242 } | |
243 | |
244 protected final boolean isCompilable() { | |
245 return WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY, | |
246 testCase.isOsr); | |
247 } | |
248 | |
249 protected final boolean isCompilable(int compLevel) { | |
250 return WHITE_BOX.isMethodCompilable(method, compLevel, testCase.isOsr); | |
251 } | |
252 | |
253 protected final void makeNotCompilable() { | |
254 WHITE_BOX.makeMethodNotCompilable(method, COMP_LEVEL_ANY, | |
255 testCase.isOsr); | |
256 } | |
257 | |
258 protected final void makeNotCompilable(int compLevel) { | |
259 WHITE_BOX.makeMethodNotCompilable(method, compLevel, testCase.isOsr); | |
201 } | 260 } |
202 | 261 |
203 /** | 262 /** |
204 * Waits for completion of background compilation of {@linkplain #method}. | 263 * Waits for completion of background compilation of {@linkplain #method}. |
205 */ | 264 */ |
224 * Prints information about {@linkplain #method}. | 283 * Prints information about {@linkplain #method}. |
225 */ | 284 */ |
226 protected final void printInfo() { | 285 protected final void printInfo() { |
227 System.out.printf("%n%s:%n", method); | 286 System.out.printf("%n%s:%n", method); |
228 System.out.printf("\tcompilable:\t%b%n", | 287 System.out.printf("\tcompilable:\t%b%n", |
229 WHITE_BOX.isMethodCompilable(method)); | 288 WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY, false)); |
230 System.out.printf("\tcompiled:\t%b%n", | 289 System.out.printf("\tcompiled:\t%b%n", |
231 WHITE_BOX.isMethodCompiled(method)); | 290 WHITE_BOX.isMethodCompiled(method, false)); |
232 System.out.printf("\tcomp_level:\t%d%n", | 291 System.out.printf("\tcomp_level:\t%d%n", |
233 WHITE_BOX.getMethodCompilationLevel(method)); | 292 WHITE_BOX.getMethodCompilationLevel(method, false)); |
234 System.out.printf("\tin_queue:\t%b%n", | 293 System.out.printf("\tosr_compilable:\t%b%n", |
294 WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY, true)); | |
295 System.out.printf("\tosr_compiled:\t%b%n", | |
296 WHITE_BOX.isMethodCompiled(method, true)); | |
297 System.out.printf("\tosr_comp_level:\t%d%n", | |
298 WHITE_BOX.getMethodCompilationLevel(method, true)); | |
299 System.out.printf("\tin_queue:\t%b%n", | |
235 WHITE_BOX.isMethodQueuedForCompilation(method)); | 300 WHITE_BOX.isMethodQueuedForCompilation(method)); |
236 System.out.printf("compile_queues_size:\t%d%n%n", | 301 System.out.printf("compile_queues_size:\t%d%n%n", |
237 WHITE_BOX.getCompileQueuesSize()); | 302 WHITE_BOX.getCompileQueuesSize()); |
238 } | 303 } |
239 | 304 |
242 */ | 307 */ |
243 protected abstract void test() throws Exception; | 308 protected abstract void test() throws Exception; |
244 | 309 |
245 /** | 310 /** |
246 * Tries to trigger compilation of {@linkplain #method} by call | 311 * Tries to trigger compilation of {@linkplain #method} by call |
247 * {@linkplain #callable} enough times. | 312 * {@linkplain #testCase.callable} enough times. |
248 * | 313 * |
249 * @return accumulated result | 314 * @return accumulated result |
250 * @see #compile(int) | 315 * @see #compile(int) |
251 */ | 316 */ |
252 protected final int compile() { | 317 protected final int compile() { |
253 return compile(Math.max(COMPILE_THRESHOLD, 150000)); | 318 if (testCase.isOsr) { |
319 return compile(1); | |
320 } else { | |
321 return compile(THRESHOLD); | |
322 } | |
254 } | 323 } |
255 | 324 |
256 /** | 325 /** |
257 * Tries to trigger compilation of {@linkplain #method} by call | 326 * Tries to trigger compilation of {@linkplain #method} by call |
258 * {@linkplain #callable} specified times. | 327 * {@linkplain #testCase.callable} specified times. |
259 * | 328 * |
260 * @param count invocation count | 329 * @param count invocation count |
261 * @return accumulated result | 330 * @return accumulated result |
262 */ | 331 */ |
263 protected final int compile(int count) { | 332 protected final int compile(int count) { |
264 int result = 0; | 333 int result = 0; |
265 Integer tmp; | 334 Integer tmp; |
266 for (int i = 0; i < count; ++i) { | 335 for (int i = 0; i < count; ++i) { |
267 try { | 336 try { |
268 tmp = callable.call(); | 337 tmp = testCase.callable.call(); |
269 } catch (Exception e) { | 338 } catch (Exception e) { |
270 tmp = null; | 339 tmp = null; |
271 } | 340 } |
272 result += tmp == null ? 0 : tmp; | 341 result += tmp == null ? 0 : tmp; |
273 } | 342 } |
281 /** | 350 /** |
282 * Utility structure containing tested method and object to invoke it. | 351 * Utility structure containing tested method and object to invoke it. |
283 */ | 352 */ |
284 enum TestCase { | 353 enum TestCase { |
285 /** constructor test case */ | 354 /** constructor test case */ |
286 CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE), | 355 CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false), |
287 /** method test case */ | 356 /** method test case */ |
288 METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE), | 357 METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false), |
289 /** static method test case */ | 358 /** static method test case */ |
290 STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE); | 359 STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false), |
360 | |
361 /** OSR constructor test case */ | |
362 OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR, | |
363 Helper.OSR_CONSTRUCTOR_CALLABLE, true), | |
364 /** OSR method test case */ | |
365 OSR_METOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true), | |
366 /** OSR static method test case */ | |
367 OSR_STATIC_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true); | |
291 | 368 |
292 /** tested method */ | 369 /** tested method */ |
293 final Executable executable; | 370 final Executable executable; |
294 /** object to invoke {@linkplain #executable} */ | 371 /** object to invoke {@linkplain #executable} */ |
295 final Callable<Integer> callable; | 372 final Callable<Integer> callable; |
296 | 373 /** flag for OSR test case */ |
297 private TestCase(Executable executable, Callable<Integer> callable) { | 374 final boolean isOsr; |
375 | |
376 private TestCase(Executable executable, Callable<Integer> callable, | |
377 boolean isOsr) { | |
298 this.executable = executable; | 378 this.executable = executable; |
299 this.callable = callable; | 379 this.callable = callable; |
380 this.isOsr = isOsr; | |
300 } | 381 } |
301 | 382 |
302 private static class Helper { | 383 private static class Helper { |
384 | |
303 private static final Callable<Integer> CONSTRUCTOR_CALLABLE | 385 private static final Callable<Integer> CONSTRUCTOR_CALLABLE |
304 = new Callable<Integer>() { | 386 = new Callable<Integer>() { |
305 @Override | 387 @Override |
306 public Integer call() throws Exception { | 388 public Integer call() throws Exception { |
307 return new Helper(1337).hashCode(); | 389 return new Helper(1337).hashCode(); |
324 public Integer call() throws Exception { | 406 public Integer call() throws Exception { |
325 return staticMethod(); | 407 return staticMethod(); |
326 } | 408 } |
327 }; | 409 }; |
328 | 410 |
411 private static final Callable<Integer> OSR_CONSTRUCTOR_CALLABLE | |
412 = new Callable<Integer>() { | |
413 @Override | |
414 public Integer call() throws Exception { | |
415 return new Helper(null).hashCode(); | |
416 } | |
417 }; | |
418 | |
419 private static final Callable<Integer> OSR_METHOD_CALLABLE | |
420 = new Callable<Integer>() { | |
421 private final Helper helper = new Helper(); | |
422 | |
423 @Override | |
424 public Integer call() throws Exception { | |
425 return helper.osrMethod(); | |
426 } | |
427 }; | |
428 | |
429 private static final Callable<Integer> OSR_STATIC_CALLABLE | |
430 = new Callable<Integer>() { | |
431 @Override | |
432 public Integer call() throws Exception { | |
433 return osrStaticMethod(); | |
434 } | |
435 }; | |
436 | |
437 | |
329 private static final Constructor CONSTRUCTOR; | 438 private static final Constructor CONSTRUCTOR; |
439 private static final Constructor OSR_CONSTRUCTOR; | |
330 private static final Method METHOD; | 440 private static final Method METHOD; |
331 private static final Method STATIC; | 441 private static final Method STATIC; |
442 private static final Method OSR_METHOD; | |
443 private static final Method OSR_STATIC; | |
332 | 444 |
333 static { | 445 static { |
334 try { | 446 try { |
335 CONSTRUCTOR = Helper.class.getDeclaredConstructor(int.class); | 447 CONSTRUCTOR = Helper.class.getDeclaredConstructor(int.class); |
336 } catch (NoSuchMethodException | SecurityException e) { | 448 } catch (NoSuchMethodException | SecurityException e) { |
337 throw new RuntimeException( | 449 throw new RuntimeException( |
338 "exception on getting method Helper.<init>(int)", e); | 450 "exception on getting method Helper.<init>(int)", e); |
339 } | 451 } |
340 try { | 452 try { |
341 METHOD = Helper.class.getDeclaredMethod("method"); | 453 OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor( |
454 Object.class); | |
342 } catch (NoSuchMethodException | SecurityException e) { | 455 } catch (NoSuchMethodException | SecurityException e) { |
343 throw new RuntimeException( | 456 throw new RuntimeException( |
344 "exception on getting method Helper.method()", e); | 457 "exception on getting method Helper.<init>(Object)", e); |
345 } | 458 } |
459 METHOD = getMethod("method"); | |
460 STATIC = getMethod("staticMethod"); | |
461 OSR_METHOD = getMethod("osrMethod"); | |
462 OSR_STATIC = getMethod("osrStaticMethod"); | |
463 } | |
464 | |
465 private static Method getMethod(String name) { | |
346 try { | 466 try { |
347 STATIC = Helper.class.getDeclaredMethod("staticMethod"); | 467 return Helper.class.getDeclaredMethod(name); |
348 } catch (NoSuchMethodException | SecurityException e) { | 468 } catch (NoSuchMethodException | SecurityException e) { |
349 throw new RuntimeException( | 469 throw new RuntimeException( |
350 "exception on getting method Helper.staticMethod()", e); | 470 "exception on getting method Helper." + name, e); |
351 } | 471 } |
472 | |
352 } | 473 } |
353 | 474 |
354 private static int staticMethod() { | 475 private static int staticMethod() { |
355 return 1138; | 476 return 1138; |
356 } | 477 } |
357 | 478 |
358 private int method() { | 479 private int method() { |
359 return 42; | 480 return 42; |
360 } | 481 } |
361 | 482 |
483 private static int osrStaticMethod() { | |
484 int result = 0; | |
485 for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) { | |
486 result += staticMethod(); | |
487 } | |
488 return result; | |
489 } | |
490 | |
491 private int osrMethod() { | |
492 int result = 0; | |
493 for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) { | |
494 result += method(); | |
495 } | |
496 return result; | |
497 } | |
498 | |
362 private final int x; | 499 private final int x; |
363 | 500 |
501 // for method and OSR method test case | |
364 public Helper() { | 502 public Helper() { |
365 x = 0; | 503 x = 0; |
366 } | 504 } |
367 | 505 |
506 // for OSR constructor test case | |
507 private Helper(Object o) { | |
508 int result = 0; | |
509 for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) { | |
510 result += method(); | |
511 } | |
512 x = result; | |
513 } | |
514 | |
515 // for constructor test case | |
368 private Helper(int x) { | 516 private Helper(int x) { |
369 this.x = x; | 517 this.x = x; |
370 } | 518 } |
371 | 519 |
372 @Override | 520 @Override |