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 
33 package jdk.test.lib.hprof.model;
34 
35 import 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 
48 public 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 
Root(long id, long refererId, int type, String description)73     public Root(long id, long refererId, int type, String description) {
74         this(id, refererId, type, description, null);
75     }
76 
77 
Root(long id, long refererId, int type, String description, StackTrace stackTrace)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 
getId()87     public long getId() {
88         return id;
89     }
90 
getIdString()91     public String getIdString() {
92         return Misc.toHex(id);
93     }
94 
getDescription()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      */
getType()107     public int getType() {
108         return type;
109     }
110 
getTypeName()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      */
mostInteresting(Root other)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      */
getReferer()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      */
getStackTrace()150     public StackTrace getStackTrace() {
151         return stackTrace;
152     }
153 
154     /**
155      * @return The index of this root in Snapshot.roots
156      */
getIndex()157     public int getIndex() {
158         return index;
159     }
160 
resolve(Snapshot ss)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 
setIndex(int i)170     void setIndex(int i) {
171         index = i;
172     }
173 
174 }
175