|
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; |
@@ -526,6 +530,53 @@ public void clearInlineCaches(boolean preserve_static_stubs) { |
526 | 530 | // Force Full GC |
527 | 531 | public native void fullGC(); |
528 | 532 |
|
| 533 | + // Infrastructure for waitForReferenceProcessing() |
| 534 | + private static volatile Method waitForReferenceProcessingMethod = null; |
| 535 | + |
| 536 | + private static Method getWaitForReferenceProcessingMethod() { |
| 537 | + Method wfrp = waitForReferenceProcessingMethod; |
| 538 | + if (wfrp == null) { |
| 539 | + try { |
| 540 | + wfrp = Reference.class.getDeclaredMethod("waitForReferenceProcessing"); |
| 541 | + wfrp.setAccessible(true); |
| 542 | + assert wfrp.getReturnType() == Boolean.class; |
| 543 | + Class<?>[] ev = wfrp.getExceptionTypes(); |
| 544 | + assert ev.length == 1; |
| 545 | + assert ev[0] == InterruptedException.class; |
| 546 | + waitForReferenceProcessingMethod = wfrp; |
| 547 | + } catch (InaccessibleObjectException e) { |
| 548 | + throw new RuntimeException("Need to add @modules java.base/java.lang.ref:open to test?", e); |
| 549 | + } catch (NoSuchMethodException e) { |
| 550 | + throw new RuntimeException(e); |
| 551 | + } |
| 552 | + } |
| 553 | + return wfrp; |
| 554 | + } |
| 555 | + |
| 556 | + /** |
| 557 | + * Wait for reference processing, via Reference.waitForReferenceProcessing(). |
| 558 | + * Callers of this method will need the |
| 559 | + * @modules java.base/java.lang.ref:open |
| 560 | + * jtreg tag. |
| 561 | + * |
| 562 | + * This method should usually be called after a call to WhiteBox.fullGC(). |
| 563 | + */ |
| 564 | + public boolean waitForReferenceProcessing() throws InterruptedException { |
| 565 | + try { |
| 566 | + Method wfrp = getWaitForReferenceProcessingMethod(); |
| 567 | + return (Boolean) wfrp.invoke(null); |
| 568 | + } catch (IllegalAccessException e) { |
| 569 | + throw new RuntimeException("Shouldn't happen, we call setAccessible()", e); |
| 570 | + } catch (InvocationTargetException e) { |
| 571 | + Throwable cause = e.getCause(); |
| 572 | + if (cause instanceof InterruptedException) { |
| 573 | + throw (InterruptedException) cause; |
| 574 | + } else { |
| 575 | + throw new RuntimeException(e); |
| 576 | + } |
| 577 | + } |
| 578 | + } |
| 579 | + |
529 | 580 | // Returns true if the current GC supports concurrent collection control. |
530 | 581 | public native boolean supportsConcurrentGCBreakpoints(); |
531 | 582 |
|
|
0 commit comments