|
1 /* |
|
2 * Copyright (c) 2019, 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 import java.util.ArrayList; |
|
26 import jdk.internal.vm.annotation.Contended; |
|
27 |
|
28 public class FieldLayoutApp { |
|
29 public static void main(String args[]) { |
|
30 ArrayList<TestObject> list = new ArrayList<>(); |
|
31 |
|
32 for (int i=0; i<400; i++) { |
|
33 list.add(new Base1()); |
|
34 list.add(new Child1()); |
|
35 list.add(new Base2()); |
|
36 list.add(new Child2()); |
|
37 } |
|
38 |
|
39 verifyAll(list); |
|
40 |
|
41 // Make sure the oopmaps are laid out correctly. |
|
42 System.gc(); |
|
43 verifyAll(list); |
|
44 } |
|
45 |
|
46 static void verifyAll(ArrayList<TestObject> list) { |
|
47 for (TestObject obj : list) { |
|
48 obj.verify(); |
|
49 } |
|
50 } |
|
51 |
|
52 static long lastUID = 0; |
|
53 synchronized static long makeUID() { |
|
54 return ++lastUID; |
|
55 } |
|
56 |
|
57 synchronized static void verifyUID(long uid) { |
|
58 if (uid <= 0 || uid > lastUID) { |
|
59 error("Unexpected UID " + uid + ", must be > 0 and <= " + lastUID); |
|
60 } |
|
61 } |
|
62 |
|
63 static void error(String s) { |
|
64 throw new RuntimeException(s); |
|
65 } |
|
66 |
|
67 static void ensure(boolean b) { |
|
68 if (!b) { |
|
69 error("Assertion failed"); |
|
70 } |
|
71 } |
|
72 |
|
73 static String makeString(long n) { |
|
74 return Long.toString(n); |
|
75 } |
|
76 |
|
77 static class TestObject { |
|
78 void verify() {} |
|
79 } |
|
80 |
|
81 static class Base1 extends TestObject { |
|
82 byte b1, b2; |
|
83 String s1; |
|
84 byte b3, b4; |
|
85 String s2; |
|
86 long uid; |
|
87 long l1; |
|
88 int i1; |
|
89 long l2; |
|
90 int i2; |
|
91 |
|
92 Base1() { |
|
93 uid = makeUID(); |
|
94 b1 = 1; |
|
95 b2 = 2; |
|
96 b3 = 3; |
|
97 b4 = 4; |
|
98 s1 = makeString(uid + 1); |
|
99 s2 = makeString(uid + 2); |
|
100 i1 = 101; |
|
101 i2 = 102; |
|
102 l1 = 1001; |
|
103 l2 = 1002; |
|
104 } |
|
105 |
|
106 void verify() { |
|
107 super.verify(); |
|
108 ensure(b1 == 1); |
|
109 ensure(b2 == 2); |
|
110 ensure(b3 == 3); |
|
111 ensure(b4 == 4); |
|
112 verifyUID(uid); |
|
113 ensure(s1.equals(makeString(uid + 1))); |
|
114 ensure(s2.equals(makeString(uid + 2))); |
|
115 ensure(i1 == 101); |
|
116 ensure(i2 == 102); |
|
117 ensure(l1 == 1001); |
|
118 ensure(l2 == 1002); |
|
119 } |
|
120 } |
|
121 |
|
122 // Base1 is archived but Child1 is loaded dynamically at runtime. Base1 may be |
|
123 // archived with different field layout options that those used during runtime. |
|
124 static class Child1 extends Base1 { |
|
125 byte cb1, cb2; |
|
126 String cs1; |
|
127 byte cb3, cb4; |
|
128 String cs2; |
|
129 long cuid; |
|
130 long cl1; |
|
131 int ci1; |
|
132 long cl2; |
|
133 int ci2; |
|
134 |
|
135 Child1() { |
|
136 cuid = makeUID(); |
|
137 cb1 = 1; |
|
138 cb2 = 2; |
|
139 cb3 = 3; |
|
140 cb4 = 4; |
|
141 cs1 = makeString(cuid + 1); |
|
142 cs2 = makeString(cuid + 2); |
|
143 ci1 = 101; |
|
144 ci2 = 102; |
|
145 cl1 = 1001; |
|
146 cl2 = 1002; |
|
147 } |
|
148 |
|
149 void verify() { |
|
150 super.verify(); |
|
151 ensure(cb1 == 1); |
|
152 ensure(cb2 == 2); |
|
153 ensure(cb3 == 3); |
|
154 ensure(cb4 == 4); |
|
155 verifyUID(uid); |
|
156 ensure(cs1.equals(makeString(cuid + 1))); |
|
157 ensure(cs2.equals(makeString(cuid + 2))); |
|
158 ensure(ci1 == 101); |
|
159 ensure(ci2 == 102); |
|
160 ensure(cl1 == 1001); |
|
161 ensure(cl2 == 1002); |
|
162 |
|
163 // Check the fields declared by the super class: |
|
164 ensure(b1 == 1); // javac should generate a FieldRef of FieldLayoutApp$Child1.b1:B, |
|
165 // even though b1 is declared in the super class. |
|
166 ensure(b2 == 2); |
|
167 ensure(b3 == 3); |
|
168 ensure(b4 == 4); |
|
169 verifyUID(uid); |
|
170 ensure(s1.equals(makeString(uid + 1))); |
|
171 ensure(s2.equals(makeString(uid + 2))); |
|
172 |
|
173 ensure(i1 == 101); |
|
174 ensure(i2 == 102); |
|
175 ensure(l1 == 1001); |
|
176 ensure(l2 == 1002); |
|
177 } |
|
178 } |
|
179 |
|
180 // Same as Base1 - minus the i1, i2, l1, l2 fields, plus some @Contended annotations |
|
181 static class Base2 extends TestObject { |
|
182 byte b1, b2; |
|
183 String s1; |
|
184 @Contended byte b3, b4; |
|
185 @Contended String s2; |
|
186 long uid; |
|
187 |
|
188 Base2() { |
|
189 uid = makeUID(); |
|
190 b1 = 1; |
|
191 b2 = 2; |
|
192 b3 = 3; |
|
193 b4 = 4; |
|
194 s1 = makeString(uid + 1); |
|
195 s2 = makeString(uid + 2); |
|
196 } |
|
197 |
|
198 void verify() { |
|
199 super.verify(); |
|
200 ensure(b1 == 1); |
|
201 ensure(b2 == 2); |
|
202 ensure(b3 == 3); |
|
203 ensure(b4 == 4); |
|
204 verifyUID(uid); |
|
205 ensure(s1.equals(makeString(uid + 1))); |
|
206 ensure(s2.equals(makeString(uid + 2))); |
|
207 } |
|
208 } |
|
209 |
|
210 // Same as Child2 - minus the ci1, ci2, cl1, cl2 fields, plus some @Contended annotations |
|
211 // |
|
212 // Base2 is archived but Child2 is loaded dynamically at runtime. Base2 may be |
|
213 // archived with different field layout options that those used during runtime. |
|
214 static class Child2 extends Base2 { |
|
215 byte cb1, cb2; |
|
216 @Contended String cs1; |
|
217 byte cb3, cb4; |
|
218 String cs2; |
|
219 @Contended long cuid; |
|
220 |
|
221 Child2() { |
|
222 cuid = makeUID(); |
|
223 cb1 = 1; |
|
224 cb2 = 2; |
|
225 cb3 = 3; |
|
226 cb4 = 4; |
|
227 cs1 = makeString(cuid + 1); |
|
228 cs2 = makeString(cuid + 2); |
|
229 } |
|
230 |
|
231 void verify() { |
|
232 super.verify(); |
|
233 ensure(cb1 == 1); |
|
234 ensure(cb2 == 2); |
|
235 ensure(cb3 == 3); |
|
236 ensure(cb4 == 4); |
|
237 verifyUID(uid); |
|
238 ensure(cs1.equals(makeString(cuid + 1))); |
|
239 ensure(cs2.equals(makeString(cuid + 2))); |
|
240 |
|
241 // Check the fields declared by the super class: |
|
242 ensure(b1 == 1); // javac should generate a FieldRef of FieldLayoutApp$Child2.b1:B, |
|
243 // even though b1 is declared in the super class. |
|
244 ensure(b2 == 2); |
|
245 ensure(b3 == 3); |
|
246 ensure(b4 == 4); |
|
247 verifyUID(uid); |
|
248 ensure(s1.equals(makeString(uid + 1))); |
|
249 ensure(s2.equals(makeString(uid + 2))); |
|
250 } |
|
251 } |
|
252 } |
|
253 |
|
254 |