1 /*
2 * Copyright (c) 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 import jdk.internal.vm.annotation.Contended;
24 import jdk.test.lib.valueclass.AsValueClass;
25
26 /*
27 * @test
28 * @bug 8384107
29 * @summary Test contended field layout and oop maps with flattened value types
30 *
31 * @library /test/lib
32 * @modules java.base/jdk.internal.vm.annotation
33 * @run main/othervm -XX:-RestrictContended -XX:ContendedPaddingWidth=128 -Xmx128m OopMapsCustomValue
34 */
35 public class OopMapsCustomValue {
36 public static final int COUNT = 10000;
37
38 // Small value type (32 bits) — guaranteed to be flattened
39 @AsValueClass
40 static class Small {
41 int x;
42 Small(int x) { this.x = x; }
43 }
44
45 // Value type with reference + primitive — flattened with compressed oops,
46 // not flattened with full size oops, creating distinct layout patterns
47 @AsValueClass
48 static class Opt {
49 Object o;
50 boolean b;
51 Opt(Object o, boolean b) { this.o = o; this.b = b; }
52 }
53
54 // Contended fields using exact value types for flattening
55 public static class R0 {
56 int i1;
57 int i2;
58 Small s01;
59 Small s02;
60 @Contended
61 Small s03;
62 @Contended
63 Small s04;
64 @Contended
65 Opt opt01;
66 @Contended
67 Opt opt02;
68 }
69
70 public static class R1 extends R0 {
71 int i3;
72 int i4;
73 Small s05;
74 Small s06;
75 @Contended
76 Small s07;
77 @Contended
78 Small s08;
79 @Contended
80 Opt opt03;
81 @Contended
82 Opt opt04;
83 }
84
85 // Same-group contended with exact value types
86 public static class G {
87 @Contended("g1")
88 Small s01;
89 @Contended("g1")
90 Opt opt01;
91 @Contended("g2")
92 Small s02;
93 @Contended("g2")
94 Opt opt02;
95 }
96
97 public static void main(String[] args) throws Exception {
98 testContendedValueFields();
99 testContendedSameGroup();
100 }
101
102 static void testContendedValueFields() {
103 Object anchor = new Object();
104
105 R1[] rs = new R1[COUNT];
106 for (int i = 0; i < COUNT; i++) {
107 R1 r = new R1();
108 r.s01 = new Small(1);
109 r.s02 = new Small(2);
110 r.s03 = new Small(3);
111 r.s04 = new Small(4);
112 r.opt01 = new Opt(anchor, true);
113 r.opt02 = new Opt(anchor, false);
114 r.i1 = 1;
115 r.i2 = 2;
116 r.s05 = new Small(5);
117 r.s06 = new Small(6);
118 r.s07 = new Small(7);
119 r.s08 = new Small(8);
120 r.opt03 = new Opt(anchor, true);
121 r.opt04 = new Opt(anchor, false);
122 r.i3 = 3;
123 r.i4 = 4;
124 rs[i] = r;
125 }
126
127 System.gc();
128
129 for (int i = 0; i < COUNT; i++) {
130 R1 r = rs[i];
131 if (r.s01.x != 1) throw new Error("s01");
132 if (r.s02.x != 2) throw new Error("s02");
133 if (r.s03.x != 3) throw new Error("s03");
134 if (r.s04.x != 4) throw new Error("s04");
135 if (r.opt01.o != anchor || r.opt01.b != true) throw new Error("opt01");
136 if (r.opt02.o != anchor || r.opt02.b != false) throw new Error("opt02");
137 if (r.i1 != 1) throw new Error("i1");
138 if (r.i2 != 2) throw new Error("i2");
139 if (r.s05.x != 5) throw new Error("s05");
140 if (r.s06.x != 6) throw new Error("s06");
141 if (r.s07.x != 7) throw new Error("s07");
142 if (r.s08.x != 8) throw new Error("s08");
143 if (r.opt03.o != anchor || r.opt03.b != true) throw new Error("opt03");
144 if (r.opt04.o != anchor || r.opt04.b != false) throw new Error("opt04");
145 if (r.i3 != 3) throw new Error("i3");
146 if (r.i4 != 4) throw new Error("i4");
147 }
148 }
149
150 static void testContendedSameGroup() {
151 Object anchor = new Object();
152
153 G[] gs = new G[COUNT];
154 for (int i = 0; i < COUNT; i++) {
155 G g = new G();
156 g.s01 = new Small(1);
157 g.opt01 = new Opt(anchor, true);
158 g.s02 = new Small(2);
159 g.opt02 = new Opt(anchor, false);
160 gs[i] = g;
161 }
162
163 System.gc();
164
165 for (int i = 0; i < COUNT; i++) {
166 G g = gs[i];
167 if (g.s01.x != 1) throw new Error("g1 s01");
168 if (g.opt01.o != anchor || g.opt01.b != true) throw new Error("g1 opt01");
169 if (g.s02.x != 2) throw new Error("g2 s02");
170 if (g.opt02.o != anchor || g.opt02.b != false) throw new Error("g2 opt02");
171 }
172 }
173 }