1 /* 2 * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package compiler.valhalla.valuetypes; 25 26 import jdk.test.lib.Asserts; 27 28 /* 29 * @test 30 * @summary Test on stack replacement (OSR) with value types 31 * @library /testlibrary /test/lib /compiler/whitebox / 32 * @compile -XDallowWithFieldOperator TestOnStackReplacement.java 33 * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform 34 * @run main/othervm/timeout=120 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 35 * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+EnableValhalla 36 * compiler.valhalla.valuetypes.ValueTypeTest 37 * compiler.valhalla.valuetypes.TestOnStackReplacement 38 */ 39 public class TestOnStackReplacement extends ValueTypeTest { 40 // Extra VM parameters for some test scenarios. See ValueTypeTest.getVMParameters() 41 @Override 42 public String[] getExtraVMParameters(int scenario) { 43 switch (scenario) { 44 case 3: return new String[] {"-XX:ValueArrayElemMaxFlatSize=0"}; 45 } 46 return null; 47 } 48 49 public static void main(String[] args) throws Throwable { 50 TestOnStackReplacement test = new TestOnStackReplacement(); 51 test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class); 52 } 53 54 // Helper methods 55 56 protected long hash() { 57 return hash(rI, rL); 58 } 59 60 protected long hash(int x, long y) { 61 return MyValue1.createWithFieldsInline(x, y).hash(); 62 } 63 64 // Test OSR compilation 65 @Test() 66 public long test1() { 67 MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); 68 MyValue1[] va = new MyValue1[Math.abs(rI) % 3]; 69 for (int i = 0; i < va.length; ++i) { 70 va[i] = MyValue1.createWithFieldsInline(rI, rL); 71 } 72 long result = 0; 73 // Long loop to trigger OSR compilation 74 for (int i = 0 ; i < 50_000; ++i) { 75 // Reference local value type in interpreter state 76 result = v.hash(); 77 for (int j = 0; j < va.length; ++j) { 78 result += va[j].hash(); 79 } 80 } 81 return result; 82 } 83 84 @DontCompile 85 public void test1_verifier(boolean warmup) { 86 long result = test1(); 87 Asserts.assertEQ(result, ((Math.abs(rI) % 3) + 1) * hash()); 88 } 89 90 // Test loop peeling 91 @Test(failOn = ALLOC + LOAD + STORE) 92 public void test2() { 93 MyValue1 v = MyValue1.createWithFieldsInline(0, 1); 94 // Trigger OSR compilation and loop peeling 95 for (int i = 0; i < 50_000; ++i) { 96 if (v.x != i || v.y != i + 1) { 97 // Uncommon trap 98 throw new RuntimeException("test2 failed"); 99 } 100 v = MyValue1.createWithFieldsInline(i + 1, i + 2); 101 } 102 } 103 104 @DontCompile 105 public void test2_verifier(boolean warmup) { 106 test2(); 107 } 108 109 // Test loop peeling and unrolling 110 @Test() 111 public void test3() { 112 MyValue1 v1 = MyValue1.createWithFieldsInline(0, 0); 113 MyValue1 v2 = MyValue1.createWithFieldsInline(1, 1); 114 // Trigger OSR compilation and loop peeling 115 for (int i = 0; i < 50_000; ++i) { 116 if (v1.x != 2*i || v2.x != i+1 || v2.y != i+1) { 117 // Uncommon trap 118 throw new RuntimeException("test3 failed"); 119 } 120 v1 = MyValue1.createWithFieldsInline(2*(i+1), 0); 121 v2 = MyValue1.createWithFieldsInline(i+2, i+2); 122 } 123 } 124 125 @DontCompile 126 public void test3_verifier(boolean warmup) { 127 test3(); 128 } 129 130 // OSR compilation with Object local 131 @DontCompile 132 public Object test4_init() { 133 return MyValue1.createWithFieldsInline(rI, rL); 134 } 135 136 @DontCompile 137 public Object test4_body() { 138 return MyValue1.createWithFieldsInline(rI, rL); 139 } 140 141 @Test() 142 public Object test4() { 143 Object vt = test4_init(); 144 for (int i = 0; i < 50_000; i++) { 145 if (i % 2 == 1) { 146 vt = test4_body(); 147 } 148 } 149 return vt; 150 } 151 152 @DontCompile 153 public void test4_verifier(boolean warmup) { 154 test4(); 155 } 156 157 // OSR compilation with null value type local 158 159 MyValue1.box nullField; 160 161 @Test() 162 public void test5() { 163 MyValue1.box vt = nullField; 164 for (int i = 0; i < 50_000; i++) { 165 if ((Object)vt != null) { 166 throw new RuntimeException("test5 failed: No NPE thrown"); 167 } 168 } 169 } 170 171 @DontCompile 172 public void test5_verifier(boolean warmup) { 173 test5(); 174 } 175 }