|
24 | 24 | package jdk.test.whitebox; |
25 | 25 |
|
26 | 26 | import java.lang.management.MemoryUsage; |
| 27 | +import java.lang.ref.Reference; |
27 | 28 | import java.lang.reflect.Executable; |
| 29 | +import java.lang.reflect.InaccessibleObjectException; |
| 30 | +import java.lang.reflect.InvocationTargetException; |
| 31 | +import java.lang.reflect.Method; |
28 | 32 | import java.util.Arrays; |
29 | 33 | import java.util.List; |
30 | 34 | import java.util.function.BiFunction; |
@@ -434,6 +438,53 @@ public void clearInlineCaches(boolean preserve_static_stubs) { |
434 | 438 | // Force Full GC |
435 | 439 | public native void fullGC(); |
436 | 440 |
|
| 441 | + // Infrastructure for waitForReferenceProcessing() |
| 442 | + private static volatile Method waitForReferenceProcessingMethod = null; |
| 443 | + |
| 444 | + private static Method getWaitForReferenceProcessingMethod() { |
| 445 | + Method wfrp = waitForReferenceProcessingMethod; |
| 446 | + if (wfrp == null) { |
| 447 | + try { |
| 448 | + wfrp = Reference.class.getDeclaredMethod("waitForReferenceProcessing"); |
| 449 | + wfrp.setAccessible(true); |
| 450 | + assert wfrp.getReturnType() == Boolean.class; |
| 451 | + Class<?>[] ev = wfrp.getExceptionTypes(); |
| 452 | + assert ev.length == 1; |
| 453 | + assert ev[0] == InterruptedException.class; |
| 454 | + waitForReferenceProcessingMethod = wfrp; |
| 455 | + } catch (InaccessibleObjectException e) { |
| 456 | + throw new RuntimeException("Need to add @modules java.base/java.lang.ref:open to test?", e); |
| 457 | + } catch (NoSuchMethodException e) { |
| 458 | + throw new RuntimeException(e); |
| 459 | + } |
| 460 | + } |
| 461 | + return wfrp; |
| 462 | + } |
| 463 | + |
| 464 | + /** |
| 465 | + * Wait for reference processing, via Reference.waitForReferenceProcessing(). |
| 466 | + * Callers of this method will need the |
| 467 | + * @modules java.base/java.lang.ref:open |
| 468 | + * jtreg tag. |
| 469 | + * |
| 470 | + * This method should usually be called after a call to WhiteBox.fullGC(). |
| 471 | + */ |
| 472 | + public boolean waitForReferenceProcessing() throws InterruptedException { |
| 473 | + try { |
| 474 | + Method wfrp = getWaitForReferenceProcessingMethod(); |
| 475 | + return (Boolean) wfrp.invoke(null); |
| 476 | + } catch (IllegalAccessException e) { |
| 477 | + throw new RuntimeException("Shouldn't happen, we call setAccessible()", e); |
| 478 | + } catch (InvocationTargetException e) { |
| 479 | + Throwable cause = e.getCause(); |
| 480 | + if (cause instanceof InterruptedException) { |
| 481 | + throw (InterruptedException) cause; |
| 482 | + } else { |
| 483 | + throw new RuntimeException(e); |
| 484 | + } |
| 485 | + } |
| 486 | + } |
| 487 | + |
437 | 488 | // Returns true if the current GC supports concurrent collection control. |
438 | 489 | public native boolean supportsConcurrentGCBreakpoints(); |
439 | 490 |
|
|
0 commit comments