1 /*
  2  * Copyright (c) 2019, 2024, 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  * @summary Test accessing value class arrays that exceed the flattening threshold.
 27  * @library /test/lib
 28  * @enablePreview
 29  * @modules java.base/jdk.internal.value
 30  *          java.base/jdk.internal.vm.annotation
 31  * @run main/othervm -Xbatch
 32  *                   TestFlatArrayThreshold
 33  * @run main/othervm -XX:FlatArrayElementMaxOops=1 -Xbatch
 34  *                   TestFlatArrayThreshold
 35  * @run main/othervm -XX:FlatArrayElementMaxSize=1 -Xbatch
 36  *                   TestFlatArrayThreshold
 37 
 38  */
 39 
 40 import jdk.test.lib.Asserts;
 41 
 42 import jdk.internal.value.ValueClass;
 43 import jdk.internal.vm.annotation.ImplicitlyConstructible;
 44 import jdk.internal.vm.annotation.LooselyConsistentValue;
 45 import jdk.internal.vm.annotation.NullRestricted;
 46 
 47 @ImplicitlyConstructible
 48 @LooselyConsistentValue
 49 value class MyValue1 {
 50     Object o1;
 51     Object o2;
 52 
 53     public MyValue1() {
 54         o1 = new Integer(42);
 55         o2 = new Integer(43);
 56     }
 57 }
 58 
 59 public class TestFlatArrayThreshold {
 60 
 61     public static MyValue1 test1(MyValue1[] va, MyValue1 vt) {
 62         va[0] = vt;
 63         return va[1];
 64     }
 65 
 66     public static MyValue1 test2(MyValue1[] va, MyValue1 vt) {
 67         va[0] = vt;
 68         return va[1];
 69     }
 70 
 71     public static Object test3(Object[] va, MyValue1 vt) {
 72         va[0] = vt;
 73         return va[1];
 74     }
 75 
 76     public static Object test4(Object[] va, MyValue1 vt) {
 77         va[0] = vt;
 78         return va[1];
 79     }
 80 
 81     public static MyValue1 test5(MyValue1[] va, Object vt) {
 82         va[0] = (MyValue1)vt;
 83         return va[1];
 84     }
 85 
 86     public static MyValue1 test6(MyValue1[] va, Object vt) {
 87         va[0] = (MyValue1)vt;
 88         return va[1];
 89     }
 90 
 91     public static Object test7(Object[] va, Object vt) {
 92         va[0] = vt;
 93         return va[1];
 94     }
 95 
 96     static public void main(String[] args) {
 97         MyValue1 vt = new MyValue1();
 98         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
 99         MyValue1[] vaB = new MyValue1[2];
100         va[1] = vt;
101         for (int i = 0; i < 10_000; ++i) {
102             MyValue1 result1 = test1(va, vt);
103             Asserts.assertEQ(result1.o1, 42);
104             Asserts.assertEQ(result1.o2, 43);
105 
106             MyValue1 result2 = test2(va, vt);
107             Asserts.assertEQ(result2.o1, 42);
108             Asserts.assertEQ(result2.o2, 43);
109             result2 = test2(vaB, null);
110             Asserts.assertEQ(result2, null);
111 
112             MyValue1 result3 = (MyValue1)test3(va, vt);
113             Asserts.assertEQ(result3.o1, 42);
114             Asserts.assertEQ(result3.o2, 43);
115             result3 = (MyValue1)test3(vaB, vt);
116             Asserts.assertEQ(result3, null);
117 
118             MyValue1 result4 = (MyValue1)test4(va, vt);
119             Asserts.assertEQ(result4.o1, 42);
120             Asserts.assertEQ(result4.o2, 43);
121             result4 = (MyValue1)test4(vaB, null);
122             Asserts.assertEQ(result4, null);
123 
124             MyValue1 result5 = test5(va, vt);
125             Asserts.assertEQ(result5.o1, 42);
126             Asserts.assertEQ(result5.o2, 43);
127 
128             MyValue1 result6 = test6(va, vt);
129             Asserts.assertEQ(result6.o1, 42);
130             Asserts.assertEQ(result6.o2, 43);
131             result6 = test6(vaB, null);
132             Asserts.assertEQ(result6, null);
133 
134             MyValue1 result7 = (MyValue1)test7(va, vt);
135             Asserts.assertEQ(result7.o1, 42);
136             Asserts.assertEQ(result7.o2, 43);
137             result7 = (MyValue1)test7(vaB, null);
138             Asserts.assertEQ(result7, null);
139         }
140         try {
141             test2(va, null);
142             throw new RuntimeException("NullPointerException expected");
143         } catch (NullPointerException npe) {
144             // Expected
145         }
146         try {
147             test4(va, null);
148             throw new RuntimeException("NullPointerException expected");
149         } catch (NullPointerException npe) {
150             // Expected
151         }
152         try {
153             test5(va, null);
154             throw new RuntimeException("NullPointerException expected");
155         } catch (NullPointerException npe) {
156             // Expected
157         }
158         try {
159             test6(va, null);
160             throw new RuntimeException("NullPointerException expected");
161         } catch (NullPointerException npe) {
162             // Expected
163         }
164         try {
165             test7(va, null);
166             throw new RuntimeException("NullPointerException expected");
167         } catch (NullPointerException npe) {
168             // Expected
169         }
170     }
171 }