From 5c7f201af69a500b06a345f84a5b1ce550b605b2 Mon Sep 17 00:00:00 2001 From: Adam Farley Date: Wed, 21 Aug 2024 09:43:47 +0000 Subject: [PATCH] 8021775: compiler/8009761/Test8009761.java "Failed: init recursive calls: 51. After deopt 50" Reimplemented the test using the Whitebox API to deterministically trigger compilation and deoptimization. Now allowing number of recursive calls to vary by 1. Reviewed-by: sgehwolf Backport-of: 1ed4c8394859f6c36e165c4f59a6b5c9fbd793ee --- hotspot/test/TEST.groups | 1 + .../test/compiler/8009761/Test8009761.java | 68 +++++++++++++++---- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index c8767949707..c55ef8d17b9 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -153,6 +153,7 @@ hotspot_tier1 = \ # Tests that require compact3 API's # needs_compact3 = \ + compiler/8009761/Test8009761.java \ compiler/jsr292/RedefineMethodUsedByMultipleMethodHandles.java \ compiler/rangechecks/TestRangeCheckSmearing.java \ compiler/whitebox/DeoptimizeMethodTest.java \ diff --git a/hotspot/test/compiler/8009761/Test8009761.java b/hotspot/test/compiler/8009761/Test8009761.java index b41f49fd9b1..b6e021e3fec 100644 --- a/hotspot/test/compiler/8009761/Test8009761.java +++ b/hotspot/test/compiler/8009761/Test8009761.java @@ -21,19 +21,28 @@ * questions. */ +import com.sun.management.HotSpotDiagnosticMXBean; +import com.sun.management.VMOption; +import sun.hotspot.WhiteBox; +import sun.management.ManagementFactoryHelper; + +import java.lang.reflect.Method; + /* * @test * @bug 8009761 + * @library /testlibrary /testlibrary/whitebox * @summary Deoptimization on sparc doesn't set Llast_SP correctly in the interpreter frames it creates - * @run main/othervm -XX:CompileCommand=exclude,Test8009761::m2 -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -Xss512K Test8009761 - * + * @build Test8009761 + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=exclude,Test8009761::m2 -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -Xss512K Test8009761 */ public class Test8009761 { - static class UnloadedClass { - volatile int i; - } + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private static int COMP_LEVEL_FULL_OPTIMIZATION = 4; + private static Method m3 = null; static Object m1(boolean deopt) { // When running interpreted, on sparc, the caller's stack is @@ -142,9 +151,11 @@ static Object m1(boolean deopt) { ll508, ll509, ll510, ll511; if (deopt) { - UnloadedClass res = new UnloadedClass(); // sufficient to force deopt with c2 but not c1 - res.i = 0; // forces deopt with c1 - return res; + // Force deoptimization of m3 + WHITE_BOX.deoptimizeMethod(m3); + if(WHITE_BOX.isMethodCompiled(m3)) { + throw new RuntimeException(m3 + " not deoptimized"); + } } return null; } @@ -225,6 +236,18 @@ static Object m3(boolean overflow_stack, boolean deopt) { } static public void main(String[] args) { + // Make sure background compilation is disabled + if (backgroundCompilationEnabled()) { + throw new RuntimeException("Background compilation enabled"); + } + + try { + // Get Method object for m3 + m3 = Test8009761.class.getDeclaredMethod("m3", boolean.class, boolean.class); + } catch (NoSuchMethodException | SecurityException ex) { + throw new RuntimeException("Failed to retrieve method m3"); + } + int c1; // Call m2 from m3 recursively until stack overflow. Count the number of recursive calls. try { @@ -232,10 +255,14 @@ static public void main(String[] args) { } catch(StackOverflowError soe) { } c1 = count; + // Force the compilation of m3() that will inline m1() - for (int i = 0; i < 20000; i++) { - m3(false, false); + WHITE_BOX.enqueueMethodForCompilation(m3, COMP_LEVEL_FULL_OPTIMIZATION); + // Because background compilation is disabled, method should now be compiled + if(!WHITE_BOX.isMethodCompiled(m3)) { + throw new RuntimeException(m3 + " not compiled"); } + count = 0; // Force deoptimization of m3() in m1(), then return from m1() // to m3(), call recursively m2(). If deoptimization correctly @@ -245,11 +272,26 @@ static public void main(String[] args) { m3(false, true); } catch(StackOverflowError soe) { } - if (c1 != count) { - System.out.println("Failed: init recursive calls: " + c1 + ". After deopt " + count); - System.exit(97); + // Allow number of recursive calls to vary by 1 + if ((c1 < (count - 1)) || (c1 > (count + 1))) { + throw new RuntimeException("Failed: init recursive calls: " + c1 + ". After deopt " + count); } else { System.out.println("PASSED " + c1); } } + + /** + * Checks if background compilation (-XX:+BackgroundCompilation) is enabled. + * @return True if background compilation is enabled, false otherwise + */ + private static boolean backgroundCompilationEnabled() { + HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); + VMOption backgroundCompilation; + try { + backgroundCompilation = diagnostic.getVMOption("BackgroundCompilation"); + } catch (IllegalArgumentException e) { + return false; + } + return Boolean.valueOf(backgroundCompilation.getValue()); + } }