1 /*
2 * Copyright (c) 2019, 2026, 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.LooselyConsistentValue;
27 import jdk.internal.vm.annotation.NullRestricted;
28
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 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 @LooselyConsistentValue
47 static value class ClassA {
48 @NullRestricted
49 static ClassB b = new ClassB();
50 public int i;
51
52 public ClassA() {
53 i = 3;
54 }
55 }
56
57 @LooselyConsistentValue
58 static value class ClassB {
59 @NullRestricted
60 static ClassA a = new ClassA();
61 public int i;
62
63 public ClassB() {
64 i = 700;
65 }
66 }
67
68 // ClassC has a reference to itself in its static field, but it should be able
69 // to initialize itself successfully. Access to this static field after initialization
70 // should return the default value.
71 @LooselyConsistentValue
72 static value class ClassC {
73 @NullRestricted
74 static ClassC c = new ClassC();
75 int i;
76
77 public ClassC() {
78 i = 42;
79 }
80 }
81
82
83 // ClassD and ClassE have circular references in their static fields, and they
84 // read these static fields during their initialization, the value read from
85 // these fields should be the default value. Both classes should initialize
86 // successfully.
87 @LooselyConsistentValue
88 static value class ClassD {
89 @NullRestricted
90 static ClassE e = new ClassE();
91 int i;
92
93 static {
94 Asserts.assertEquals(e.i, 42, "Static field e.i incorrect");
95 }
96
97 public ClassD() {
98 i = 42;
99 }
100 }
101
102 @LooselyConsistentValue
103 static value class ClassE {
104 @NullRestricted
105 static ClassD d = new ClassD();
106 int i;
107
108 static {
109 Asserts.assertEquals(d.i, 42, "Static field d.i incorrect");
110 }
111
112 public ClassE() {
113 i = 42;
114 }
115 }
116
117 // ClassF and ClassG have circular references in their static fields, and they
118 // create new instances of each other type to initialize these static fields
119 // during their initialization. Both classes should initialize successfully.
120 @LooselyConsistentValue
121 static value class ClassF {
122 @NullRestricted
123 static ClassG g = new ClassG();
124 int i;
125
126 static {
127 g = new ClassG();
128 Asserts.assertEquals(g.i, 64, "Static field ClassF.g.i incorrect");
129 }
130
131 ClassF() {
132 i = 314;
133 }
134 }
135
136 @LooselyConsistentValue
137 static value class ClassG {
138 @NullRestricted
139 static ClassF f = new ClassF();
140 int i;
141
142 static {
143 f = new ClassF();
144 Asserts.assertEquals(f.i, 314, "Static field ClassG.f.i incorrect");
145 }
146
147 ClassG() {
148 i = 64;
149 }
150 }
151
152 public static void main(String[] args) {
153 Asserts.assertEquals(ClassA.b.i, 700, "Static field ClassA.b.i incorrect");
154 Asserts.assertEquals(ClassB.a.i, 3, "Static field Classb.a.i incorrect");
155 Asserts.assertEquals(ClassC.c.i, 42, "Static field ClassC.c.i incorrect");
156 new ClassD();
157 new ClassF();
158 }
159 }