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 package runtime.valhalla.inlinetypes; 24 25 import jdk.test.lib.Asserts; 26 import jdk.internal.vm.annotation.ImplicitlyConstructible; 27 import jdk.internal.vm.annotation.LooselyConsistentValue; 28 import jdk.internal.vm.annotation.NullRestricted; 29 30 /* 31 * @test 32 * @summary Test circularity in static fields 33 * @library /test/lib 34 * @modules java.base/jdk.internal.vm.annotation 35 * @enablePreview 36 * @compile StaticFieldsTest.java 37 * @run main/othervm runtime.valhalla.inlinetypes.StaticFieldsTest 38 */ 39 40 public class StaticFieldsTest { 41 42 43 // ClassA and ClassB have a simple cycle in their static fields, but they should 44 // be able to load and initialize themselves successfully. Access to these 45 // static fields after their initialization should return the default value. 46 @ImplicitlyConstructible 47 @LooselyConsistentValue 48 static value class ClassA { 49 @NullRestricted 50 static ClassB b; 51 public int i; 52 53 public ClassA() { 54 i = 3; 55 } 56 } 57 58 @ImplicitlyConstructible 59 @LooselyConsistentValue 60 static value class ClassB { 61 @NullRestricted 62 static ClassA a; 63 public int i; 64 65 public ClassB() { 66 i = 700; 67 } 68 } 69 70 // ClassC has a reference to itself in its static field, but it should be able 71 // to initialize itelf successfully. Access to this static field after initialization 72 // should return the default value. 73 @ImplicitlyConstructible 74 @LooselyConsistentValue 75 static value class ClassC { 76 @NullRestricted 77 static ClassC c; 78 int i; 79 80 public ClassC() { 81 i = 42; 82 } 83 } 84 85 86 // ClassD and ClassE have circular references in their static fields, and they 87 // read these static fields during their initialization, the value read from 88 // these fields should be the default value. Both classes should initialize 89 // successfully. 90 @ImplicitlyConstructible 91 @LooselyConsistentValue 92 static value class ClassD { 93 @NullRestricted 94 static ClassE e; 95 int i; 96 97 static { 98 Asserts.assertEquals(e.i, 0, "Static field e.i incorrect"); 99 } 100 101 public ClassD() { 102 i = 42; 103 } 104 } 105 106 @ImplicitlyConstructible 107 @LooselyConsistentValue 108 static value class ClassE { 109 @NullRestricted 110 static ClassD d; 111 int i; 112 113 static { 114 Asserts.assertEquals(d.i, 0, "Static field d.i incorrect"); 115 } 116 117 public ClassE() { 118 i = 42; 119 } 120 } 121 122 // ClassF and ClassG have circular references in their static fields, and they 123 // create new instances of each other type to initialize these static fields 124 // during their initialization. Both classes should initialize successfully. 125 @ImplicitlyConstructible 126 @LooselyConsistentValue 127 static value class ClassF { 128 @NullRestricted 129 static ClassG g; 130 int i; 131 132 static { 133 g = new ClassG(); 134 Asserts.assertEquals(g.i, 64, "Static field ClassF.g.i incorrect"); 135 } 136 137 ClassF() { 138 i = 314; 139 } 140 } 141 142 @ImplicitlyConstructible 143 @LooselyConsistentValue 144 static value class ClassG { 145 @NullRestricted 146 static ClassF f; 147 int i; 148 149 static { 150 f = new ClassF(); 151 Asserts.assertEquals(f.i, 314, "Static field ClassG.f.i incorrect"); 152 } 153 154 ClassG() { 155 i = 64; 156 } 157 } 158 159 public static void main(String[] args) { 160 Asserts.assertEquals(ClassA.b.i, 0, "Static field ClassA.b.i incorrect"); 161 Asserts.assertEquals(ClassB.a.i, 0, "Static field Classb.a.i incorrect"); 162 Asserts.assertEquals(ClassC.c.i, 0, "Static field ClassC.c.i incorrect"); 163 new ClassD(); 164 new ClassF(); 165 } 166 }