--- old/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestUnloadedValueTypeField.java 2019-03-11 15:37:38.158305226 -0700 +++ new/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestUnloadedValueTypeField.java 2019-03-11 15:37:37.922296642 -0700 @@ -21,30 +21,41 @@ * questions. */ +package compiler.valhalla.valuetypes; +import jdk.test.lib.Asserts; + /** * @test - * @library /test/lib + * @library /testlibrary /test/lib /compiler/whitebox / * @summary Test the handling of fields of unloaded value classes. * @compile -XDallowWithFieldOperator hack/GetUnresolvedValueFieldWrongSignature.java * @compile -XDallowWithFieldOperator TestUnloadedValueTypeField.java - * @run main/othervm -XX:+EnableValhalla -Xcomp - * -XX:CompileCommand=compileonly,TestUnloadedValueTypeField::test1 - * -XX:CompileCommand=compileonly,TestUnloadedValueTypeField::test2 - * -XX:CompileCommand=compileonly,GetUnresolvedValueFieldWrongSignature::test3 - * -XX:CompileCommand=compileonly,TestUnloadedValueTypeField::test4 - * -XX:CompileCommand=compileonly,TestUnloadedValueTypeField::test5 - * TestUnloadedValueTypeField + * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform + * @run main/othervm/timeout=120 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions + * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+EnableValhalla + * compiler.valhalla.valuetypes.ValueTypeTest + * compiler.valhalla.valuetypes.TestUnloadedValueTypeField */ -import jdk.test.lib.Asserts; +public class TestUnloadedValueTypeField extends compiler.valhalla.valuetypes.ValueTypeTest { + public static void main(String[] args) throws Throwable { + TestUnloadedValueTypeField test = new TestUnloadedValueTypeField(); + test.run(args); + } + + static final String[][] scenarios = { + {}, + {"-XX:ValueFieldMaxFlatSize=0"} + }; + + @Override + public int getNumScenarios() { + return scenarios.length; + } -public class TestUnloadedValueTypeField { - static public void main(String[] args) { - test1_verifier(); - test2_verifier(); - test3_verifier(); - test4_verifier(); - test5_verifier(); + @Override + public String[] getVMParameters(int scenario) { + return scenarios[scenario]; } // Test case 1: @@ -76,7 +87,8 @@ return MyValue1.make(); } - static int test1(MyValue1Holder holder) { + @Test + public int test1(MyValue1Holder holder) { if (holder != null) { return holder.v.foo + 1; } else { @@ -84,11 +96,10 @@ } } - static void test1_verifier() { - for (int i=0; i<10000; i++) { - // Make sure test1() is compiled for the first iteration of this loop, - // while MyValue1Holder is yet to be loaded. + public void test1_verifier(boolean warmup) { + if (warmup) { test1(null); + } else { MyValue1Holder holder = new MyValue1Holder(); Asserts.assertEQ(test1(holder), 1235); } @@ -101,7 +112,7 @@ // getfield MyValueHolder2.v:QMyValue2; // ^ not loaded ^ not loaded // - // MyValue2 has already been loaded, because it is not explicitly referenced by + // MyValue2 has not been loaded, because it is not explicitly referenced by // TestUnloadedValueTypeField. static value final class MyValue2 { final int foo = 0; @@ -120,7 +131,8 @@ } - static int test2(MyValue2Holder holder) { + @Test + public int test2(MyValue2Holder holder) { if (holder != null) { return holder.v.foo + 2; } else { @@ -128,11 +140,10 @@ } } - static void test2_verifier() { - for (int i=0; i<10000; i++) { - // Make sure test2() is compiled for the first iteration of this loop, - // while MyValue2Holder2 and MyValue2 is yet to be loaded. + public void test2_verifier(boolean warmup) { + if (warmup) { test2(null); + } else { MyValue2Holder holder2 = new MyValue2Holder(); Asserts.assertEQ(test2(holder2), 1236); } @@ -171,15 +182,15 @@ return MyValue3.make(); } - static int test3(MyValue3Holder holder) { + @Test + public int test3(MyValue3Holder holder) { return GetUnresolvedValueFieldWrongSignature.test3(holder); } - static void test3_verifier() { - for (int i=0; i<10000; i++) { - // Make sure test3() is compiled for the first iteration of this loop, - // while MyValue3Holder is yet to be loaded. + public void test3_verifier(boolean warmup) { + if (warmup) { test3(null); + } else { MyValue3Holder holder = new MyValue3Holder(); try { test3(holder); @@ -212,18 +223,18 @@ return MyValue4.make(0); } - static void test4(MyValue4Holder holder, MyValue4 v) { + @Test + public void test4(MyValue4Holder holder, MyValue4 v) { if (holder != null) { holder.v = v; } } - static void test4_verifier() { + public void test4_verifier(boolean warmup) { MyValue4 v = MyValue4.make(5678); - for (int i=0; i<10000; i++) { - // Make sure test4() is compiled for the first iteration of this loop, - // while MyValue4Holder is yet to be loaded. + if (warmup) { test4(null, v); + } else { MyValue4Holder holder = new MyValue4Holder(); test4(holder, v); Asserts.assertEQ(holder.v.foo, 5678); @@ -251,22 +262,102 @@ } } - static void test5(MyValue5Holder holder, Object o) { + @Test + public void test5(MyValue5Holder holder, Object o) { if (holder != null) { MyValue5 v = (MyValue5)o; holder.v = v; } } - static void test5_verifier() { - for (int i=0; i<10000; i++) { - // Make sure test5() is compiled for the first iteration of this loop, - // while both MyValue5Holder and MyValye5 are yet to be loaded. + public void test5_verifier(boolean warmup) { + if (warmup) { test5(null, null); + } else { MyValue5Holder holder = new MyValue5Holder(); Object v = holder.make(5679); test5(holder, v); Asserts.assertEQ(holder.v.foo, 5679); } } + + + // Test case 11: (same as test1, except we use getstatic instead of getfield) + // The value type field class has been loaded, but the holder class has not been loaded. + // + // getstatic MyValue11Holder.v:QMyValue1; + // ^ not loaded ^ already loaded + // + // MyValue11 has already been loaded, because it's in the ValueType attribute of + // TestUnloadedValueTypeField, due to TestUnloadedValueTypeField.test1_precondition(). + static value final class MyValue11 { + final int foo = 0; + + static MyValue11 make() { + return __WithField(MyValue11.default.foo, 1234); + } + } + + static class MyValue11Holder { + static MyValue11 v = MyValue11.make(); + } + + static MyValue11 test11_precondition() { + return MyValue11.make(); + } + + @Test + public int test11(int n) { + if (n == 0) { + return 0; + } else { + return MyValue11Holder.v.foo + n; + } + } + + public void test11_verifier(boolean warmup) { + if (warmup) { + test11(0); + } else { + Asserts.assertEQ(test11(2), 1236); + } + } + + + // Test case 12: (same as test2, except we use getstatic instead of getfield) + // Both the value type field class, and the holder class have not been loaded. + // + // getstatic MyValueHolder12.v:QMyValue12; + // ^ not loaded ^ not loaded + // + // MyValue12 has not been loaded, because it is not explicitly referenced by + // TestUnloadedValueTypeField. + static value final class MyValue12 { + final int foo = 0; + + static MyValue12 make(int n) { + return __WithField(MyValue12.default.foo, n); + } + } + + static class MyValue12Holder { + static MyValue12 v = MyValue12.make(12); + } + + @Test + public int test12(int n) { + if (n == 0) { + return 0; + } else { + return MyValue12Holder.v.foo + n; + } + } + + public void test12_verifier(boolean warmup) { + if (warmup) { + test12(0); + } else { + Asserts.assertEQ(test12(1), 13); + } + } }