# HG changeset patch # User iignatyev # Date 1366131841 25200 # Node ID 4b2eebe03f93de149b45d5bee81bfc3d41cb574e # Parent c89eab0b6b30056b30f9f99ae15f43f93bcdf7f2 8011971: WB API doesn't accept j.l.reflect.Constructor Reviewed-by: kvn, vlivanov diff -r c89eab0b6b30 -r 4b2eebe03f93 src/share/vm/prims/whitebox.cpp --- a/src/share/vm/prims/whitebox.cpp Tue Apr 16 10:37:16 2013 -0400 +++ b/src/share/vm/prims/whitebox.cpp Tue Apr 16 10:04:01 2013 -0700 @@ -237,10 +237,10 @@ WB_END -WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method)) +WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level)) jmethodID jmid = reflected_method_to_jmid(thread, env, method); methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); - mh->set_not_compilable(); + mh->set_not_compilable(comp_level, true /* report */, "WhiteBox"); WB_END WB_ENTRY(jboolean, WB_TestSetDontInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value)) @@ -398,28 +398,28 @@ {CC"NMTWaitForDataMerge", CC"()Z", (void*)&WB_NMTWaitForDataMerge}, #endif // INCLUDE_NMT {CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll }, - {CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Method;)I", + {CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;)I", (void*)&WB_DeoptimizeMethod }, - {CC"isMethodCompiled", CC"(Ljava/lang/reflect/Method;)Z", + {CC"isMethodCompiled", CC"(Ljava/lang/reflect/Executable;)Z", (void*)&WB_IsMethodCompiled }, - {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Method;I)Z", + {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Executable;I)Z", (void*)&WB_IsMethodCompilable}, {CC"isMethodQueuedForCompilation", - CC"(Ljava/lang/reflect/Method;)Z", (void*)&WB_IsMethodQueuedForCompilation}, + CC"(Ljava/lang/reflect/Executable;)Z", (void*)&WB_IsMethodQueuedForCompilation}, {CC"makeMethodNotCompilable", - CC"(Ljava/lang/reflect/Method;)V", (void*)&WB_MakeMethodNotCompilable}, + CC"(Ljava/lang/reflect/Executable;I)V", (void*)&WB_MakeMethodNotCompilable}, {CC"testSetDontInlineMethod", - CC"(Ljava/lang/reflect/Method;Z)Z", (void*)&WB_TestSetDontInlineMethod}, + CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetDontInlineMethod}, {CC"getMethodCompilationLevel", - CC"(Ljava/lang/reflect/Method;)I", (void*)&WB_GetMethodCompilationLevel}, + CC"(Ljava/lang/reflect/Executable;)I", (void*)&WB_GetMethodCompilationLevel}, {CC"getCompileQueuesSize", CC"()I", (void*)&WB_GetCompileQueuesSize}, {CC"testSetForceInlineMethod", - CC"(Ljava/lang/reflect/Method;Z)Z", (void*)&WB_TestSetForceInlineMethod}, + CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetForceInlineMethod}, {CC"enqueueMethodForCompilation", - CC"(Ljava/lang/reflect/Method;I)Z", (void*)&WB_EnqueueMethodForCompilation}, + CC"(Ljava/lang/reflect/Executable;I)Z", (void*)&WB_EnqueueMethodForCompilation}, {CC"clearMethodState", - CC"(Ljava/lang/reflect/Method;)V", (void*)&WB_ClearMethodState}, + CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState}, {CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable }, {CC"fullGC", CC"()V", (void*)&WB_FullGC }, }; diff -r c89eab0b6b30 -r 4b2eebe03f93 test/compiler/whitebox/ClearMethodStateTest.java --- a/test/compiler/whitebox/ClearMethodStateTest.java Tue Apr 16 10:37:16 2013 -0400 +++ b/test/compiler/whitebox/ClearMethodStateTest.java Tue Apr 16 10:04:01 2013 -0700 @@ -27,42 +27,61 @@ * @build ClearMethodStateTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ClearMethodStateTest + * @summary testing of WB::clearMethodState() * @author igor.ignatyev@oracle.com */ public class ClearMethodStateTest extends CompilerWhiteBoxTest { + public static void main(String[] args) throws Exception { - // to prevent inlining #method into #compile() and #test() - WHITE_BOX.testSetDontInlineMethod(METHOD, true); - new ClearMethodStateTest().runTest(); + for (TestCase test : TestCase.values()) { + new ClearMethodStateTest(test).runTest(); + } + } + + public ClearMethodStateTest(TestCase testCase) { + super(testCase); + // to prevent inlining of #method + WHITE_BOX.testSetDontInlineMethod(method, true); } + + /** + * Tests {@code WB::clearMethodState()} by calling it before/after + * compilation. For non-tiered, checks that counters will be rested after + * clearing of method state. + * + * @throws Exception if one of the checks fails. + */ + @Override protected void test() throws Exception { - checkNotCompiled(METHOD); + checkNotCompiled(); compile(); - checkCompiled(METHOD); - WHITE_BOX.clearMethodState(METHOD); - WHITE_BOX.deoptimizeMethod(METHOD); - checkNotCompiled(METHOD); + WHITE_BOX.clearMethodState(method); + checkCompiled(); + WHITE_BOX.clearMethodState(method); + WHITE_BOX.deoptimizeMethod(method); + checkNotCompiled(); if (!TIERED_COMPILATION) { - WHITE_BOX.clearMethodState(METHOD); + WHITE_BOX.clearMethodState(method); compile(COMPILE_THRESHOLD); - checkCompiled(METHOD); + checkCompiled(); - WHITE_BOX.deoptimizeMethod(METHOD); - checkNotCompiled(METHOD); - WHITE_BOX.clearMethodState(METHOD); + WHITE_BOX.deoptimizeMethod(method); + checkNotCompiled(); + WHITE_BOX.clearMethodState(method); + // invoke method one less time than needed to compile if (COMPILE_THRESHOLD > 1) { compile(COMPILE_THRESHOLD - 1); - checkNotCompiled(METHOD); + checkNotCompiled(); } else { - System.err.println("Warning: 'CompileThreshold' <= 1"); + System.err.println("Warning: 'CompileThreshold' <= 1"); } - method(); - checkCompiled(METHOD); + compile(1); + checkCompiled(); } else { System.err.println( "Warning: part of test is not applicable in Tiered"); diff -r c89eab0b6b30 -r 4b2eebe03f93 test/compiler/whitebox/CompilerWhiteBoxTest.java --- a/test/compiler/whitebox/CompilerWhiteBoxTest.java Tue Apr 16 10:37:16 2013 -0400 +++ b/test/compiler/whitebox/CompilerWhiteBoxTest.java Tue Apr 16 10:04:01 2013 -0700 @@ -21,68 +21,132 @@ * questions. */ +import com.sun.management.HotSpotDiagnosticMXBean; +import com.sun.management.VMOption; import sun.hotspot.WhiteBox; import sun.management.ManagementFactoryHelper; -import com.sun.management.HotSpotDiagnosticMXBean; +import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; import java.lang.reflect.Method; +import java.util.Objects; +import java.util.concurrent.Callable; -/* +/** + * Abstract class for WhiteBox testing of JIT. + * * @author igor.ignatyev@oracle.com */ public abstract class CompilerWhiteBoxTest { + /** {@code CompLevel::CompLevel_none} -- Interpreter */ + protected static int COMP_LEVEL_NONE = 0; + /** {@code CompLevel::CompLevel_any}, {@code CompLevel::CompLevel_all} */ + protected static int COMP_LEVEL_ANY = -1; + /** Instance of WhiteBox */ protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); - protected static final Method METHOD = getMethod("method"); + /** Value of {@code -XX:CompileThreshold} */ protected static final int COMPILE_THRESHOLD = Integer.parseInt(getVMOption("CompileThreshold", "10000")); + /** Value of {@code -XX:BackgroundCompilation} */ protected static final boolean BACKGROUND_COMPILATION = Boolean.valueOf(getVMOption("BackgroundCompilation", "true")); + /** Value of {@code -XX:TieredCompilation} */ protected static final boolean TIERED_COMPILATION = Boolean.valueOf(getVMOption("TieredCompilation", "false")); + /** Value of {@code -XX:TieredStopAtLevel} */ + protected static final int TIERED_STOP_AT_LEVEL + = Integer.parseInt(getVMOption("TieredStopAtLevel", "0")); - protected static Method getMethod(String name) { + /** + * Returns value of VM option. + * + * @param name option's name + * @return value of option or {@code null}, if option doesn't exist + * @throws NullPointerException if name is null + */ + protected static String getVMOption(String name) { + Objects.requireNonNull(name); + HotSpotDiagnosticMXBean diagnostic + = ManagementFactoryHelper.getDiagnosticMXBean(); + VMOption tmp; try { - return CompilerWhiteBoxTest.class.getDeclaredMethod(name); - } catch (NoSuchMethodException | SecurityException e) { - throw new RuntimeException( - "exception on getting method " + name, e); + tmp = diagnostic.getVMOption(name); + } catch (IllegalArgumentException e) { + tmp = null; } + return (tmp == null ? null : tmp.getValue()); } - protected static String getVMOption(String name) { - String result; - HotSpotDiagnosticMXBean diagnostic - = ManagementFactoryHelper.getDiagnosticMXBean(); - result = diagnostic.getVMOption(name).getValue(); - return result; - } - + /** + * Returns value of VM option or default value. + * + * @param name option's name + * @param defaultValue default value + * @return value of option or {@code defaultValue}, if option doesn't exist + * @throws NullPointerException if name is null + * @see #getVMOption(String) + */ protected static String getVMOption(String name, String defaultValue) { String result = getVMOption(name); return result == null ? defaultValue : result; } - protected final void runTest() throws RuntimeException { + /** tested method */ + protected final Executable method; + private final Callable callable; + + /** + * Constructor. + * + * @param testCase object, that contains tested method and way to invoke it. + */ + protected CompilerWhiteBoxTest(TestCase testCase) { + Objects.requireNonNull(testCase); + System.out.println("TEST CASE:" + testCase.name()); + method = testCase.executable; + callable = testCase.callable; + } + + /** + * Template method for testing. Prints tested method's info before + * {@linkplain #test()} and after {@linkplain #test()} or on thrown + * exception. + * + * @throws RuntimeException if method {@linkplain #test()} throws any + * exception + * @see #test() + */ + protected final void runTest() { if (ManagementFactoryHelper.getCompilationMXBean() == null) { System.err.println( "Warning: test is not applicable in interpreted mode"); return; } System.out.println("at test's start:"); - printInfo(METHOD); + printInfo(); try { test(); } catch (Exception e) { System.out.printf("on exception '%s':", e.getMessage()); - printInfo(METHOD); + printInfo(); e.printStackTrace(); + if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } throw new RuntimeException(e); } System.out.println("at test's end:"); - printInfo(METHOD); + printInfo(); } - protected static void checkNotCompiled(Method method) { + /** + * Checks, that {@linkplain #method} is not compiled. + * + * @throws RuntimeException if {@linkplain #method} is in compiler queue or + * is compiled, or if {@linkplain #method} has zero + * compilation level. + */ + protected final void checkNotCompiled() { if (WHITE_BOX.isMethodQueuedForCompilation(method)) { throw new RuntimeException(method + " must not be in queue"); } @@ -94,10 +158,16 @@ } } - protected static void checkCompiled(Method method) - throws InterruptedException { + /** + * Checks, that {@linkplain #method} is compiled. + * + * @throws RuntimeException if {@linkplain #method} isn't in compiler queue + * and isn't compiled, or if {@linkplain #method} + * has nonzero compilation level + */ + protected final void checkCompiled() { final long start = System.currentTimeMillis(); - waitBackgroundCompilation(method); + waitBackgroundCompilation(); if (WHITE_BOX.isMethodQueuedForCompilation(method)) { System.err.printf("Warning: %s is still in queue after %dms%n", method, System.currentTimeMillis() - start); @@ -111,23 +181,30 @@ } } - protected static void waitBackgroundCompilation(Method method) - throws InterruptedException { + /** + * Waits for completion of background compilation of {@linkplain #method}. + */ + protected final void waitBackgroundCompilation() { if (!BACKGROUND_COMPILATION) { return; } final Object obj = new Object(); - synchronized (obj) { - for (int i = 0; i < 10; ++i) { - if (!WHITE_BOX.isMethodQueuedForCompilation(method)) { - break; + for (int i = 0; i < 10 + && WHITE_BOX.isMethodQueuedForCompilation(method); ++i) { + synchronized (obj) { + try { + obj.wait(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); } - obj.wait(1000); } } } - protected static void printInfo(Method method) { + /** + * Prints information about {@linkplain #method}. + */ + protected final void printInfo() { System.out.printf("%n%s:%n", method); System.out.printf("\tcompilable:\t%b%n", WHITE_BOX.isMethodCompilable(method)); @@ -141,22 +218,139 @@ WHITE_BOX.getCompileQueuesSize()); } + /** + * Executes testing. + */ protected abstract void test() throws Exception; + /** + * Tries to trigger compilation of {@linkplain #method} by call + * {@linkplain #callable} enough times. + * + * @return accumulated result + * @see #compile(int) + */ protected final int compile() { return compile(Math.max(COMPILE_THRESHOLD, 150000)); } + /** + * Tries to trigger compilation of {@linkplain #method} by call + * {@linkplain #callable} specified times. + * + * @param count invocation count + * @return accumulated result + */ protected final int compile(int count) { int result = 0; + Integer tmp; for (int i = 0; i < count; ++i) { - result += method(); + try { + tmp = callable.call(); + } catch (Exception e) { + tmp = null; + } + result += tmp == null ? 0 : tmp; } System.out.println("method was invoked " + count + " times"); return result; } +} - protected int method() { - return 42; +/** + * Utility structure containing tested method and object to invoke it. + */ +enum TestCase { + /** constructor test case */ + CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE), + /** method test case */ + METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE), + /** static method test case */ + STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE); + + /** tested method */ + final Executable executable; + /** object to invoke {@linkplain #executable} */ + final Callable callable; + + private TestCase(Executable executable, Callable callable) { + this.executable = executable; + this.callable = callable; + } + + private static class Helper { + private static final Callable CONSTRUCTOR_CALLABLE + = new Callable() { + @Override + public Integer call() throws Exception { + return new Helper(1337).hashCode(); + } + }; + + private static final Callable METHOD_CALLABLE + = new Callable() { + private final Helper helper = new Helper(); + + @Override + public Integer call() throws Exception { + return helper.method(); + } + }; + + private static final Callable STATIC_CALLABLE + = new Callable() { + @Override + public Integer call() throws Exception { + return staticMethod(); + } + }; + + private static final Constructor CONSTRUCTOR; + private static final Method METHOD; + private static final Method STATIC; + + static { + try { + CONSTRUCTOR = Helper.class.getDeclaredConstructor(int.class); + } catch (NoSuchMethodException | SecurityException e) { + throw new RuntimeException( + "exception on getting method Helper.(int)", e); + } + try { + METHOD = Helper.class.getDeclaredMethod("method"); + } catch (NoSuchMethodException | SecurityException e) { + throw new RuntimeException( + "exception on getting method Helper.method()", e); + } + try { + STATIC = Helper.class.getDeclaredMethod("staticMethod"); + } catch (NoSuchMethodException | SecurityException e) { + throw new RuntimeException( + "exception on getting method Helper.staticMethod()", e); + } + } + + private static int staticMethod() { + return 1138; + } + + private int method() { + return 42; + } + + private final int x; + + public Helper() { + x = 0; + } + + private Helper(int x) { + this.x = x; + } + + @Override + public int hashCode() { + return x; + } } } diff -r c89eab0b6b30 -r 4b2eebe03f93 test/compiler/whitebox/DeoptimizeAllTest.java --- a/test/compiler/whitebox/DeoptimizeAllTest.java Tue Apr 16 10:37:16 2013 -0400 +++ b/test/compiler/whitebox/DeoptimizeAllTest.java Tue Apr 16 10:04:01 2013 -0700 @@ -27,20 +27,34 @@ * @build DeoptimizeAllTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeAllTest + * @summary testing of WB::deoptimizeAll() * @author igor.ignatyev@oracle.com */ public class DeoptimizeAllTest extends CompilerWhiteBoxTest { public static void main(String[] args) throws Exception { - // to prevent inlining #method into #compile() - WHITE_BOX.testSetDontInlineMethod(METHOD, true); - new DeoptimizeAllTest().runTest(); + for (TestCase test : TestCase.values()) { + new DeoptimizeAllTest(test).runTest(); + } + } + + public DeoptimizeAllTest(TestCase testCase) { + super(testCase); + // to prevent inlining of #method + WHITE_BOX.testSetDontInlineMethod(method, true); } + /** + * Tests {@code WB::deoptimizeAll()} by calling it after + * compilation and checking that method isn't compiled. + * + * @throws Exception if one of the checks fails. + */ + @Override protected void test() throws Exception { compile(); - checkCompiled(METHOD); + checkCompiled(); WHITE_BOX.deoptimizeAll(); - checkNotCompiled(METHOD); + checkNotCompiled(); } } diff -r c89eab0b6b30 -r 4b2eebe03f93 test/compiler/whitebox/DeoptimizeMethodTest.java --- a/test/compiler/whitebox/DeoptimizeMethodTest.java Tue Apr 16 10:37:16 2013 -0400 +++ b/test/compiler/whitebox/DeoptimizeMethodTest.java Tue Apr 16 10:04:01 2013 -0700 @@ -27,20 +27,34 @@ * @build DeoptimizeMethodTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeMethodTest + * @summary testing of WB::deoptimizeMethod() * @author igor.ignatyev@oracle.com */ public class DeoptimizeMethodTest extends CompilerWhiteBoxTest { public static void main(String[] args) throws Exception { - // to prevent inlining #method into #compile() - WHITE_BOX.testSetDontInlineMethod(METHOD, true); - new DeoptimizeMethodTest().runTest(); + for (TestCase test : TestCase.values()) { + new DeoptimizeMethodTest(test).runTest(); + } + } + + public DeoptimizeMethodTest(TestCase testCase) { + super(testCase); + // to prevent inlining of #method + WHITE_BOX.testSetDontInlineMethod(method, true); } + /** + * Tests {@code WB::deoptimizeMethod()} by calling it after + * compilation and checking that method isn't compiled. + * + * @throws Exception if one of the checks fails. + */ + @Override protected void test() throws Exception { compile(); - checkCompiled(METHOD); - WHITE_BOX.deoptimizeMethod(METHOD); - checkNotCompiled(METHOD); + checkCompiled(); + WHITE_BOX.deoptimizeMethod(method); + checkNotCompiled(); } } diff -r c89eab0b6b30 -r 4b2eebe03f93 test/compiler/whitebox/EnqueueMethodForCompilationTest.java --- a/test/compiler/whitebox/EnqueueMethodForCompilationTest.java Tue Apr 16 10:37:16 2013 -0400 +++ b/test/compiler/whitebox/EnqueueMethodForCompilationTest.java Tue Apr 16 10:04:01 2013 -0700 @@ -27,48 +27,60 @@ * @build EnqueueMethodForCompilationTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI EnqueueMethodForCompilationTest + * @summary testing of WB::enqueueMethodForCompilation() * @author igor.ignatyev@oracle.com */ public class EnqueueMethodForCompilationTest extends CompilerWhiteBoxTest { + public static void main(String[] args) throws Exception { - // to prevent inlining #method into #compile() - WHITE_BOX.testSetDontInlineMethod(METHOD, true); - new EnqueueMethodForCompilationTest().runTest(); + for (TestCase test : TestCase.values()) { + new EnqueueMethodForCompilationTest(test).runTest(); + } + } + + public EnqueueMethodForCompilationTest(TestCase testCase) { + super(testCase); + // to prevent inlining of #method + WHITE_BOX.testSetDontInlineMethod(method, true); } + @Override protected void test() throws Exception { - checkNotCompiled(METHOD); + checkNotCompiled(); - WHITE_BOX.enqueueMethodForCompilation(METHOD, 0); - if (WHITE_BOX.isMethodCompilable(METHOD, 0)) { - throw new RuntimeException(METHOD + " is compilable at level 0"); + // method can not be compiled on level 'none' + WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_NONE); + if (WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_NONE)) { + throw new RuntimeException(method + + " is compilable at level COMP_LEVEL_NONE"); } - checkNotCompiled(METHOD); + checkNotCompiled(); - WHITE_BOX.enqueueMethodForCompilation(METHOD, -1); - checkNotCompiled(METHOD); + // COMP_LEVEL_ANY is inapplicable as level for compilation + WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_ANY); + checkNotCompiled(); - WHITE_BOX.enqueueMethodForCompilation(METHOD, 5); - if (!WHITE_BOX.isMethodCompilable(METHOD, 5)) { - checkNotCompiled(METHOD); - compile(); - checkCompiled(METHOD); + WHITE_BOX.enqueueMethodForCompilation(method, 5); + if (!WHITE_BOX.isMethodCompilable(method, 5)) { + checkNotCompiled(); + compile(); + checkCompiled(); } else { - checkCompiled(METHOD); + checkCompiled(); } - int compLevel = WHITE_BOX.getMethodCompilationLevel(METHOD); - WHITE_BOX.deoptimizeMethod(METHOD); - checkNotCompiled(METHOD); + int compLevel = WHITE_BOX.getMethodCompilationLevel(method); + WHITE_BOX.deoptimizeMethod(method); + checkNotCompiled(); - WHITE_BOX.enqueueMethodForCompilation(METHOD, compLevel); - checkCompiled(METHOD); - WHITE_BOX.deoptimizeMethod(METHOD); - checkNotCompiled(METHOD); + WHITE_BOX.enqueueMethodForCompilation(method, compLevel); + checkCompiled(); + WHITE_BOX.deoptimizeMethod(method); + checkNotCompiled(); compile(); - checkCompiled(METHOD); - WHITE_BOX.deoptimizeMethod(METHOD); - checkNotCompiled(METHOD); + checkCompiled(); + WHITE_BOX.deoptimizeMethod(method); + checkNotCompiled(); } } diff -r c89eab0b6b30 -r 4b2eebe03f93 test/compiler/whitebox/IsMethodCompilableTest.java --- a/test/compiler/whitebox/IsMethodCompilableTest.java Tue Apr 16 10:37:16 2013 -0400 +++ b/test/compiler/whitebox/IsMethodCompilableTest.java Tue Apr 16 10:04:01 2013 -0700 @@ -28,9 +28,13 @@ * @build IsMethodCompilableTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI IsMethodCompilableTest + * @summary testing of WB::isMethodCompilable() * @author igor.ignatyev@oracle.com */ public class IsMethodCompilableTest extends CompilerWhiteBoxTest { + /** + * Value of {@code -XX:PerMethodRecompilationCutoff} + */ protected static final long PER_METHOD_RECOMPILATION_CUTOFF; static { @@ -44,14 +48,28 @@ } public static void main(String[] args) throws Exception { - // to prevent inlining #method into #compile() - WHITE_BOX.testSetDontInlineMethod(METHOD, true); - new IsMethodCompilableTest().runTest(); + for (TestCase test : TestCase.values()) { + new IsMethodCompilableTest(test).runTest(); + } + } + + public IsMethodCompilableTest(TestCase testCase) { + super(testCase); + // to prevent inlining of #method + WHITE_BOX.testSetDontInlineMethod(method, true); } + /** + * Tests {@code WB::isMethodCompilable()} by recompilation of tested method + * 'PerMethodRecompilationCutoff' times and checks compilation status. Also + * checks that WB::clearMethodState() clears no-compilable flags. + * + * @throws Exception if one of the checks fails. + */ + @Override protected void test() throws Exception { - if (!WHITE_BOX.isMethodCompilable(METHOD)) { - throw new RuntimeException(METHOD + " must be compilable"); + if (!WHITE_BOX.isMethodCompilable(method)) { + throw new RuntimeException(method + " must be compilable"); } System.out.println("PerMethodRecompilationCutoff = " + PER_METHOD_RECOMPILATION_CUTOFF); @@ -61,46 +79,47 @@ return; } - // deoptimze 'PerMethodRecompilationCutoff' times and clear state + // deoptimize 'PerMethodRecompilationCutoff' times and clear state for (long i = 0L, n = PER_METHOD_RECOMPILATION_CUTOFF - 1; i < n; ++i) { - compileAndDeoptimaze(); + compileAndDeoptimize(); } - if (!WHITE_BOX.isMethodCompilable(METHOD)) { - throw new RuntimeException(METHOD + " is not compilable after " + if (!WHITE_BOX.isMethodCompilable(method)) { + throw new RuntimeException(method + " is not compilable after " + (PER_METHOD_RECOMPILATION_CUTOFF - 1) + " iterations"); } - WHITE_BOX.clearMethodState(METHOD); + WHITE_BOX.clearMethodState(method); - // deoptimze 'PerMethodRecompilationCutoff' + 1 times + // deoptimize 'PerMethodRecompilationCutoff' + 1 times long i; for (i = 0L; i < PER_METHOD_RECOMPILATION_CUTOFF - && WHITE_BOX.isMethodCompilable(METHOD); ++i) { - compileAndDeoptimaze(); + && WHITE_BOX.isMethodCompilable(method); ++i) { + compileAndDeoptimize(); } if (i != PER_METHOD_RECOMPILATION_CUTOFF) { - throw new RuntimeException(METHOD + " is not compilable after " - + i + " iterations, but must only after " - + PER_METHOD_RECOMPILATION_CUTOFF); + throw new RuntimeException(method + " is not compilable after " + + i + " iterations, but must only after " + + PER_METHOD_RECOMPILATION_CUTOFF); } - if (WHITE_BOX.isMethodCompilable(METHOD)) { - throw new RuntimeException(METHOD + " is still compilable after " + if (WHITE_BOX.isMethodCompilable(method)) { + throw new RuntimeException(method + " is still compilable after " + PER_METHOD_RECOMPILATION_CUTOFF + " iterations"); } compile(); - checkNotCompiled(METHOD); + checkNotCompiled(); - WHITE_BOX.clearMethodState(METHOD); - if (!WHITE_BOX.isMethodCompilable(METHOD)) { - throw new RuntimeException(METHOD - + " is compilable after clearMethodState()"); + // WB.clearMethodState() must reset no-compilable flags + WHITE_BOX.clearMethodState(method); + if (!WHITE_BOX.isMethodCompilable(method)) { + throw new RuntimeException(method + + " is not compilable after clearMethodState()"); } compile(); - checkCompiled(METHOD); + checkCompiled(); } - private void compileAndDeoptimaze() throws Exception { + private void compileAndDeoptimize() throws Exception { compile(); - waitBackgroundCompilation(METHOD); - WHITE_BOX.deoptimizeMethod(METHOD); + waitBackgroundCompilation(); + WHITE_BOX.deoptimizeMethod(method); } } diff -r c89eab0b6b30 -r 4b2eebe03f93 test/compiler/whitebox/MakeMethodNotCompilableTest.java --- a/test/compiler/whitebox/MakeMethodNotCompilableTest.java Tue Apr 16 10:37:16 2013 -0400 +++ b/test/compiler/whitebox/MakeMethodNotCompilableTest.java Tue Apr 16 10:04:01 2013 -0700 @@ -27,28 +27,85 @@ * @build MakeMethodNotCompilableTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI MakeMethodNotCompilableTest + * @summary testing of WB::makeMethodNotCompilable() * @author igor.ignatyev@oracle.com */ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest { public static void main(String[] args) throws Exception { - // to prevent inlining #method into #compile() - WHITE_BOX.testSetDontInlineMethod(METHOD, true); - new MakeMethodNotCompilableTest().runTest(); + if (args.length == 0) { + for (TestCase test : TestCase.values()) { + new MakeMethodNotCompilableTest(test).runTest(); + } + } else { + for (String name : args) { + new MakeMethodNotCompilableTest( + TestCase.valueOf(name)).runTest(); + } + } + } + + public MakeMethodNotCompilableTest(TestCase testCase) { + super(testCase); + // to prevent inlining of #method + WHITE_BOX.testSetDontInlineMethod(method, true); } - protected void test() throws Exception { - if (!WHITE_BOX.isMethodCompilable(METHOD)) { - throw new RuntimeException(METHOD + " must be compilable"); + /** + * Tests {@code WB::makeMethodNotCompilable()} by calling it before + * compilation and checking that method isn't compiled. Also + * checks that WB::clearMethodState() clears no-compilable flags. For + * tiered, additional checks for all available levels are conducted. + * + * @throws Exception if one of the checks fails. + */ + @Override + protected void test() throws Exception { + checkNotCompiled(); + if (!WHITE_BOX.isMethodCompilable(method)) { + throw new RuntimeException(method + " must be compilable"); } - WHITE_BOX.makeMethodNotCompilable(METHOD); - if (WHITE_BOX.isMethodCompilable(METHOD)) { - throw new RuntimeException(METHOD + " must be not compilable"); + + if (TIERED_COMPILATION) { + for (int i = 1, n = TIERED_STOP_AT_LEVEL + 1; i < n; ++i) { + WHITE_BOX.makeMethodNotCompilable(method, i); + if (WHITE_BOX.isMethodCompilable(method, i)) { + throw new RuntimeException(method + + " must be not compilable at level" + i); + } + WHITE_BOX.enqueueMethodForCompilation(method, i); + checkNotCompiled(); + + if (!WHITE_BOX.isMethodCompilable(method)) { + System.out.println(method + + " is not compilable after level " + i); + } + } + + // WB.clearMethodState() must reset no-compilable flags + WHITE_BOX.clearMethodState(method); + if (!WHITE_BOX.isMethodCompilable(method)) { + throw new RuntimeException(method + + " is not compilable after clearMethodState()"); + } + } + WHITE_BOX.makeMethodNotCompilable(method); + if (WHITE_BOX.isMethodCompilable(method)) { + throw new RuntimeException(method + " must be not compilable"); + } + + compile(); + checkNotCompiled(); + if (WHITE_BOX.isMethodCompilable(method)) { + throw new RuntimeException(method + " must be not compilable"); + } + // WB.clearMethodState() must reset no-compilable flags + WHITE_BOX.clearMethodState(method); + if (!WHITE_BOX.isMethodCompilable(method)) { + throw new RuntimeException(method + + " is not compilable after clearMethodState()"); } compile(); - checkNotCompiled(METHOD); - if (WHITE_BOX.isMethodCompilable(METHOD)) { - throw new RuntimeException(METHOD + " must be not compilable"); - } + checkCompiled(); } } diff -r c89eab0b6b30 -r 4b2eebe03f93 test/compiler/whitebox/SetDontInlineMethodTest.java --- a/test/compiler/whitebox/SetDontInlineMethodTest.java Tue Apr 16 10:37:16 2013 -0400 +++ b/test/compiler/whitebox/SetDontInlineMethodTest.java Tue Apr 16 10:04:01 2013 -0700 @@ -27,33 +27,47 @@ * @build SetDontInlineMethodTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetDontInlineMethodTest + * @summary testing of WB::testSetDontInlineMethod() * @author igor.ignatyev@oracle.com */ public class SetDontInlineMethodTest extends CompilerWhiteBoxTest { public static void main(String[] args) throws Exception { - new SetDontInlineMethodTest().runTest(); + for (TestCase test : TestCase.values()) { + new SetDontInlineMethodTest(test).runTest(); + } + } + + public SetDontInlineMethodTest(TestCase testCase) { + super(testCase); } + /** + * Tests {@code WB::testSetDontInlineMethod()} by sequential calling it and + * checking of return value. + * + * @throws Exception if one of the checks fails. + */ + @Override protected void test() throws Exception { - if (WHITE_BOX.testSetDontInlineMethod(METHOD, true)) { - throw new RuntimeException("on start " + METHOD + if (WHITE_BOX.testSetDontInlineMethod(method, true)) { + throw new RuntimeException("on start " + method + " must be inlineable"); } - if (!WHITE_BOX.testSetDontInlineMethod(METHOD, true)) { - throw new RuntimeException("after first change to true " + METHOD + if (!WHITE_BOX.testSetDontInlineMethod(method, true)) { + throw new RuntimeException("after first change to true " + method + " must be not inlineable"); } - if (!WHITE_BOX.testSetDontInlineMethod(METHOD, false)) { - throw new RuntimeException("after second change to true " + METHOD + if (!WHITE_BOX.testSetDontInlineMethod(method, false)) { + throw new RuntimeException("after second change to true " + method + " must be still not inlineable"); } - if (WHITE_BOX.testSetDontInlineMethod(METHOD, false)) { - throw new RuntimeException("after first change to false" + METHOD + if (WHITE_BOX.testSetDontInlineMethod(method, false)) { + throw new RuntimeException("after first change to false" + method + " must be inlineable"); } - if (WHITE_BOX.testSetDontInlineMethod(METHOD, false)) { - throw new RuntimeException("after second change to false " + METHOD + if (WHITE_BOX.testSetDontInlineMethod(method, false)) { + throw new RuntimeException("after second change to false " + method + " must be inlineable"); } } diff -r c89eab0b6b30 -r 4b2eebe03f93 test/compiler/whitebox/SetForceInlineMethodTest.java --- a/test/compiler/whitebox/SetForceInlineMethodTest.java Tue Apr 16 10:37:16 2013 -0400 +++ b/test/compiler/whitebox/SetForceInlineMethodTest.java Tue Apr 16 10:04:01 2013 -0700 @@ -27,33 +27,47 @@ * @build SetForceInlineMethodTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetForceInlineMethodTest + * @summary testing of WB::testSetForceInlineMethod() * @author igor.ignatyev@oracle.com */ public class SetForceInlineMethodTest extends CompilerWhiteBoxTest { public static void main(String[] args) throws Exception { - new SetForceInlineMethodTest().runTest(); + for (TestCase test : TestCase.values()) { + new SetForceInlineMethodTest(test).runTest(); + } + } + + public SetForceInlineMethodTest(TestCase testCase) { + super(testCase); } + /** + * Tests {@code WB::testSetForceInlineMethod()} by sequential calling it and + * checking of return value. + * + * @throws Exception if one of the checks fails. + */ + @Override protected void test() throws Exception { - if (WHITE_BOX.testSetForceInlineMethod(METHOD, true)) { - throw new RuntimeException("on start " + METHOD + if (WHITE_BOX.testSetForceInlineMethod(method, true)) { + throw new RuntimeException("on start " + method + " must be not force inlineable"); } - if (!WHITE_BOX.testSetForceInlineMethod(METHOD, true)) { - throw new RuntimeException("after first change to true " + METHOD + if (!WHITE_BOX.testSetForceInlineMethod(method, true)) { + throw new RuntimeException("after first change to true " + method + " must be force inlineable"); } - if (!WHITE_BOX.testSetForceInlineMethod(METHOD, false)) { - throw new RuntimeException("after second change to true " + METHOD + if (!WHITE_BOX.testSetForceInlineMethod(method, false)) { + throw new RuntimeException("after second change to true " + method + " must be still force inlineable"); } - if (WHITE_BOX.testSetForceInlineMethod(METHOD, false)) { - throw new RuntimeException("after first change to false" + METHOD + if (WHITE_BOX.testSetForceInlineMethod(method, false)) { + throw new RuntimeException("after first change to false" + method + " must be not force inlineable"); } - if (WHITE_BOX.testSetForceInlineMethod(METHOD, false)) { - throw new RuntimeException("after second change to false " + METHOD + if (WHITE_BOX.testSetForceInlineMethod(method, false)) { + throw new RuntimeException("after second change to false " + method + " must be not force inlineable"); } } diff -r c89eab0b6b30 -r 4b2eebe03f93 test/testlibrary/whitebox/sun/hotspot/WhiteBox.java --- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Tue Apr 16 10:37:16 2013 -0400 +++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Tue Apr 16 10:04:01 2013 -0700 @@ -24,7 +24,7 @@ package sun.hotspot; -import java.lang.reflect.Method; +import java.lang.reflect.Executable; import java.security.BasicPermission; import sun.hotspot.parser.DiagnosticCommand; @@ -90,22 +90,25 @@ // Compiler public native void deoptimizeAll(); - public native boolean isMethodCompiled(Method method); - public boolean isMethodCompilable(Method method) { + public native boolean isMethodCompiled(Executable method); + public boolean isMethodCompilable(Executable method) { return isMethodCompilable(method, -1 /*any*/); } - public native boolean isMethodCompilable(Method method, int compLevel); - public native boolean isMethodQueuedForCompilation(Method method); - public native int deoptimizeMethod(Method method); - public native void makeMethodNotCompilable(Method method); - public native int getMethodCompilationLevel(Method method); - public native boolean testSetDontInlineMethod(Method method, boolean value); + public native boolean isMethodCompilable(Executable method, int compLevel); + public native boolean isMethodQueuedForCompilation(Executable method); + public native int deoptimizeMethod(Executable method); + public void makeMethodNotCompilable(Executable method) { + makeMethodNotCompilable(method, -1 /*any*/); + } + public native void makeMethodNotCompilable(Executable method, int compLevel); + public native int getMethodCompilationLevel(Executable method); + public native boolean testSetDontInlineMethod(Executable method, boolean value); public native int getCompileQueuesSize(); - public native boolean testSetForceInlineMethod(Method method, boolean value); - public native boolean enqueueMethodForCompilation(Method method, int compLevel); - public native void clearMethodState(Method method); + public native boolean testSetForceInlineMethod(Executable method, boolean value); + public native boolean enqueueMethodForCompilation(Executable method, int compLevel); + public native void clearMethodState(Executable method); - //Intered strings + // Intered strings public native boolean isInStringTable(String str); // force Full GC