Root.java revision 2224:2a8815d86b93
1/*
2 * Copyright (c) 1997, 2016, 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.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26
27/*
28 * The Original Code is HAT. The Initial Developer of the
29 * Original Code is Bill Foote, with contributions from others
30 * at JavaSoft/Sun.
31 */
32
33package jdk.test.lib.hprof.model;
34
35import jdk.test.lib.hprof.util.Misc;
36
37/**
38 *
39 * @author      Bill Foote
40 */
41
42
43/**
44 * Represents a member of the rootset, that is, one of the objects that
45 * the GC starts from when marking reachable objects.
46 */
47
48public class Root {
49
50    private long id;            // ID of the JavaThing we refer to
51    private long refererId;     // Thread or Class responsible for this, or 0
52    private int index = -1;             // Index in Snapshot.roots
53    private int type;
54    private String description;
55    private JavaHeapObject referer = null;
56    private StackTrace stackTrace = null;
57
58    // Values for type.  Higher values are more interesting -- see getType().
59    // See also getTypeName()
60    public final static int INVALID_TYPE = 0;
61    public final static int UNKNOWN = 1;
62    public final static int SYSTEM_CLASS = 2;
63
64    public final static int NATIVE_LOCAL = 3;
65    public final static int NATIVE_STATIC = 4;
66    public final static int THREAD_BLOCK = 5;
67    public final static int BUSY_MONITOR = 6;
68    public final static int JAVA_LOCAL = 7;
69    public final static int NATIVE_STACK = 8;
70    public final static int JAVA_STATIC = 9;
71
72
73    public Root(long id, long refererId, int type, String description) {
74        this(id, refererId, type, description, null);
75    }
76
77
78    public Root(long id, long refererId, int type, String description,
79                StackTrace stackTrace) {
80        this.id = id;
81        this.refererId = refererId;
82        this.type = type;
83        this.description = description;
84        this.stackTrace = stackTrace;
85    }
86
87    public long getId() {
88        return id;
89    }
90
91    public String getIdString() {
92        return Misc.toHex(id);
93    }
94
95    public String getDescription() {
96        if ("".equals(description)) {
97            return getTypeName() + " Reference";
98        } else {
99            return description;
100        }
101    }
102
103    /**
104     * Return type.  We guarantee that more interesting roots will have
105     * a type that is numerically higher.
106     */
107    public int getType() {
108        return type;
109    }
110
111    public String getTypeName() {
112        switch(type) {
113            case INVALID_TYPE:          return "Invalid (?!?)";
114            case UNKNOWN:               return "Unknown";
115            case SYSTEM_CLASS:          return "System Class";
116            case NATIVE_LOCAL:          return "JNI Local";
117            case NATIVE_STATIC:         return "JNI Global";
118            case THREAD_BLOCK:          return "Thread Block";
119            case BUSY_MONITOR:          return "Busy Monitor";
120            case JAVA_LOCAL:            return "Java Local";
121            case NATIVE_STACK:          return "Native Stack (possibly Java local)";
122            case JAVA_STATIC:           return "Java Static";
123            default:                    return "??";
124        }
125    }
126
127    /**
128     * Given two Root instances, return the one that is most interesting.
129     */
130    public Root mostInteresting(Root other) {
131        if (other.type > this.type) {
132            return other;
133        } else {
134            return this;
135        }
136    }
137
138    /**
139     * Get the object that's responsible for this root, if there is one.
140     * This will be null, a Thread object, or a Class object.
141     */
142    public JavaHeapObject getReferer() {
143        return referer;
144    }
145
146    /**
147     * @return the stack trace responsible for this root, or null if there
148     * is none.
149     */
150    public StackTrace getStackTrace() {
151        return stackTrace;
152    }
153
154    /**
155     * @return The index of this root in Snapshot.roots
156     */
157    public int getIndex() {
158        return index;
159    }
160
161    void resolve(Snapshot ss) {
162        if (refererId != 0) {
163            referer = ss.findThing(refererId);
164        }
165        if (stackTrace != null) {
166            stackTrace.resolve(ss);
167        }
168    }
169
170    void setIndex(int i) {
171        index = i;
172    }
173
174}
175