0
|
1 /*
|
|
2 * Copyright 2000-2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 * have any questions.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 package sun.jvm.hotspot.utilities;
|
|
26
|
|
27 import java.io.*;
|
|
28 import sun.jvm.hotspot.code.*;
|
|
29 import sun.jvm.hotspot.debugger.*;
|
|
30 import sun.jvm.hotspot.gc_interface.*;
|
|
31 import sun.jvm.hotspot.interpreter.*;
|
|
32 import sun.jvm.hotspot.runtime.*;
|
|
33 import sun.jvm.hotspot.memory.*;
|
|
34
|
|
35 /** This class attempts to describe possible locations of pointers in
|
|
36 the VM. */
|
|
37
|
|
38 public class PointerLocation {
|
|
39 //////////////////////////////////////////////////////////////////
|
|
40 // //
|
|
41 // These are package private to simplify the implementation and //
|
|
42 // interaction with PointerFinder //
|
|
43 // //
|
|
44 //////////////////////////////////////////////////////////////////
|
|
45
|
|
46 Address addr;
|
|
47
|
|
48 CollectedHeap heap;
|
|
49 Generation gen;
|
|
50 Generation permGen;
|
|
51
|
|
52 // If UseTLAB was enabled and the pointer was found in a
|
|
53 // currently-active TLAB, these will be set
|
|
54 boolean inTLAB;
|
|
55 JavaThread tlabThread;
|
|
56 ThreadLocalAllocBuffer tlab;
|
|
57
|
|
58 // Generated code locations
|
|
59 boolean inInterpreter;
|
|
60 boolean inCodeCache;
|
|
61
|
|
62 // FIXME: add other locations like VTableStubs, StubRoutines, maybe
|
|
63 // even "on thread x's stack"
|
|
64
|
|
65 InterpreterCodelet interpreterCodelet;
|
|
66 CodeBlob blob;
|
|
67 // FIXME: add more detail about CodeBlob
|
|
68 boolean inBlobInstructions;
|
|
69 boolean inBlobData;
|
|
70 boolean inBlobOops;
|
|
71 boolean inBlobUnknownLocation;
|
|
72
|
|
73 boolean inStrongGlobalJNIHandleBlock;
|
|
74 boolean inWeakGlobalJNIHandleBlock;
|
|
75 boolean inLocalJNIHandleBlock;
|
|
76 JNIHandleBlock handleBlock;
|
|
77 sun.jvm.hotspot.runtime.Thread handleThread;
|
|
78
|
|
79 public PointerLocation(Address addr) {
|
|
80 this.addr = addr;
|
|
81 }
|
|
82
|
|
83 public boolean isInHeap() {
|
|
84 return (heap != null || (gen != null) || (permGen != null));
|
|
85 }
|
|
86
|
|
87 public boolean isInNewGen() {
|
|
88 return ((gen != null) && (gen.level() == 0));
|
|
89 }
|
|
90
|
|
91 public boolean isInOldGen() {
|
|
92 return ((gen != null) && (gen.level() == 1));
|
|
93 }
|
|
94
|
|
95 public boolean isInPermGen() {
|
|
96 return (permGen != null);
|
|
97 }
|
|
98
|
|
99 public boolean inOtherGen() {
|
|
100 return (!isInNewGen() && !isInOldGen() && !isInPermGen());
|
|
101 }
|
|
102
|
|
103 /** Only valid if isInHeap() */
|
|
104 public Generation getGeneration() {
|
|
105 if (gen != null) {
|
|
106 return gen;
|
|
107 } else {
|
|
108 return permGen;
|
|
109 }
|
|
110 }
|
|
111
|
|
112 /** This may be true if isInNewGen is also true */
|
|
113 public boolean isInTLAB() {
|
|
114 return inTLAB;
|
|
115 }
|
|
116
|
|
117 /** Only valid if isInTLAB() returns true */
|
|
118 public JavaThread getTLABThread() {
|
|
119 return tlabThread;
|
|
120 }
|
|
121
|
|
122 /** Only valid if isInTLAB() returns true */
|
|
123 public ThreadLocalAllocBuffer getTLAB() {
|
|
124 return tlab;
|
|
125 }
|
|
126
|
|
127 public boolean isInInterpreter() {
|
|
128 return inInterpreter;
|
|
129 }
|
|
130
|
|
131 /** For now, only valid if isInInterpreter is true */
|
|
132 public InterpreterCodelet getInterpreterCodelet() {
|
|
133 return interpreterCodelet;
|
|
134 }
|
|
135
|
|
136 public boolean isInCodeCache() {
|
|
137 return inCodeCache;
|
|
138 }
|
|
139
|
|
140 /** For now, only valid if isInCodeCache is true */
|
|
141 public CodeBlob getCodeBlob() {
|
|
142 return blob;
|
|
143 }
|
|
144
|
|
145 public boolean isInBlobInstructions() {
|
|
146 return inBlobInstructions;
|
|
147 }
|
|
148
|
|
149 public boolean isInBlobData() {
|
|
150 return inBlobData;
|
|
151 }
|
|
152
|
|
153 public boolean isInBlobOops() {
|
|
154 return inBlobOops;
|
|
155 }
|
|
156
|
|
157 public boolean isInBlobUnknownLocation() {
|
|
158 return inBlobUnknownLocation;
|
|
159 }
|
|
160
|
|
161 public boolean isInStrongGlobalJNIHandleBlock() {
|
|
162 return inStrongGlobalJNIHandleBlock;
|
|
163 }
|
|
164
|
|
165 public boolean isInWeakGlobalJNIHandleBlock() {
|
|
166 return inWeakGlobalJNIHandleBlock;
|
|
167 }
|
|
168
|
|
169 public boolean isInLocalJNIHandleBlock() {
|
|
170 return inLocalJNIHandleBlock;
|
|
171 }
|
|
172
|
|
173 /** Only valid if isInStrongGlobalJNIHandleBlock,
|
|
174 isInWeakGlobalJNIHandleBlock, or isInLocalJNIHandleBlock is true */
|
|
175 public JNIHandleBlock getJNIHandleBlock() {
|
|
176 return handleBlock;
|
|
177 }
|
|
178
|
|
179 /** Only valid if isInLocalJNIHandleBlock is true */
|
|
180 public sun.jvm.hotspot.runtime.Thread getJNIHandleThread() {
|
|
181 return handleThread;
|
|
182 }
|
|
183
|
|
184 public boolean isUnknown() {
|
|
185 return (!(isInHeap() || isInInterpreter() || isInCodeCache() ||
|
|
186 isInStrongGlobalJNIHandleBlock() || isInWeakGlobalJNIHandleBlock() || isInLocalJNIHandleBlock()));
|
|
187 }
|
|
188
|
|
189 public String toString() {
|
|
190 ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
|
191 printOn(new PrintStream(bos));
|
|
192 return bos.toString();
|
|
193 }
|
|
194
|
|
195 public void print() {
|
|
196 printOn(System.out);
|
|
197 }
|
|
198
|
|
199 public void printOn(PrintStream tty) {
|
|
200 tty.print("Address ");
|
|
201 if (addr == null) {
|
|
202 tty.print("0x0");
|
|
203 } else {
|
|
204 tty.print(addr.toString());
|
|
205 }
|
|
206 tty.print(": ");
|
|
207 if (isInHeap()) {
|
|
208 if (isInTLAB()) {
|
|
209 tty.print("In thread-local allocation buffer for thread \"" +
|
|
210 getTLABThread().getThreadName() + "\" (");
|
|
211 getTLABThread().printThreadIDOn(tty);
|
|
212 tty.print(") ");
|
|
213 getTLAB().printOn(tty);
|
|
214 } else {
|
|
215 if (isInNewGen()) {
|
|
216 tty.print("In new generation ");
|
|
217 } else if (isInOldGen()) {
|
|
218 tty.print("In old generation ");
|
|
219 } else if (isInPermGen()) {
|
|
220 tty.print("In perm generation ");
|
|
221 } else if (gen != null) {
|
|
222 tty.print("In Generation " + getGeneration().level());
|
|
223 } else {
|
|
224 tty.print("In unknown section of Java heap");
|
|
225 }
|
|
226 if (getGeneration() != null) {
|
|
227 getGeneration().printOn(tty);
|
|
228 }
|
|
229 }
|
|
230 } else if (isInInterpreter()) {
|
|
231 tty.println("In interpreter codelet \"" + interpreterCodelet.getDescription() + "\"");
|
|
232 interpreterCodelet.printOn(tty);
|
|
233 } else if (isInCodeCache()) {
|
|
234 CodeBlob b = getCodeBlob();
|
|
235 tty.print("In ");
|
|
236 if (isInBlobInstructions()) {
|
|
237 tty.print("instructions");
|
|
238 } else if (isInBlobData()) {
|
|
239 tty.print("data");
|
|
240 } else if (isInBlobOops()) {
|
|
241 tty.print("oops");
|
|
242 } else {
|
|
243 if (Assert.ASSERTS_ENABLED) {
|
|
244 Assert.that(isInBlobUnknownLocation(), "Should have known location in CodeBlob");
|
|
245 }
|
|
246 tty.print("unknown location");
|
|
247 }
|
|
248 tty.print(" in ");
|
|
249 b.printOn(tty);
|
|
250
|
|
251 // FIXME: add more detail
|
|
252 } else if (isInStrongGlobalJNIHandleBlock() ||
|
|
253 isInWeakGlobalJNIHandleBlock() ||
|
|
254 isInLocalJNIHandleBlock()) {
|
|
255 tty.print("In ");
|
|
256 if (isInStrongGlobalJNIHandleBlock()) {
|
|
257 tty.print("strong global");
|
|
258 } else if (isInWeakGlobalJNIHandleBlock()) {
|
|
259 tty.print("weak global");
|
|
260 } else {
|
|
261 tty.print("thread-local");
|
|
262 }
|
|
263 tty.print(" JNI handle block (" + handleBlock.top() + " handle slots present)");
|
|
264 if (isInLocalJNIHandleBlock()) {
|
|
265 if (handleThread.isJavaThread()) {
|
|
266 tty.print(" for JavaThread ");
|
|
267 ((JavaThread) handleThread).printThreadIDOn(tty);
|
|
268 } else {
|
|
269 tty.print("for a non-Java Thread");
|
|
270 }
|
|
271 }
|
|
272 } else {
|
|
273 // This must be last
|
|
274 if (Assert.ASSERTS_ENABLED) {
|
|
275 Assert.that(isUnknown(), "Should have unknown location");
|
|
276 }
|
|
277 tty.print("In unknown location");
|
|
278 }
|
|
279 }
|
|
280 }
|