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 }