comparison agent/src/share/classes/sun/jvm/hotspot/utilities/AbstractHeapGraphWriter.java @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children ba764ed4b6f2
comparison
equal deleted inserted replaced
-1:000000000000 0:a61af66fc99e
1 /*
2 * Copyright 2004-2005 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.debugger.*;
29 import sun.jvm.hotspot.memory.*;
30 import sun.jvm.hotspot.oops.*;
31 import sun.jvm.hotspot.runtime.*;
32
33 /**
34 * This is abstract base class for heap graph writers. This class does
35 * not assume any file format for the heap graph. It hides heap
36 * iteration, object (fields) iteration mechanism from derived
37 * classes. This class does not even accept OutputStream etc. so that
38 * derived class can construct specific writer/filter from input
39 * stream.
40 */
41
42 public abstract class AbstractHeapGraphWriter implements HeapGraphWriter {
43 // the function iterates heap and calls Oop type specific writers
44 protected void write() throws IOException {
45 SymbolTable symTbl = VM.getVM().getSymbolTable();
46 javaLangClass = symTbl.probe("java/lang/Class");
47 javaLangString = symTbl.probe("java/lang/String");
48 javaLangThread = symTbl.probe("java/lang/Thread");
49 ObjectHeap heap = VM.getVM().getObjectHeap();
50 try {
51 heap.iterate(new DefaultHeapVisitor() {
52 public void prologue(long usedSize) {
53 try {
54 writeHeapHeader();
55 } catch (IOException exp) {
56 throw new RuntimeException(exp);
57 }
58 }
59
60 public boolean doObj(Oop oop) {
61 try {
62 if (oop instanceof TypeArray) {
63 writePrimitiveArray((TypeArray)oop);
64 } else if (oop instanceof ObjArray) {
65 Klass klass = oop.getKlass();
66 ObjArrayKlass oak = (ObjArrayKlass) klass;
67 Klass bottomType = oak.getBottomKlass();
68 if (bottomType instanceof InstanceKlass ||
69 bottomType instanceof TypeArrayKlass) {
70 writeObjectArray((ObjArray)oop);
71 } else {
72 writeInternalObject(oop);
73 }
74 } else if (oop instanceof Instance) {
75 Instance instance = (Instance) oop;
76 Klass klass = instance.getKlass();
77 Symbol name = klass.getName();
78 if (name.equals(javaLangString)) {
79 writeString(instance);
80 } else if (name.equals(javaLangClass)) {
81 writeClass(instance);
82 } else if (name.equals(javaLangThread)) {
83 writeThread(instance);
84 } else {
85 klass = klass.getSuper();
86 while (klass != null) {
87 name = klass.getName();
88 if (name.equals(javaLangThread)) {
89 writeThread(instance);
90 return false;
91 }
92 klass = klass.getSuper();
93 }
94 writeInstance(instance);
95 }
96 } else {
97 // not-a-Java-visible oop
98 writeInternalObject(oop);
99 }
100 } catch (IOException exp) {
101 throw new RuntimeException(exp);
102 }
103 return false;
104 }
105
106 public void epilogue() {
107 try {
108 writeHeapFooter();
109 } catch (IOException exp) {
110 throw new RuntimeException(exp);
111 }
112 }
113 });
114
115 // write JavaThreads
116 writeJavaThreads();
117
118 // write JNI global handles
119 writeGlobalJNIHandles();
120
121 } catch (RuntimeException re) {
122 handleRuntimeException(re);
123 }
124 }
125
126 protected void writeJavaThreads() throws IOException {
127 Threads threads = VM.getVM().getThreads();
128 JavaThread jt = threads.first();
129 int index = 1;
130 while (jt != null) {
131 if (jt.getThreadObj() != null) {
132 // Note that the thread serial number range is 1-to-N
133 writeJavaThread(jt, index);
134 index++;
135 }
136 jt = jt.next();
137 }
138 }
139
140 protected void writeJavaThread(JavaThread jt, int index)
141 throws IOException {
142 }
143
144 protected void writeGlobalJNIHandles() throws IOException {
145 JNIHandles handles = VM.getVM().getJNIHandles();
146 JNIHandleBlock blk = handles.globalHandles();
147 if (blk != null) {
148 try {
149 blk.oopsDo(new AddressVisitor() {
150 public void visitAddress(Address handleAddr) {
151 try {
152 if (handleAddr != null) {
153 writeGlobalJNIHandle(handleAddr);
154 }
155 } catch (IOException exp) {
156 throw new RuntimeException(exp);
157 }
158 }
159 });
160 } catch (RuntimeException re) {
161 handleRuntimeException(re);
162 }
163 }
164 }
165
166 protected void writeGlobalJNIHandle(Address handleAddr) throws IOException {
167 }
168
169 protected void writeHeapHeader() throws IOException {
170 }
171
172 // write non-Java-visible (hotspot internal) object
173 protected void writeInternalObject(Oop oop) throws IOException {
174 }
175
176 // write Java primitive array
177 protected void writePrimitiveArray(TypeArray array) throws IOException {
178 writeObject(array);
179 }
180
181 // write Java object array
182 protected void writeObjectArray(ObjArray array) throws IOException {
183 writeObject(array);
184 }
185
186 protected void writeInstance(Instance instance) throws IOException {
187 writeObject(instance);
188 }
189
190 protected void writeString(Instance instance) throws IOException {
191 writeInstance(instance);
192 }
193
194 protected void writeClass(Instance instance) throws IOException {
195 writeInstance(instance);
196 }
197
198 protected void writeThread(Instance instance) throws IOException {
199 writeInstance(instance);
200 }
201
202 protected void writeObject(Oop oop) throws IOException {
203 writeObjectHeader(oop);
204 writeObjectFields(oop);
205 writeObjectFooter(oop);
206 }
207
208 protected void writeObjectHeader(Oop oop) throws IOException {
209 }
210
211 // write instance fields of given object
212 protected void writeObjectFields(final Oop oop) throws IOException {
213 try {
214 oop.iterate(new DefaultOopVisitor() {
215 public void doOop(OopField field, boolean isVMField) {
216 try {
217 Oop ref = field.getValue(oop);
218 if (ref instanceof TypeArray ||
219 ref instanceof ObjArray ||
220 ref instanceof Instance) {
221 writeReferenceField(oop, field);
222 } else {
223 writeInternalReferenceField(oop, field);
224 }
225 } catch (IOException exp) {
226 throw new RuntimeException(exp);
227 }
228 }
229
230 public void doByte(ByteField field, boolean isVMField) {
231 try {
232 writeByteField(oop, field);
233 } catch (IOException exp) {
234 throw new RuntimeException(exp);
235 }
236 }
237
238 public void doChar(CharField field, boolean isVMField) {
239 try {
240 writeCharField(oop, field);
241 } catch (IOException exp) {
242 throw new RuntimeException(exp);
243 }
244 }
245
246 public void doBoolean(BooleanField field, boolean vField) {
247 try {
248 writeBooleanField(oop, field);
249 } catch (IOException exp) {
250 throw new RuntimeException(exp);
251 }
252 }
253
254 public void doShort(ShortField field, boolean isVMField) {
255 try {
256 writeShortField(oop, field);
257 } catch (IOException exp) {
258 throw new RuntimeException(exp);
259 }
260 }
261
262 public void doInt(IntField field, boolean isVMField) {
263 try {
264 writeIntField(oop, field);
265 } catch (IOException exp) {
266 throw new RuntimeException(exp);
267 }
268 }
269
270 public void doLong(LongField field, boolean isVMField) {
271 try {
272 writeLongField(oop, field);
273 } catch (IOException exp) {
274 throw new RuntimeException(exp);
275 }
276 }
277
278 public void doFloat(FloatField field, boolean isVMField) {
279 try {
280 writeFloatField(oop, field);
281 } catch (IOException exp) {
282 throw new RuntimeException(exp);
283 }
284 }
285
286 public void doDouble(DoubleField field, boolean vField) {
287 try {
288 writeDoubleField(oop, field);
289 } catch (IOException exp) {
290 throw new RuntimeException(exp);
291 }
292 }
293 }, false);
294 } catch (RuntimeException re) {
295 handleRuntimeException(re);
296 }
297 }
298
299 // object field writers
300 protected void writeInternalReferenceField(Oop oop, OopField field)
301 throws IOException {
302 }
303
304 protected void writeReferenceField(Oop oop, OopField field)
305 throws IOException {
306 }
307
308 protected void writeByteField(Oop oop, ByteField field)
309 throws IOException {
310 }
311
312 protected void writeCharField(Oop oop, CharField field)
313 throws IOException {
314 }
315
316 protected void writeBooleanField(Oop oop, BooleanField field)
317 throws IOException {
318 }
319
320 protected void writeShortField(Oop oop, ShortField field)
321 throws IOException {
322 }
323
324 protected void writeIntField(Oop oop, IntField field)
325 throws IOException {
326 }
327
328 protected void writeLongField(Oop oop, LongField field)
329 throws IOException {
330 }
331
332 protected void writeFloatField(Oop oop, FloatField field)
333 throws IOException {
334 }
335
336 protected void writeDoubleField(Oop oop, DoubleField field)
337 throws IOException {
338 }
339
340 protected void writeObjectFooter(Oop oop) throws IOException {
341 }
342
343 protected void writeHeapFooter() throws IOException {
344 }
345
346 // HeapVisitor, OopVisitor methods can't throw any non-runtime
347 // exception. But, derived class write methods (which are called
348 // from visitor callbacks) may throw IOException. Hence, we throw
349 // RuntimeException with origianal IOException as cause from the
350 // visitor methods. This method gets back the original IOException
351 // (if any) and re-throws the same.
352 protected void handleRuntimeException(RuntimeException re)
353 throws IOException {
354 Throwable cause = re.getCause();
355 if (cause != null && cause instanceof IOException) {
356 throw (IOException) cause;
357 } else {
358 // some other RuntimeException, just re-throw
359 throw re;
360 }
361 }
362
363 // whether a given oop is Java visible or hotspot internal?
364 protected boolean isJavaVisible(Oop oop) {
365 if (oop instanceof Instance || oop instanceof TypeArray) {
366 return true;
367 } else if (oop instanceof ObjArray) {
368 ObjArrayKlass oak = (ObjArrayKlass) oop.getKlass();
369 Klass bottomKlass = oak.getBottomKlass();
370 return bottomKlass instanceof InstanceKlass ||
371 bottomKlass instanceof TypeArrayKlass;
372 } else {
373 return false;
374 }
375 }
376
377 protected Symbol javaLangClass;
378 protected Symbol javaLangString;
379 protected Symbol javaLangThread;
380 }