1 /*
2 * Copyright (c) 2020, Red Hat, Inc. 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 * @test
26 * @summary Test for Magic.deepSizeOf with 32-bit compressed oops
27 * @library /test/lib
28 *
29 * @run main/othervm -Xmx128m
30 * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -Xcheck:jni
31 * -Xint
32 * DeepSizeOf
33 *
34 * @run main/othervm -Xmx128m
35 * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -Xcheck:jni
36 * -XX:TieredStopAtLevel=1
37 * DeepSizeOf
38 *
39 * @run main/othervm -Xmx128m
40 * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -Xcheck:jni
41 * -XX:TieredStopAtLevel=2
42 * DeepSizeOf
43 *
44 * @run main/othervm -Xmx128m
45 * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -Xcheck:jni
46 * -XX:TieredStopAtLevel=3
47 * DeepSizeOf
48 *
49 * @run main/othervm -Xmx128m
50 * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -Xcheck:jni
51 * -XX:TieredStopAtLevel=4
52 * DeepSizeOf
53 *
54 * @run main/othervm -Xmx128m
55 * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -Xcheck:jni
56 * -XX:-TieredCompilation
57 * DeepSizeOf
58 */
59
60 /*
61 * @test
62 * @summary Test for Magic.deepSizeOf with zero-based compressed oops
63 * @library /test/lib
64 * @requires vm.bits == 64
65 *
66 * @run main/othervm -Xmx4g
67 * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -Xcheck:jni
68 * -Xint
69 * DeepSizeOf
70 *
71 * @run main/othervm -Xmx4g
72 * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -Xcheck:jni
73 * -XX:TieredStopAtLevel=1
74 * DeepSizeOf
75 *
76 * @run main/othervm -Xmx4g
77 * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -Xcheck:jni
78 * -XX:TieredStopAtLevel=2
79 * DeepSizeOf
80 *
81 * @run main/othervm -Xmx4g
82 * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -Xcheck:jni
83 * -XX:TieredStopAtLevel=3
84 * DeepSizeOf
85 *
86 * @run main/othervm -Xmx4g
87 * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -Xcheck:jni
88 * -XX:TieredStopAtLevel=4
89 * DeepSizeOf
90 *
91 * @run main/othervm -Xmx4g
92 * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -Xcheck:jni
93 * -XX:-TieredCompilation
94 * DeepSizeOf
95 */
96
97 /*
98 * @test
99 * @summary Test for Magic.deepSizeOf without compressed oops
100 * @library /test/lib
101 * @requires vm.bits == 64
102 *
103 * @run main/othervm -Xmx128m -XX:-UseCompressedOops
104 * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -Xcheck:jni
105 * -Xint
106 * DeepSizeOf
107 *
108 * @run main/othervm -Xmx128m -XX:-UseCompressedOops
109 * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -Xcheck:jni
110 * -XX:TieredStopAtLevel=1
111 * DeepSizeOf
112 *
113 * @run main/othervm -Xmx128m -XX:-UseCompressedOops
114 * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -Xcheck:jni
115 * -XX:-TieredCompilation
116 * DeepSizeOf
117 */
118
119 import net.shipilev.Magic;
120
121 public class DeepSizeOf {
122
123 public static void main(String ... args) {
124 testSame_newObject();
125 testSimpleHierarchy();
126 testPartialNulls();
127
128 testNodeChain(0);
129 testNodeChain(1);
130 testNodeChain(10);
131 testNodeChain(100);
132
133 testNodeTree();
134
135 testObjArray(0);
136 testObjArray(1);
137 testObjArray(10);
138 testObjArray(100);
139
140 testNulls();
141
142 testIncludeCheck();
143 testIncludeCheckDeep();
144 }
145
146 private static void testSame_newObject() {
147 for (int c = 0; c < MagicUtil.ITERS; c++) {
148 Object o = new Object();
149 MagicUtil.assertEquals(Magic.sizeOf(o), Magic.deepSizeOf(o));
150 }
151 }
152
153 private static void testNodeChain(int depth) {
154 Node n = new Node(null);
155 for (int d = 0; d < depth; d++) {
156 n = new Node(n);
157 }
158
159 for (int c = 0; c < MagicUtil.SHORT_ITERS; c++) {
160 MagicUtil.assertEquals(Magic.sizeOf(n)*(depth + 1), Magic.deepSizeOf(n));
161 }
162 }
163
164 private static class Node {
165 Node next;
166 public Node(Node n) { next = n; }
167 }
168
169 private static void testNodeTree() {
170 TreeNode r = new TreeNode(new TreeNode(new TreeNode(null, null), null), new TreeNode(null, null));
171 for (int c = 0; c < MagicUtil.SHORT_ITERS; c++) {
172 MagicUtil.assertEquals(Magic.sizeOf(r)*4, Magic.deepSizeOf(r));
173 }
174 }
175
176 private static class TreeNode {
177 TreeNode l, r;
178 public TreeNode(TreeNode l, TreeNode r) { this.l = l; this.r = r; }
179 }
180
181 private static void testObjArray(int size) {
182 Object o = new Object();
183 Object[] arr = new Object[size];
184 for (int d = 0; d < size; d++) {
185 arr[d] = new Object();
186 }
187
188 for (int c = 0; c < MagicUtil.SHORT_ITERS; c++) {
189 MagicUtil.assertEquals(Magic.sizeOf(arr) + Magic.sizeOf(o)*size, Magic.deepSizeOf(arr));
190 }
191 }
192
193 private static class A {
194 Object o1;
195 }
196
197 private static class B extends A {
198 Object o2;
199 }
200
201 private static void testSimpleHierarchy() {
202 for (int c = 0; c < MagicUtil.ITERS; c++) {
203 B b = new B();
204 b.o1 = new Object();
205 b.o2 = new Object();
206 MagicUtil.assertEquals(Magic.sizeOf(b) + Magic.sizeOf(b.o1) + Magic.sizeOf(b.o2), Magic.deepSizeOf(b));
207 }
208 }
209
210 private static class D {
211 Object o1;
212 Object o2;
213 }
214
215 private static void testPartialNulls() {
216 for (int c = 0; c < MagicUtil.ITERS; c++) {
217 D d = new D();
218 d.o1 = null;
219 d.o2 = new Object();
220 MagicUtil.assertEquals(Magic.sizeOf(d) + Magic.sizeOf(d.o2), Magic.deepSizeOf(d));
221 }
222 }
223
224 private static void testNulls() {
225 for (int c = 0; c < MagicUtil.ITERS; c++) {
226 try {
227 Magic.deepSizeOf(null);
228 MagicUtil.assertFail();
229 } catch (NullPointerException e) {
230 // expected
231 }
232 }
233 }
234
235 private static void testIncludeCheck() {
236 for (int i = 0; i < MagicUtil.ITERS; i++) {
237 Object o = new Object();
238 MagicUtil.assertEquals(42L, Magic.deepSizeOf(o, (obj) -> -42L));
239 }
240 }
241
242 private static void testIncludeCheckDeep() {
243 for (int i = 0; i < MagicUtil.ITERS; i++) {
244 DeepA a = new DeepA();
245 DeepB b = new DeepB();
246 DeepC c = new DeepC();
247 a.b = b;
248 b.c = c;
249 c.x = new Object();
250
251 long sA = Magic.sizeOf(a);
252 long sB = Magic.sizeOf(b);
253 long sC = Magic.sizeOf(c);
254 long sCX = Magic.sizeOf(c.x);
255
256 MagicUtil.assertEquals(sA,
257 Magic.deepSizeOf(a, (obj) -> {
258 if (obj instanceof DeepB)
259 return 0L; // don't consider DeepB (don't go deeper)
260 return Magic.DEEP_SIZE_OF_SHALLOW | Magic.DEEP_SIZE_OF_TRAVERSE;
261 }));
262
263 MagicUtil.assertEquals(sA + sC + sCX,
264 Magic.deepSizeOf(a, (obj) -> {
265 if (obj instanceof DeepB)
266 return Magic.DEEP_SIZE_OF_TRAVERSE; // don't consider DeepB (but its references!)
267 return Magic.DEEP_SIZE_OF_SHALLOW | Magic.DEEP_SIZE_OF_TRAVERSE;
268 }));
269
270 MagicUtil.assertEquals(sA,
271 Magic.deepSizeOf(a, (obj) -> {
272 if (obj instanceof DeepA)
273 return Magic.DEEP_SIZE_OF_SHALLOW; // consider DeepA, but don't go deeper
274 return Magic.DEEP_SIZE_OF_SHALLOW | Magic.DEEP_SIZE_OF_TRAVERSE;
275 }));
276
277 MagicUtil.assertEquals(sA + sB,
278 Magic.deepSizeOf(a, (obj) -> {
279 if (obj instanceof DeepB)
280 return Magic.DEEP_SIZE_OF_SHALLOW; // consider DeepB, but don't go deeper
281 return Magic.DEEP_SIZE_OF_SHALLOW | Magic.DEEP_SIZE_OF_TRAVERSE;
282 }));
283 }
284 }
285
286 private static class DeepA {
287 DeepB b;
288 }
289
290 private static class DeepB {
291 DeepC c;
292 }
293
294 private static class DeepC {
295 Object x;
296 }
297
298 }