ReachableObjects.java revision 2779:56d1e05e0def
164987Smsmith/*
273050Smsmith * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
364987Smsmith * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
464987Smsmith *
564987Smsmith * This code is free software; you can redistribute it and/or modify it
664987Smsmith * under the terms of the GNU General Public License version 2 only, as
764987Smsmith * published by the Free Software Foundation.  Oracle designates this
864987Smsmith * particular file as subject to the "Classpath" exception as provided
964987Smsmith * by Oracle in the LICENSE file that accompanied this code.
1064987Smsmith *
1164987Smsmith * This code is distributed in the hope that it will be useful, but WITHOUT
1264987Smsmith * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1364987Smsmith * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1464987Smsmith * version 2 for more details (a copy is included in the LICENSE file that
1564987Smsmith * accompanied this code).
1664987Smsmith *
1764987Smsmith * You should have received a copy of the GNU General Public License version
1864987Smsmith * 2 along with this work; if not, write to the Free Software Foundation,
1964987Smsmith * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2064987Smsmith *
2164987Smsmith * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2264987Smsmith * or visit www.oracle.com if you need additional information or have any
2364987Smsmith * questions.
2464987Smsmith */
2564987Smsmith
2664987Smsmith
2764987Smsmith/*
2864987Smsmith * The Original Code is HAT. The Initial Developer of the
2964987Smsmith * Original Code is Bill Foote, with contributions from others
3064987Smsmith * at JavaSoft/Sun.
3164987Smsmith */
3264987Smsmith
3364987Smsmithpackage jdk.test.lib.hprof.model;
3464987Smsmith
3564987Smsmithimport java.util.Vector;
3664987Smsmithimport java.util.Hashtable;
3764987Smsmithimport java.util.Enumeration;
3864987Smsmith
3964987Smsmithimport jdk.test.lib.hprof.util.ArraySorter;
4064987Smsmithimport jdk.test.lib.hprof.util.Comparer;
4179695Smsmith
4264987Smsmith/**
4364987Smsmith * @author      A. Sundararajan
4464987Smsmith */
4564987Smsmith
4664987Smsmithpublic class ReachableObjects {
4779695Smsmith    public ReachableObjects(JavaHeapObject root,
4864987Smsmith                            final ReachableExcludes excludes) {
4979695Smsmith        this.root = root;
5079695Smsmith
5179695Smsmith        final Hashtable<JavaHeapObject, JavaHeapObject> bag = new Hashtable<JavaHeapObject, JavaHeapObject>();
5279695Smsmith        final Hashtable<String, String> fieldsExcluded = new Hashtable<String, String>();  //Bag<String>
5379695Smsmith        final Hashtable<String, String> fieldsUsed = new Hashtable<String, String>();   // Bag<String>
5464987Smsmith        JavaHeapObjectVisitor visitor = new AbstractJavaHeapObjectVisitor() {
5564987Smsmith            public void visit(JavaHeapObject t) {
5673050Smsmith                // Size is zero for things like integer fields
5764987Smsmith                if (t != null && t.getSize() > 0 && bag.get(t) == null) {
5864987Smsmith                    bag.put(t, t);
5964987Smsmith                    t.visitReferencedObjects(this);
6064987Smsmith                }
6164987Smsmith            }
6273050Smsmith
6373050Smsmith            public boolean mightExclude() {
6473050Smsmith                return excludes != null;
6573050Smsmith            }
6673050Smsmith
6773050Smsmith            public boolean exclude(JavaClass clazz, JavaField f) {
6864987Smsmith                if (excludes == null) {
6964987Smsmith                    return false;
7064987Smsmith                }
7164987Smsmith                String nm = clazz.getName() + "." + f.getName();
7264987Smsmith                if (excludes.isExcluded(nm)) {
7364987Smsmith                    fieldsExcluded.put(nm, nm);
7464987Smsmith                    return true;
7587599Sobrien                } else {
7687599Sobrien                    fieldsUsed.put(nm, nm);
7764987Smsmith                    return false;
7864987Smsmith                }
7964987Smsmith            }
8064987Smsmith        };
8164987Smsmith        // Put the closure of root and all objects reachable from root into
8264987Smsmith        // bag (depth first), but don't include root:
8364987Smsmith        visitor.visit(root);
8464987Smsmith        bag.remove(root);
8564987Smsmith
8664987Smsmith        // Now grab the elements into a vector, and sort it in decreasing size
8764987Smsmith        JavaThing[] things = new JavaThing[bag.size()];
8864987Smsmith        int i = 0;
8964987Smsmith        for (Enumeration<JavaHeapObject> e = bag.elements(); e.hasMoreElements(); ) {
9064987Smsmith            things[i++] = (JavaThing) e.nextElement();
9164987Smsmith        }
9264987Smsmith        ArraySorter.sort(things, new Comparer() {
9364987Smsmith            public int compare(Object lhs, Object rhs) {
9464987Smsmith                JavaThing left = (JavaThing) lhs;
9564987Smsmith                JavaThing right = (JavaThing) rhs;
9664987Smsmith                long diff = right.getSize() - left.getSize();
9764987Smsmith                if (diff != 0) {
9864987Smsmith                    return Long.signum(diff);
9964987Smsmith                }
10064987Smsmith                return left.compareTo(right);
10164987Smsmith            }
10264987Smsmith        });
10364987Smsmith        this.reachables = things;
10464987Smsmith
10573050Smsmith        this.totalSize = root.getSize();
10673050Smsmith        for (i = 0; i < things.length; i++) {
10773050Smsmith            this.totalSize += things[i].getSize();
10873050Smsmith        }
10964987Smsmith
11064987Smsmith        excludedFields = getElements(fieldsExcluded);
11164987Smsmith        usedFields = getElements(fieldsUsed);
11264987Smsmith    }
11364987Smsmith
11464987Smsmith    public JavaHeapObject getRoot() {
11564987Smsmith        return root;
11664987Smsmith    }
11764987Smsmith
11864987Smsmith    public JavaThing[] getReachables() {
11964987Smsmith        return reachables;
12073050Smsmith    }
12173050Smsmith
12273050Smsmith    public long getTotalSize() {
12373050Smsmith        return totalSize;
12473050Smsmith    }
125246713Skib
12664987Smsmith    public String[] getExcludedFields() {
12764987Smsmith        return excludedFields;
12864987Smsmith    }
12964987Smsmith
13064987Smsmith    public String[] getUsedFields() {
13164987Smsmith        return usedFields;
13264987Smsmith    }
13364987Smsmith
13464987Smsmith    private String[] getElements(Hashtable<?, ?> ht) {
13564987Smsmith        Object[] keys = ht.keySet().toArray();
13664987Smsmith        int len = keys.length;
13764987Smsmith        String[] res = new String[len];
13864987Smsmith        System.arraycopy(keys, 0, res, 0, len);
13964987Smsmith        ArraySorter.sortArrayOfStrings(res);
140110479Sscottl        return res;
14164987Smsmith    }
14264987Smsmith
14364987Smsmith    private JavaHeapObject root;
14464987Smsmith    private JavaThing[] reachables;
14564987Smsmith    private String[]  excludedFields;
14664987Smsmith    private String[]  usedFields;
14764987Smsmith    private long totalSize;
14864987Smsmith}
14979695Smsmith