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 -XX:+Inline 31 * -XX:CompileCommand=compileonly,TestUnloadedValueTypeField::test1 32 * -XX:CompileCommand=print,TestUnloadedValueTypeField::test1 33 * -XX:CompileCommand=compileonly,TestUnloadedValueTypeField::test2 34 * -XX:CompileCommand=compileonly,GetUnresolvedValueFieldWrongSignature::test3 35 * -XX:CompileCommand=compileonly,TestUnloadedValueTypeField::test4 36 * -XX:CompileCommand=compileonly,TestUnloadedValueTypeField::test5 37 * -XX:CompileCommand=compileonly,TestUnloadedValueTypeField::test11 38 * -XX:CompileCommand=compileonly,TestUnloadedValueTypeField::test12 39 * TestUnloadedValueTypeField 40 */ 41 42 import jdk.test.lib.Asserts; 43 44 public class TestUnloadedValueTypeField { 45 static final int WARMUP_LOOPS = 10000; 46 static public void main(String[] args) { 47 // instance fields 48 test1_verifier(); 49 test2_verifier(); 50 test3_verifier(); 51 test4_verifier(); 52 test5_verifier(); 53 54 // static fields 55 test11_verifier(); 56 test12_verifier(); 57 } 58 59 // Test case 1: 60 // The value type field class has been loaded, but the holder class has not been loaded. 61 // 62 // aload_0 63 // getfield MyValue1Holder.v:QMyValue1; 64 // ^ not loaded ^ already loaded 65 // 66 // MyValue1 has already been loaded, because it's in the ValueType attribute of 67 // TestUnloadedValueTypeField, due to TestUnloadedValueTypeField.test1_precondition(). 68 static value final class MyValue1 { 69 final int foo = 0; 70 71 static MyValue1 make() { 72 return __WithField(MyValue1.default.foo, 1234); 73 } 74 } 75 76 static class MyValue1Holder { 77 MyValue1 v; 78 79 public MyValue1Holder() { 80 v = MyValue1.make(); 81 } 82 } 83 84 static MyValue1 test1_precondition() { 85 return MyValue1.make(); 86 } 87 88 static int test1(MyValue1Holder holder) { 89 if (holder != null) { 90 return holder.v.foo + 1; 91 } else { 92 return 0; 93 } 94 } 95 96 static void test1_verifier() { 97 for (int i=0; i<WARMUP_LOOPS; i++) { 98 // Make sure test1() is compiled for the first iteration of this loop, 99 // while MyValue1Holder is yet to be loaded. 100 test1(null); 101 } 102 MyValue1Holder holder = new MyValue1Holder(); 103 Asserts.assertEQ(test1(holder), 1235); 104 } 105 106 // Test case 2: 107 // Both the value type field class, and the holder class have not been loaded. 108 // 109 // aload_0 110 // getfield MyValueHolder2.v:QMyValue2; 111 // ^ not loaded ^ not loaded 112 // 113 // MyValue2 has not been loaded, because it is not explicitly referenced by 114 // TestUnloadedValueTypeField. 115 static value final class MyValue2 { 116 final int foo = 0; 117 118 static MyValue2 make(int n) { 119 return __WithField(MyValue2.default.foo, n); 120 } 121 } 122 123 static class MyValue2Holder { 124 MyValue2 v; 125 126 public MyValue2Holder() { 127 v = MyValue2.make(1234); 128 } 129 } 130 131 132 static int test2(MyValue2Holder holder) { 133 if (holder != null) { 134 return holder.v.foo + 2; 135 } else { 136 return 0; 137 } 138 } 139 140 static void test2_verifier() { 141 for (int i=0; i<WARMUP_LOOPS; i++) { 142 // Make sure test2() is compiled for the first iteration of this loop, 143 // while MyValue2Holder2 and MyValue2 is yet to be loaded. 144 test2(null); 145 } 146 MyValue2Holder holder2 = new MyValue2Holder(); 147 Asserts.assertEQ(test2(holder2), 1236); 148 } 149 150 // Test case 3: same as test1, except we are using an incorrect signature to 151 // refer to the value class. 152 // The value type field class has been loaded, but the holder class has not been loaded. 153 // 154 // GetUnresolvedValueFieldWrongSignature::test3() { 155 // aload_0 156 // getfield MyValueHolder3.v:LMyValue3; 157 // ^ not loaded ^ already loaded (but should have been "Q") 158 // ... 159 // } 160 // 161 // MyValue3 has already been loaded, because it's in the ValueType attribute of 162 // TestUnloadedValueTypeField, due to TestUnloadedValueTypeField.test3_precondition(). 163 static value final class MyValue3 { 164 final int foo = 0; 165 166 static MyValue3 make() { 167 return __WithField(MyValue3.default.foo, 1234); 168 } 169 } 170 171 static class MyValue3Holder { 172 MyValue3 v; 173 174 public MyValue3Holder() { 175 v = MyValue3.make(); 176 } 177 } 178 179 static MyValue3 test3_precondition() { 180 return MyValue3.make(); 181 } 182 183 static int test3(MyValue3Holder holder) { 184 return GetUnresolvedValueFieldWrongSignature.test3(holder); 185 } 186 187 static void test3_verifier() { 188 for (int i=0; i<WARMUP_LOOPS; i++) { 189 // Make sure test3() is compiled for the first iteration of this loop, 190 // while MyValue3Holder is yet to be loaded. 191 test3(null); 192 } 193 194 MyValue3Holder holder = new MyValue3Holder(); 195 try { 196 test3(holder); 197 Asserts.fail("Should have thrown NoSuchFieldError"); 198 } catch (NoSuchFieldError e) { 199 // OK 200 } 201 } 202 203 // Test case 4: 204 // Same as case 1, except we use putfield instead of getfield. 205 static value final class MyValue4 { 206 final int foo = 0; 207 208 static MyValue4 make(int n) { 209 return __WithField(MyValue4.default.foo, n); 210 } 211 } 212 213 static class MyValue4Holder { 214 MyValue4 v; 215 216 public MyValue4Holder() { 217 v = MyValue4.make(0); 218 } 219 } 220 221 static MyValue4 test4_precondition() { 222 return MyValue4.make(0); 223 } 224 225 static void test4(MyValue4Holder holder, MyValue4 v) { 226 if (holder != null) { 227 holder.v = v; 228 } 229 } 230 231 static void test4_verifier() { 232 MyValue4 v = MyValue4.make(5678); 233 for (int i=0; i<WARMUP_LOOPS; i++) { 234 // Make sure test4() is compiled for the first iteration of this loop, 235 // while MyValue4Holder is yet to be loaded. 236 test4(null, v); 237 } 238 MyValue4Holder holder = new MyValue4Holder(); 239 test4(holder, v); 240 Asserts.assertEQ(holder.v.foo, 5678); 241 } 242 243 // Test case 5: 244 // Same as case 2, except we use putfield instead of getfield. 245 static value final class MyValue5 { 246 final int foo = 0; 247 248 static MyValue5 make(int n) { 249 return __WithField(MyValue5.default.foo, n); 250 } 251 } 252 253 static class MyValue5Holder { 254 MyValue5 v; 255 256 public MyValue5Holder() { 257 v = MyValue5.make(0); 258 } 259 public Object make(int n) { 260 return MyValue5.make(n); 261 } 262 } 263 264 static void test5(MyValue5Holder holder, Object o) { 265 if (holder != null) { 266 MyValue5 v = (MyValue5)o; 267 holder.v = v; 268 } 269 } 270 271 static void test5_verifier() { 272 for (int i=0; i<WARMUP_LOOPS; i++) { 273 // Make sure test5() is compiled for the first iteration of this loop, 274 // while both MyValue5Holder and MyValye5 are yet to be loaded. 275 test5(null, null); 276 } 277 278 MyValue5Holder holder = new MyValue5Holder(); 279 Object v = holder.make(5679); 280 test5(holder, v); 281 Asserts.assertEQ(holder.v.foo, 5679); 282 } 283 284 285 // Test case 11: (same as test1, except we use getstatic instead of getfield) 286 // The value type field class has been loaded, but the holder class has not been loaded. 287 // 288 // getstatic MyValue11Holder.v:QMyValue1; 289 // ^ not loaded ^ already loaded 290 // 291 // MyValue11 has already been loaded, because it's in the ValueType attribute of 292 // TestUnloadedValueTypeField, due to TestUnloadedValueTypeField.test1_precondition(). 293 static value final class MyValue11 { 294 final int foo = 0; 295 296 static MyValue11 make() { 297 return __WithField(MyValue11.default.foo, 1234); 298 } 299 } 300 301 static class MyValue11Holder { 302 static MyValue11 v = MyValue11.make(); 303 } 304 305 static MyValue11 test11_precondition() { 306 return MyValue11.make(); 307 } 308 309 static int test11(int n) { 310 if (n == 0) { 311 return 0; 312 } else { 313 return MyValue11Holder.v.foo + n; 314 } 315 } 316 317 static void test11_verifier() { 318 for (int i=0; i<WARMUP_LOOPS; i++) { 319 // Make sure test1() is compiled for the first iteration of this loop, 320 // while MyValue1Holder is yet to be loaded. 321 test11(0); 322 } 323 Asserts.assertEQ(test11(2), 1236); 324 } 325 326 327 // Test case 12: (same as test2, except we use getstatic instead of getfield) 328 // Both the value type field class, and the holder class have not been loaded. 329 // 330 // getstatic MyValueHolder12.v:QMyValue12; 331 // ^ not loaded ^ not loaded 332 // 333 // MyValue12 has not been loaded, because it is not explicitly referenced by 334 // TestUnloadedValueTypeField. 335 static value final class MyValue12 { 336 final int foo = 0; 337 338 static MyValue12 make(int n) { 339 return __WithField(MyValue12.default.foo, n); 340 } 341 } 342 343 static class MyValue12Holder { 344 static MyValue12 v = MyValue12.make(12); 345 } 346 347 static int test12(int n) { 348 if (n == 0) { 349 return 0; 350 } else { 351 return MyValue12Holder.v.foo + n; 352 } 353 } 354 355 static void test12_verifier() { 356 for (int i=0; i<WARMUP_LOOPS; i++) { 357 // Make sure test2() is compiled for the first iteration of this loop, 358 // while MyValue2Holder2 and MyValue2 is yet to be loaded. 359 test12(0); 360 } 361 Asserts.assertEQ(test12(1), 13); 362 } 363 }