1 /* 2 * Copyright (c) 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 /** 25 * @test 26 * @library /test/lib 27 * @summary Test the handling of fields of unloaded value classes. 28 * @compile -XDallowWithFieldOperator hack/GetUnresolvedValueFieldWrongSignature.java 29 * @compile -XDallowWithFieldOperator TestUnloadedValueTypeField.java 30 * @run main/othervm -XX:+EnableValhalla -Xcomp 31 * -XX:CompileCommand=compileonly,TestUnloadedValueTypeField::test1 32 * -XX:CompileCommand=compileonly,TestUnloadedValueTypeField::test2 33 * -XX:CompileCommand=compileonly,GetUnresolvedValueFieldWrongSignature::test3 34 * -XX:CompileCommand=compileonly,TestUnloadedValueTypeField::test4 35 * -XX:CompileCommand=compileonly,TestUnloadedValueTypeField::test5 36 * TestUnloadedValueTypeField 37 */ 38 39 import jdk.test.lib.Asserts; 40 41 public class TestUnloadedValueTypeField { 42 static public void main(String[] args) { 43 test1_verifier(); 44 test2_verifier(); 45 test3_verifier(); 46 test4_verifier(); 47 test5_verifier(); 48 } 49 50 // Test case 1: 51 // The value type field class has been loaded, but the holder class has not been loaded. 52 // 53 // aload_0 54 // getfield MyValue1Holder.v:QMyValue1; 55 // ^ not loaded ^ already loaded 56 // 57 // MyValue1 has already been loaded, because it's in the ValueType attribute of 58 // TestUnloadedValueTypeField, due to TestUnloadedValueTypeField.test1_precondition(). 59 static value final class MyValue1 { 60 final int foo = 0; 61 62 static MyValue1 make() { 63 return __WithField(MyValue1.default.foo, 1234); 64 } 65 } 66 67 static class MyValue1Holder { 68 MyValue1 v; 69 70 public MyValue1Holder() { 71 v = MyValue1.make(); 72 } 73 } 74 75 static MyValue1 test1_precondition() { 76 return MyValue1.make(); 77 } 78 79 static int test1(MyValue1Holder holder) { 80 if (holder != null) { 81 return holder.v.foo + 1; 82 } else { 83 return 0; 84 } 85 } 86 87 static void test1_verifier() { 88 for (int i=0; i<10000; i++) { 89 // Make sure test1() is compiled for the first iteration of this loop, 90 // while MyValue1Holder is yet to be loaded. 91 test1(null); 92 MyValue1Holder holder = new MyValue1Holder(); 93 Asserts.assertEQ(test1(holder), 1235); 94 } 95 } 96 97 // Test case 2: 98 // Both the value type field class, and the holder class have not been loaded. 99 // 100 // aload_0 101 // getfield MyValueHolder2.v:QMyValue2; 102 // ^ not loaded ^ not loaded 103 // 104 // MyValue2 has already been loaded, because it is not explicitly referenced by 105 // TestUnloadedValueTypeField. 106 static value final class MyValue2 { 107 final int foo = 0; 108 109 static MyValue2 make(int n) { 110 return __WithField(MyValue2.default.foo, n); 111 } 112 } 113 114 static class MyValue2Holder { 115 MyValue2 v; 116 117 public MyValue2Holder() { 118 v = MyValue2.make(1234); 119 } 120 } 121 122 123 static int test2(MyValue2Holder holder) { 124 if (holder != null) { 125 return holder.v.foo + 2; 126 } else { 127 return 0; 128 } 129 } 130 131 static void test2_verifier() { 132 for (int i=0; i<10000; i++) { 133 // Make sure test2() is compiled for the first iteration of this loop, 134 // while MyValue2Holder2 and MyValue2 is yet to be loaded. 135 test2(null); 136 MyValue2Holder holder2 = new MyValue2Holder(); 137 Asserts.assertEQ(test2(holder2), 1236); 138 } 139 } 140 141 // Test case 3: same as test1, except we are using an incorrect signature to 142 // refer to the value class. 143 // The value type field class has been loaded, but the holder class has not been loaded. 144 // 145 // GetUnresolvedValueFieldWrongSignature::test3() { 146 // aload_0 147 // getfield MyValueHolder3.v:LMyValue3; 148 // ^ not loaded ^ already loaded (but should have been "Q") 149 // ... 150 // } 151 // 152 // MyValue3 has already been loaded, because it's in the ValueType attribute of 153 // TestUnloadedValueTypeField, due to TestUnloadedValueTypeField.test3_precondition(). 154 static value final class MyValue3 { 155 final int foo = 0; 156 157 static MyValue3 make() { 158 return __WithField(MyValue3.default.foo, 1234); 159 } 160 } 161 162 static class MyValue3Holder { 163 MyValue3 v; 164 165 public MyValue3Holder() { 166 v = MyValue3.make(); 167 } 168 } 169 170 static MyValue3 test3_precondition() { 171 return MyValue3.make(); 172 } 173 174 static int test3(MyValue3Holder holder) { 175 return GetUnresolvedValueFieldWrongSignature.test3(holder); 176 } 177 178 static void test3_verifier() { 179 for (int i=0; i<10000; i++) { 180 // Make sure test3() is compiled for the first iteration of this loop, 181 // while MyValue3Holder is yet to be loaded. 182 test3(null); 183 MyValue3Holder holder = new MyValue3Holder(); 184 try { 185 test3(holder); 186 Asserts.fail("Should have thrown NoSuchFieldError"); 187 } catch (NoSuchFieldError e) { 188 // OK 189 } 190 } 191 } 192 193 // Test case 4: 194 // Same as case 1, except we use putfield instead of getfield. 195 static value final class MyValue4 { 196 final int foo = 0; 197 198 static MyValue4 make(int n) { 199 return __WithField(MyValue4.default.foo, n); 200 } 201 } 202 203 static class MyValue4Holder { 204 MyValue4 v; 205 206 public MyValue4Holder() { 207 v = MyValue4.make(0); 208 } 209 } 210 211 static MyValue4 test4_precondition() { 212 return MyValue4.make(0); 213 } 214 215 static void test4(MyValue4Holder holder, MyValue4 v) { 216 if (holder != null) { 217 holder.v = v; 218 } 219 } 220 221 static void test4_verifier() { 222 MyValue4 v = MyValue4.make(5678); 223 for (int i=0; i<10000; i++) { 224 // Make sure test4() is compiled for the first iteration of this loop, 225 // while MyValue4Holder is yet to be loaded. 226 test4(null, v); 227 MyValue4Holder holder = new MyValue4Holder(); 228 test4(holder, v); 229 Asserts.assertEQ(holder.v.foo, 5678); 230 } 231 } 232 233 // Test case 5: 234 // Same as case 2, except we use putfield instead of getfield. 235 static value final class MyValue5 { 236 final int foo = 0; 237 238 static MyValue5 make(int n) { 239 return __WithField(MyValue5.default.foo, n); 240 } 241 } 242 243 static class MyValue5Holder { 244 MyValue5 v; 245 246 public MyValue5Holder() { 247 v = MyValue5.make(0); 248 } 249 public Object make(int n) { 250 return MyValue5.make(n); 251 } 252 } 253 254 static void test5(MyValue5Holder holder, Object o) { 255 if (holder != null) { 256 MyValue5 v = (MyValue5)o; 257 holder.v = v; 258 } 259 } 260 261 static void test5_verifier() { 262 for (int i=0; i<10000; i++) { 263 // Make sure test5() is compiled for the first iteration of this loop, 264 // while both MyValue5Holder and MyValye5 are yet to be loaded. 265 test5(null, null); 266 MyValue5Holder holder = new MyValue5Holder(); 267 Object v = holder.make(5679); 268 test5(holder, v); 269 Asserts.assertEQ(holder.v.foo, 5679); 270 } 271 } 272 }