1 /*
  2  * Copyright (c) 2023, 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 
 26 import jdk.internal.value.ValueClass;
 27 import jdk.test.lib.Asserts;
 28 import java.lang.reflect.Method;
 29 import jdk.internal.misc.Unsafe;
 30 import jdk.internal.vm.annotation.ImplicitlyConstructible;
 31 import jdk.internal.vm.annotation.LooselyConsistentValue;
 32 
 33 
 34 /*
 35  * @test
 36  * @summary Test of VM.newNullRestrictedArray API
 37  * @library /test/lib
 38  * @modules java.base/jdk.internal.vm.annotation
 39  *          java.base/jdk.internal.misc
 40  *          java.base/jdk.internal.value
 41  * @enablePreview
 42  * @run main/othervm NullRestrictedArrayTest
 43  */
 44 
 45 
 46 public class NullRestrictedArrayTest {
 47 
 48   private static final Unsafe UNSAFE = Unsafe.getUnsafe();
 49 
 50 
 51   public static void main(String[] args) {
 52       NullRestrictedArrayTest tests = new NullRestrictedArrayTest();
 53       Class c = tests.getClass();
 54       for (Method m : c.getDeclaredMethods()) {
 55         if (m.getName().startsWith("test_")) {
 56           try {
 57             System.out.println("Running " + m.getName());
 58             m.invoke(tests);
 59           } catch (Throwable t) {
 60             t.printStackTrace();
 61             throw new RuntimeException(t);
 62           }
 63         }
 64       }
 65   }
 66 
 67   // Test illegal attempt to create a null restricted array with an identity class
 68   public void test_0() {
 69       Throwable exception = null;
 70       try {
 71         ValueClass.newNullRestrictedArray(String.class, 4);
 72       } catch (IllegalArgumentException e) {
 73         System.out.println("Received: " + e);
 74         exception = e;
 75       }
 76       Asserts.assertNotNull(exception, "Expected IllegalArgumentException not received");
 77   }
 78 
 79   // Test illegal array length
 80   @ImplicitlyConstructible
 81   @LooselyConsistentValue
 82   static value class ValueClass1 {
 83     int i = 0;
 84     int j = 0;
 85   }
 86 
 87   public void test_1() {
 88       Throwable exception = null;
 89       try {
 90         ValueClass.newNullRestrictedArray(ValueClass1.class, -1);
 91       } catch (IllegalArgumentException e) {
 92         System.out.println("Received: " + e);
 93         exception = e;
 94       }
 95       Asserts.assertNotNull(exception, "Expected IllegalArgumentException not received");
 96   }
 97 
 98   // Test illegal attempt to create a null restricted array with a value class not annotated with @ImplicitlyConstructible
 99   static value class ValueClass2 {
100     int i = 0;
101     int j = 0;
102   }
103 
104   public void test_2() {
105       Throwable exception = null;
106       try {
107         ValueClass.newNullRestrictedArray(ValueClass2.class, 8);
108       } catch (IllegalArgumentException e) {
109         System.out.println("Received: " + e);
110         exception = e;
111       }
112       Asserts.assertNotNull(exception, "Expected IllegalArgumentException not received");
113   }
114 
115   // Test valid creation of a flat array
116   @ImplicitlyConstructible
117   @LooselyConsistentValue
118   static value class ValueClass3 {
119     int i = 0;
120     int j = 0;
121   }
122 
123   public void test_3() {
124       Throwable exception = null;
125       try {
126         Object array = ValueClass.newNullRestrictedArray(ValueClass3.class, 8);
127         Asserts.assertTrue(UNSAFE.isFlatArray(array.getClass()), "Expecting flat array but array is not flat");
128       } catch (Throwable e) {
129         System.out.println("Received: " + e);
130         exception = e;
131       }
132       Asserts.assertNull(exception, "Unexpected exception: " + exception);
133   }
134 
135   // Test that elements are not null
136   @ImplicitlyConstructible
137   @LooselyConsistentValue
138 
139   static value class ValueClass4 {
140     int i = 0;
141     int j = 0;
142   }
143 
144   public void test_4() {
145       Throwable exception = null;
146       try {
147         Object[] array = ValueClass.newNullRestrictedArray(ValueClass4.class, 8);
148         Asserts.assertNotNull(array[1], "Expecting non null element but null found instead");
149       } catch (Throwable e) {
150         System.out.println("Received: " + e);
151         exception = e;
152       }
153       Asserts.assertNull(exception, "Unexpected exception: " + exception);
154   }
155 
156   // Test that writing null to a null restricted array throws an exception
157   @ImplicitlyConstructible
158   @LooselyConsistentValue
159   static value class ValueClass5 {
160     int i = 0;
161     int j = 0;
162   }
163 
164   public void test_5() {
165       Throwable exception = null;
166       try {
167         Object[] array = ValueClass.newNullRestrictedArray(ValueClass4.class, 8);
168         array[1] = null;
169       } catch (NullPointerException e) {
170         System.out.println("Received: " + e);
171         exception = e;
172       }
173       Asserts.assertNotNull(exception, "Expected NullPointerException not received");
174   }
175 
176 }