--- /dev/null 2019-03-11 09:22:42.048915961 +0100 +++ new/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestOnStackReplacement.java 2019-03-11 14:27:39.214353868 +0100 @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.valhalla.valuetypes; + +import jdk.test.lib.Asserts; + +/* + * @test + * @summary Test on stack replacement (OSR) with value types + * @library /testlibrary /test/lib /compiler/whitebox / + * @requires os.simpleArch == "x64" + * @compile -XDallowWithFieldOperator TestOnStackReplacement.java + * @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.TestOnStackReplacement + */ +public class TestOnStackReplacement extends ValueTypeTest { + // Extra VM parameters for some test scenarios. See ValueTypeTest.getVMParameters() + @Override + public String[] getExtraVMParameters(int scenario) { + switch (scenario) { + case 3: return new String[] {"-XX:-ValueArrayFlatten"}; + } + return null; + } + + public static void main(String[] args) throws Throwable { + TestOnStackReplacement test = new TestOnStackReplacement(); + test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class); + } + + // Helper methods + + protected long hash() { + return hash(rI, rL); + } + + protected long hash(int x, long y) { + return MyValue1.createWithFieldsInline(x, y).hash(); + } + + // Test OSR compilation + @Test() + public long test1() { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + MyValue1[] va = new MyValue1[Math.abs(rI) % 3]; + for (int i = 0; i < va.length; ++i) { + va[i] = MyValue1.createWithFieldsInline(rI, rL); + } + long result = 0; + // Long loop to trigger OSR compilation + for (int i = 0 ; i < 50_000; ++i) { + // Reference local value type in interpreter state + result = v.hash(); + for (int j = 0; j < va.length; ++j) { + result += va[j].hash(); + } + } + return result; + } + + @DontCompile + public void test1_verifier(boolean warmup) { + long result = test1(); + Asserts.assertEQ(result, ((Math.abs(rI) % 3) + 1) * hash()); + } + + // Test loop peeling + @Test(failOn = ALLOC + LOAD + STORE) + public void test2() { + MyValue1 v = MyValue1.createWithFieldsInline(0, 1); + // Trigger OSR compilation and loop peeling + for (int i = 0; i < 50_000; ++i) { + if (v.x != i || v.y != i + 1) { + // Uncommon trap + throw new RuntimeException("test2 failed"); + } + v = MyValue1.createWithFieldsInline(i + 1, i + 2); + } + } + + @DontCompile + public void test2_verifier(boolean warmup) { + test2(); + } + + // Test loop peeling and unrolling + @Test() + public void test3() { + MyValue1 v1 = MyValue1.createWithFieldsInline(0, 0); + MyValue1 v2 = MyValue1.createWithFieldsInline(1, 1); + // Trigger OSR compilation and loop peeling + for (int i = 0; i < 50_000; ++i) { + if (v1.x != 2*i || v2.x != i+1 || v2.y != i+1) { + // Uncommon trap + throw new RuntimeException("test3 failed"); + } + v1 = MyValue1.createWithFieldsInline(2*(i+1), 0); + v2 = MyValue1.createWithFieldsInline(i+2, i+2); + } + } + + @DontCompile + public void test3_verifier(boolean warmup) { + test3(); + } + + // OSR compilation with Object local + @DontCompile + public Object test4_init() { + return MyValue1.createWithFieldsInline(rI, rL); + } + + @DontCompile + public Object test4_body() { + return MyValue1.createWithFieldsInline(rI, rL); + } + + @Test() + public Object test4() { + Object vt = test4_init(); + for (int i = 0; i < 50_000; i++) { + if (i % 2 == 1) { + vt = test4_body(); + } + } + return vt; + } + + @DontCompile + public void test4_verifier(boolean warmup) { + test4(); + } + + // OSR compilation with null value type local + + MyValue1.box nullField; + + @Test() + public void test5() { + MyValue1.box vt = nullField; + for (int i = 0; i < 50_000; i++) { + if ((Object)vt != null) { + throw new RuntimeException("test5 failed: No NPE thrown"); + } + } + } + + @DontCompile + public void test5_verifier(boolean warmup) { + test5(); + } +}