Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/AbstractHeapGraphWriter.java
41161 views
1
/*
2
* Copyright (c) 2004, 2019, 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.
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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* 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.gc.shared.OopStorage;
30
import sun.jvm.hotspot.memory.*;
31
import sun.jvm.hotspot.oops.*;
32
import sun.jvm.hotspot.runtime.*;
33
34
/**
35
* This is abstract base class for heap graph writers. This class does
36
* not assume any file format for the heap graph. It hides heap
37
* iteration, object (fields) iteration mechanism from derived
38
* classes. This class does not even accept OutputStream etc. so that
39
* derived class can construct specific writer/filter from input
40
* stream.
41
*/
42
43
public abstract class AbstractHeapGraphWriter implements HeapGraphWriter {
44
// the function iterates heap and calls Oop type specific writers
45
protected void write() throws IOException {
46
javaLangClass = "java/lang/Class";
47
javaLangString = "java/lang/String";
48
javaLangThread = "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
writeHeapRecordPrologue();
63
if (oop instanceof TypeArray) {
64
writePrimitiveArray((TypeArray)oop);
65
} else if (oop instanceof ObjArray) {
66
Klass klass = oop.getKlass();
67
ObjArrayKlass oak = (ObjArrayKlass) klass;
68
Klass bottomType = oak.getBottomKlass();
69
if (bottomType instanceof InstanceKlass ||
70
bottomType instanceof TypeArrayKlass) {
71
writeObjectArray((ObjArray)oop);
72
} else {
73
writeInternalObject(oop);
74
}
75
} else if (oop instanceof Instance) {
76
Instance instance = (Instance) oop;
77
Klass klass = instance.getKlass();
78
Symbol name = klass.getName();
79
if (name.equals(javaLangString)) {
80
writeString(instance);
81
} else if (name.equals(javaLangClass)) {
82
writeClass(instance);
83
} else if (name.equals(javaLangThread)) {
84
writeThread(instance);
85
} else {
86
klass = klass.getSuper();
87
while (klass != null) {
88
name = klass.getName();
89
if (name.equals(javaLangThread)) {
90
writeThread(instance);
91
return false;
92
}
93
klass = klass.getSuper();
94
}
95
writeInstance(instance);
96
}
97
} else {
98
// not-a-Java-visible oop
99
writeInternalObject(oop);
100
}
101
writeHeapRecordEpilogue();
102
} catch (IOException exp) {
103
throw new RuntimeException(exp);
104
}
105
return false;
106
}
107
108
public void epilogue() {
109
try {
110
writeHeapFooter();
111
} catch (IOException exp) {
112
throw new RuntimeException(exp);
113
}
114
}
115
});
116
117
writeHeapRecordPrologue();
118
119
// write JavaThreads
120
writeJavaThreads();
121
122
// write JNI global handles
123
writeGlobalJNIHandles();
124
125
} catch (RuntimeException re) {
126
handleRuntimeException(re);
127
}
128
}
129
130
protected void writeJavaThreads() throws IOException {
131
Threads threads = VM.getVM().getThreads();
132
for (int i = 0; i < threads.getNumberOfThreads(); i++) {
133
JavaThread jt = threads.getJavaThreadAt(i);
134
if (jt.getThreadObj() != null) {
135
// Note that the thread serial number range is 1-to-N
136
writeJavaThread(jt, i + 1);
137
}
138
}
139
}
140
141
protected void writeJavaThread(JavaThread jt, int index)
142
throws IOException {
143
}
144
145
protected void writeGlobalJNIHandles() throws IOException {
146
JNIHandles handles = VM.getVM().getJNIHandles();
147
OopStorage blk = handles.globalHandles();
148
if (blk != null) {
149
try {
150
blk.oopsDo(new AddressVisitor() {
151
public void visitAddress(Address handleAddr) {
152
try {
153
if (handleAddr != null) {
154
writeGlobalJNIHandle(handleAddr);
155
}
156
} catch (IOException exp) {
157
throw new RuntimeException(exp);
158
}
159
}
160
public void visitCompOopAddress(Address handleAddr) {
161
throw new RuntimeException("Should not reach here. JNIHandles are not compressed");
162
}
163
});
164
} catch (RuntimeException re) {
165
handleRuntimeException(re);
166
}
167
}
168
}
169
170
protected void writeGlobalJNIHandle(Address handleAddr) throws IOException {
171
}
172
173
protected void writeHeapHeader() throws IOException {
174
}
175
176
// write non-Java-visible (hotspot internal) object
177
protected void writeInternalObject(Oop oop) throws IOException {
178
}
179
180
// write Java primitive array
181
protected void writePrimitiveArray(TypeArray array) throws IOException {
182
writeObject(array);
183
}
184
185
// write Java object array
186
protected void writeObjectArray(ObjArray array) throws IOException {
187
writeObject(array);
188
}
189
190
protected void writeInstance(Instance instance) throws IOException {
191
writeObject(instance);
192
}
193
194
protected void writeString(Instance instance) throws IOException {
195
writeInstance(instance);
196
}
197
198
protected void writeClass(Instance instance) throws IOException {
199
writeInstance(instance);
200
}
201
202
protected void writeThread(Instance instance) throws IOException {
203
writeInstance(instance);
204
}
205
206
protected void writeObject(Oop oop) throws IOException {
207
writeObjectHeader(oop);
208
writeObjectFields(oop);
209
writeObjectFooter(oop);
210
}
211
212
protected void writeObjectHeader(Oop oop) throws IOException {
213
}
214
215
// write instance fields of given object
216
protected void writeObjectFields(final Oop oop) throws IOException {
217
try {
218
oop.iterate(new DefaultOopVisitor() {
219
public void doOop(OopField field, boolean isVMField) {
220
try {
221
writeReferenceField(oop, field);
222
} catch (IOException exp) {
223
throw new RuntimeException(exp);
224
}
225
}
226
227
public void doByte(ByteField field, boolean isVMField) {
228
try {
229
writeByteField(oop, field);
230
} catch (IOException exp) {
231
throw new RuntimeException(exp);
232
}
233
}
234
235
public void doChar(CharField field, boolean isVMField) {
236
try {
237
writeCharField(oop, field);
238
} catch (IOException exp) {
239
throw new RuntimeException(exp);
240
}
241
}
242
243
public void doBoolean(BooleanField field, boolean vField) {
244
try {
245
writeBooleanField(oop, field);
246
} catch (IOException exp) {
247
throw new RuntimeException(exp);
248
}
249
}
250
251
public void doShort(ShortField field, boolean isVMField) {
252
try {
253
writeShortField(oop, field);
254
} catch (IOException exp) {
255
throw new RuntimeException(exp);
256
}
257
}
258
259
public void doInt(IntField field, boolean isVMField) {
260
try {
261
writeIntField(oop, field);
262
} catch (IOException exp) {
263
throw new RuntimeException(exp);
264
}
265
}
266
267
public void doLong(LongField field, boolean isVMField) {
268
try {
269
writeLongField(oop, field);
270
} catch (IOException exp) {
271
throw new RuntimeException(exp);
272
}
273
}
274
275
public void doFloat(FloatField field, boolean isVMField) {
276
try {
277
writeFloatField(oop, field);
278
} catch (IOException exp) {
279
throw new RuntimeException(exp);
280
}
281
}
282
283
public void doDouble(DoubleField field, boolean vField) {
284
try {
285
writeDoubleField(oop, field);
286
} catch (IOException exp) {
287
throw new RuntimeException(exp);
288
}
289
}
290
}, false);
291
} catch (RuntimeException re) {
292
handleRuntimeException(re);
293
}
294
}
295
296
// write instance fields of given object
297
protected void writeObjectFields(final InstanceKlass oop) throws IOException {
298
try {
299
oop.iterateStaticFields(new DefaultOopVisitor() {
300
public void doOop(OopField field, boolean isVMField) {
301
try {
302
writeReferenceField(null, field);
303
} catch (IOException exp) {
304
throw new RuntimeException(exp);
305
}
306
}
307
308
public void doByte(ByteField field, boolean isVMField) {
309
try {
310
writeByteField(null, field);
311
} catch (IOException exp) {
312
throw new RuntimeException(exp);
313
}
314
}
315
316
public void doChar(CharField field, boolean isVMField) {
317
try {
318
writeCharField(null, field);
319
} catch (IOException exp) {
320
throw new RuntimeException(exp);
321
}
322
}
323
324
public void doBoolean(BooleanField field, boolean vField) {
325
try {
326
writeBooleanField(null, field);
327
} catch (IOException exp) {
328
throw new RuntimeException(exp);
329
}
330
}
331
332
public void doShort(ShortField field, boolean isVMField) {
333
try {
334
writeShortField(null, field);
335
} catch (IOException exp) {
336
throw new RuntimeException(exp);
337
}
338
}
339
340
public void doInt(IntField field, boolean isVMField) {
341
try {
342
writeIntField(null, field);
343
} catch (IOException exp) {
344
throw new RuntimeException(exp);
345
}
346
}
347
348
public void doLong(LongField field, boolean isVMField) {
349
try {
350
writeLongField(null, field);
351
} catch (IOException exp) {
352
throw new RuntimeException(exp);
353
}
354
}
355
356
public void doFloat(FloatField field, boolean isVMField) {
357
try {
358
writeFloatField(null, field);
359
} catch (IOException exp) {
360
throw new RuntimeException(exp);
361
}
362
}
363
364
public void doDouble(DoubleField field, boolean vField) {
365
try {
366
writeDoubleField(null, field);
367
} catch (IOException exp) {
368
throw new RuntimeException(exp);
369
}
370
}
371
});
372
} catch (RuntimeException re) {
373
handleRuntimeException(re);
374
}
375
}
376
377
// object field writers
378
protected void writeReferenceField(Oop oop, OopField field)
379
throws IOException {
380
}
381
382
protected void writeByteField(Oop oop, ByteField field)
383
throws IOException {
384
}
385
386
protected void writeCharField(Oop oop, CharField field)
387
throws IOException {
388
}
389
390
protected void writeBooleanField(Oop oop, BooleanField field)
391
throws IOException {
392
}
393
394
protected void writeShortField(Oop oop, ShortField field)
395
throws IOException {
396
}
397
398
protected void writeIntField(Oop oop, IntField field)
399
throws IOException {
400
}
401
402
protected void writeLongField(Oop oop, LongField field)
403
throws IOException {
404
}
405
406
protected void writeFloatField(Oop oop, FloatField field)
407
throws IOException {
408
}
409
410
protected void writeDoubleField(Oop oop, DoubleField field)
411
throws IOException {
412
}
413
414
protected void writeObjectFooter(Oop oop) throws IOException {
415
}
416
417
protected void writeHeapFooter() throws IOException {
418
}
419
420
protected void writeHeapRecordPrologue() throws IOException {
421
}
422
423
protected void writeHeapRecordEpilogue() throws IOException {
424
}
425
426
// HeapVisitor, OopVisitor methods can't throw any non-runtime
427
// exception. But, derived class write methods (which are called
428
// from visitor callbacks) may throw IOException. Hence, we throw
429
// RuntimeException with origianal IOException as cause from the
430
// visitor methods. This method gets back the original IOException
431
// (if any) and re-throws the same.
432
protected void handleRuntimeException(RuntimeException re)
433
throws IOException {
434
Throwable cause = re.getCause();
435
if (cause != null && cause instanceof IOException) {
436
throw (IOException) cause;
437
} else {
438
// some other RuntimeException, just re-throw
439
throw re;
440
}
441
}
442
443
// whether a given oop is Java visible or hotspot internal?
444
protected boolean isJavaVisible(Oop oop) {
445
if (oop instanceof Instance || oop instanceof TypeArray) {
446
return true;
447
} else if (oop instanceof ObjArray) {
448
ObjArrayKlass oak = (ObjArrayKlass) oop.getKlass();
449
Klass bottomKlass = oak.getBottomKlass();
450
return bottomKlass instanceof InstanceKlass ||
451
bottomKlass instanceof TypeArrayKlass;
452
} else {
453
return false;
454
}
455
}
456
457
protected String javaLangClass;
458
protected String javaLangString;
459
protected String javaLangThread;
460
}
461
462