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 }