81 // Record types:
82 //
83 static final int HPROF_UTF8 = 0x01;
84 static final int HPROF_LOAD_CLASS = 0x02;
85 static final int HPROF_UNLOAD_CLASS = 0x03;
86 static final int HPROF_FRAME = 0x04;
87 static final int HPROF_TRACE = 0x05;
88 static final int HPROF_ALLOC_SITES = 0x06;
89 static final int HPROF_HEAP_SUMMARY = 0x07;
90
91 static final int HPROF_START_THREAD = 0x0a;
92 static final int HPROF_END_THREAD = 0x0b;
93
94 static final int HPROF_HEAP_DUMP = 0x0c;
95
96 static final int HPROF_CPU_SAMPLES = 0x0d;
97 static final int HPROF_CONTROL_SETTINGS = 0x0e;
98 static final int HPROF_LOCKSTATS_WAIT_TIME = 0x10;
99 static final int HPROF_LOCKSTATS_HOLD_TIME = 0x11;
100
101 static final int HPROF_GC_ROOT_UNKNOWN = 0xff;
102 static final int HPROF_GC_ROOT_JNI_GLOBAL = 0x01;
103 static final int HPROF_GC_ROOT_JNI_LOCAL = 0x02;
104 static final int HPROF_GC_ROOT_JAVA_FRAME = 0x03;
105 static final int HPROF_GC_ROOT_NATIVE_STACK = 0x04;
106 static final int HPROF_GC_ROOT_STICKY_CLASS = 0x05;
107 static final int HPROF_GC_ROOT_THREAD_BLOCK = 0x06;
108 static final int HPROF_GC_ROOT_MONITOR_USED = 0x07;
109 static final int HPROF_GC_ROOT_THREAD_OBJ = 0x08;
110
111 static final int HPROF_GC_CLASS_DUMP = 0x20;
112 static final int HPROF_GC_INSTANCE_DUMP = 0x21;
113 static final int HPROF_GC_OBJ_ARRAY_DUMP = 0x22;
114 static final int HPROF_GC_PRIM_ARRAY_DUMP = 0x23;
115
116 static final int HPROF_HEAP_DUMP_SEGMENT = 0x1c;
117 static final int HPROF_HEAP_DUMP_END = 0x2c;
118
119 private final static int T_CLASS = 2;
120
227 byte[] chars = new byte[(int)length - identifierSize];
228 in.readFully(chars);
229 names.put(id, new String(chars));
230 break;
231 }
232 case HPROF_LOAD_CLASS: {
233 int serialNo = in.readInt(); // Not used
234 long classID = readID();
235 int stackTraceSerialNo = in.readInt();
236 long classNameID = readID();
237 Long classIdI = classID;
238 String nm = getNameFromID(classNameID).replace('/', '.');
239 classNameFromObjectID.put(classIdI, nm);
240 if (classNameFromSerialNo != null) {
241 classNameFromSerialNo.put(serialNo, nm);
242 }
243 break;
244 }
245
246 case HPROF_HEAP_DUMP: {
247 if (dumpsToSkip <= 0) {
248 try {
249 readHeapDump(length, currPos);
250 } catch (EOFException exp) {
251 handleEOF(exp, snapshot);
252 }
253 if (debugLevel > 0) {
254 System.out.println(" Finished processing instances in heap dump.");
255 }
256 return snapshot;
257 } else {
258 dumpsToSkip--;
259 skipBytes(length);
260 }
261 break;
262 }
263
264 case HPROF_HEAP_DUMP_END: {
265 if (version >= VERSION_JDK6) {
266 if (dumpsToSkip <= 0) {
267 skipBytes(length); // should be no-op
268 return snapshot;
269 } else {
270 // skip this dump (of the end record for a sequence of dump segments)
271 dumpsToSkip--;
272 }
273 } else {
274 // HPROF_HEAP_DUMP_END only recognized in >= 1.0.2
275 warn("Ignoring unrecognized record type " + type);
276 }
277 skipBytes(length); // should be no-op
278 break;
279 }
280
281 case HPROF_HEAP_DUMP_SEGMENT: {
282 if (version >= VERSION_JDK6) {
283 if (dumpsToSkip <= 0) {
284 try {
285 // read the dump segment
286 readHeapDump(length, currPos);
287 } catch (EOFException exp) {
288 handleEOF(exp, snapshot);
289 }
290 } else {
291 // all segments comprising the heap dump will be skipped
292 skipBytes(length);
293 }
294 } else {
295 // HPROF_HEAP_DUMP_SEGMENT only recognized in >= 1.0.2
296 warn("Ignoring unrecognized record type " + type);
297 skipBytes(length);
298 }
299 break;
300 }
301
302 case HPROF_FRAME: {
303 if (stackFrames == null) {
337 }
338 stackTraces.put(serialNo,
339 new StackTrace(frames));
340 }
341 break;
342 }
343 case HPROF_UNLOAD_CLASS:
344 case HPROF_ALLOC_SITES:
345 case HPROF_START_THREAD:
346 case HPROF_END_THREAD:
347 case HPROF_HEAP_SUMMARY:
348 case HPROF_CPU_SAMPLES:
349 case HPROF_CONTROL_SETTINGS:
350 case HPROF_LOCKSTATS_WAIT_TIME:
351 case HPROF_LOCKSTATS_HOLD_TIME:
352 {
353 // Ignore these record types
354 skipBytes(length);
355 break;
356 }
357 default: {
358 skipBytes(length);
359 warn("Ignoring unrecognized record type " + type);
360 }
361 }
362 }
363
364 return snapshot;
365 }
366
367 public String printStackTraces() {
368 StringBuffer output = new StringBuffer();
369 for (Map.Entry<Integer, StackTrace> entry : stackTraces.entrySet()) {
370 StackFrame[] frames = entry.getValue().getFrames();
371 output.append("SerialNo " + entry.getKey() + "\n");
372 for (int i = 0; i < frames.length; i++) {
373 output.append(" " + frames[i].getClassName() + "." + frames[i].getMethodName()
374 + frames[i].getMethodSignature() + " (" + frames[i].getSourceFileName()
375 + ":" + frames[i].getLineNumber() + ")" + "\n");
376 }
835 }
836 case T_INT: {
837 primitiveSignature = (byte) 'I';
838 elSize = 4;
839 break;
840 }
841 case T_LONG: {
842 primitiveSignature = (byte) 'J';
843 elSize = 8;
844 break;
845 }
846 }
847 if (version >= VERSION_JDK12BETA4 && primitiveSignature == 0x00) {
848 throw new IOException("Unrecognized typecode: "
849 + elementClassID);
850 }
851 }
852 if (primitiveSignature != 0x00) {
853 long size = elSize * (long)num;
854 bytesRead += size;
855 JavaValueArray va = new JavaValueArray(primitiveSignature, start);
856 skipBytes(size);
857 snapshot.addHeapObject(id, va);
858 snapshot.setSiteTrace(va, stackTrace);
859 } else {
860 long sz = (long)num * identifierSize;
861 bytesRead += sz;
862 JavaObjectArray arr = new JavaObjectArray(elementClassID, start);
863 skipBytes(sz);
864 snapshot.addHeapObject(id, arr);
865 snapshot.setSiteTrace(arr, stackTrace);
866 }
867 return bytesRead;
868 }
869
870 private byte signatureFromTypeId(byte typeId) throws IOException {
871 switch (typeId) {
872 case T_CLASS: {
873 return (byte) 'L';
874 }
875 case T_BOOLEAN: {
885 return (byte) 'D';
886 }
887 case T_BYTE: {
888 return (byte) 'B';
889 }
890 case T_SHORT: {
891 return (byte) 'S';
892 }
893 case T_INT: {
894 return (byte) 'I';
895 }
896 case T_LONG: {
897 return (byte) 'J';
898 }
899 default: {
900 throw new IOException("Invalid type id of " + typeId);
901 }
902 }
903 }
904
905 private void handleEOF(EOFException exp, Snapshot snapshot) {
906 if (debugLevel > 0) {
907 exp.printStackTrace();
908 }
909 warn("Unexpected EOF. Will miss information...");
910 // we have EOF, we have to tolerate missing references
911 snapshot.setUnresolvedObjectsOK(true);
912 }
913
914 private void warn(String msg) {
915 System.out.println("WARNING: " + msg);
916 }
917
918 //
919 // A trivial data-holder class for HPROF_GC_ROOT_THREAD_OBJ.
920 //
921 private class ThreadObject {
922
923 long threadId;
924 int stackSeq;
|
81 // Record types:
82 //
83 static final int HPROF_UTF8 = 0x01;
84 static final int HPROF_LOAD_CLASS = 0x02;
85 static final int HPROF_UNLOAD_CLASS = 0x03;
86 static final int HPROF_FRAME = 0x04;
87 static final int HPROF_TRACE = 0x05;
88 static final int HPROF_ALLOC_SITES = 0x06;
89 static final int HPROF_HEAP_SUMMARY = 0x07;
90
91 static final int HPROF_START_THREAD = 0x0a;
92 static final int HPROF_END_THREAD = 0x0b;
93
94 static final int HPROF_HEAP_DUMP = 0x0c;
95
96 static final int HPROF_CPU_SAMPLES = 0x0d;
97 static final int HPROF_CONTROL_SETTINGS = 0x0e;
98 static final int HPROF_LOCKSTATS_WAIT_TIME = 0x10;
99 static final int HPROF_LOCKSTATS_HOLD_TIME = 0x11;
100
101 static final int HPROF_FLAT_ARRAYS = 0x12;
102 static final int HPROF_INLINED_FIELDS = 0x13;
103
104 static final int HPROF_FLAT_ARRAY = 0x01;
105 static final int HPROF_CLASS_WITH_INLINED_FIELDS = 0x01;
106
107 static final int HPROF_GC_ROOT_UNKNOWN = 0xff;
108 static final int HPROF_GC_ROOT_JNI_GLOBAL = 0x01;
109 static final int HPROF_GC_ROOT_JNI_LOCAL = 0x02;
110 static final int HPROF_GC_ROOT_JAVA_FRAME = 0x03;
111 static final int HPROF_GC_ROOT_NATIVE_STACK = 0x04;
112 static final int HPROF_GC_ROOT_STICKY_CLASS = 0x05;
113 static final int HPROF_GC_ROOT_THREAD_BLOCK = 0x06;
114 static final int HPROF_GC_ROOT_MONITOR_USED = 0x07;
115 static final int HPROF_GC_ROOT_THREAD_OBJ = 0x08;
116
117 static final int HPROF_GC_CLASS_DUMP = 0x20;
118 static final int HPROF_GC_INSTANCE_DUMP = 0x21;
119 static final int HPROF_GC_OBJ_ARRAY_DUMP = 0x22;
120 static final int HPROF_GC_PRIM_ARRAY_DUMP = 0x23;
121
122 static final int HPROF_HEAP_DUMP_SEGMENT = 0x1c;
123 static final int HPROF_HEAP_DUMP_END = 0x2c;
124
125 private final static int T_CLASS = 2;
126
233 byte[] chars = new byte[(int)length - identifierSize];
234 in.readFully(chars);
235 names.put(id, new String(chars));
236 break;
237 }
238 case HPROF_LOAD_CLASS: {
239 int serialNo = in.readInt(); // Not used
240 long classID = readID();
241 int stackTraceSerialNo = in.readInt();
242 long classNameID = readID();
243 Long classIdI = classID;
244 String nm = getNameFromID(classNameID).replace('/', '.');
245 classNameFromObjectID.put(classIdI, nm);
246 if (classNameFromSerialNo != null) {
247 classNameFromSerialNo.put(serialNo, nm);
248 }
249 break;
250 }
251
252 case HPROF_HEAP_DUMP: {
253 if (dumpsToSkip == 0) {
254 try {
255 readHeapDump(length, currPos);
256 } catch (EOFException exp) {
257 handleEOF(exp, snapshot);
258 }
259 if (debugLevel > 0) {
260 System.out.println(" Finished processing instances in heap dump.");
261 }
262 } else {
263 dumpsToSkip--;
264 skipBytes(length);
265 }
266 break;
267 }
268
269 case HPROF_HEAP_DUMP_END: {
270 if (version >= VERSION_JDK6) {
271 if (dumpsToSkip == 0) {
272 // update dumpsToSkip to skip other dumps
273 dumpsToSkip--;
274 } else {
275 // skip this dump (of the end record for a sequence of dump segments)
276 dumpsToSkip--;
277 }
278 } else {
279 // HPROF_HEAP_DUMP_END only recognized in >= 1.0.2
280 warn("Ignoring unrecognized record type " + type);
281 }
282 skipBytes(length); // should be no-op
283 break;
284 }
285
286 case HPROF_HEAP_DUMP_SEGMENT: {
287 if (version >= VERSION_JDK6) {
288 if (dumpsToSkip == 0) {
289 try {
290 // read the dump segment
291 readHeapDump(length, currPos);
292 } catch (EOFException exp) {
293 handleEOF(exp, snapshot);
294 }
295 } else {
296 // all segments comprising the heap dump will be skipped
297 skipBytes(length);
298 }
299 } else {
300 // HPROF_HEAP_DUMP_SEGMENT only recognized in >= 1.0.2
301 warn("Ignoring unrecognized record type " + type);
302 skipBytes(length);
303 }
304 break;
305 }
306
307 case HPROF_FRAME: {
308 if (stackFrames == null) {
342 }
343 stackTraces.put(serialNo,
344 new StackTrace(frames));
345 }
346 break;
347 }
348 case HPROF_UNLOAD_CLASS:
349 case HPROF_ALLOC_SITES:
350 case HPROF_START_THREAD:
351 case HPROF_END_THREAD:
352 case HPROF_HEAP_SUMMARY:
353 case HPROF_CPU_SAMPLES:
354 case HPROF_CONTROL_SETTINGS:
355 case HPROF_LOCKSTATS_WAIT_TIME:
356 case HPROF_LOCKSTATS_HOLD_TIME:
357 {
358 // Ignore these record types
359 skipBytes(length);
360 break;
361 }
362 case HPROF_FLAT_ARRAYS: {
363 readFlatArrays(length);
364 break;
365 }
366 case HPROF_INLINED_FIELDS: {
367 readInlinedFields(length);
368 break;
369 }
370
371 default: {
372 skipBytes(length);
373 warn("Ignoring unrecognized record type " + type);
374 }
375 }
376 }
377
378 return snapshot;
379 }
380
381 public String printStackTraces() {
382 StringBuffer output = new StringBuffer();
383 for (Map.Entry<Integer, StackTrace> entry : stackTraces.entrySet()) {
384 StackFrame[] frames = entry.getValue().getFrames();
385 output.append("SerialNo " + entry.getKey() + "\n");
386 for (int i = 0; i < frames.length; i++) {
387 output.append(" " + frames[i].getClassName() + "." + frames[i].getMethodName()
388 + frames[i].getMethodSignature() + " (" + frames[i].getSourceFileName()
389 + ":" + frames[i].getLineNumber() + ")" + "\n");
390 }
849 }
850 case T_INT: {
851 primitiveSignature = (byte) 'I';
852 elSize = 4;
853 break;
854 }
855 case T_LONG: {
856 primitiveSignature = (byte) 'J';
857 elSize = 8;
858 break;
859 }
860 }
861 if (version >= VERSION_JDK12BETA4 && primitiveSignature == 0x00) {
862 throw new IOException("Unrecognized typecode: "
863 + elementClassID);
864 }
865 }
866 if (primitiveSignature != 0x00) {
867 long size = elSize * (long)num;
868 bytesRead += size;
869 JavaValueArray va = new JavaValueArray(id, primitiveSignature, start);
870 skipBytes(size);
871 snapshot.addHeapObject(id, va);
872 snapshot.setSiteTrace(va, stackTrace);
873 } else {
874 long sz = (long)num * identifierSize;
875 bytesRead += sz;
876 JavaObjectArray arr = new JavaObjectArray(elementClassID, start);
877 skipBytes(sz);
878 snapshot.addHeapObject(id, arr);
879 snapshot.setSiteTrace(arr, stackTrace);
880 }
881 return bytesRead;
882 }
883
884 private byte signatureFromTypeId(byte typeId) throws IOException {
885 switch (typeId) {
886 case T_CLASS: {
887 return (byte) 'L';
888 }
889 case T_BOOLEAN: {
899 return (byte) 'D';
900 }
901 case T_BYTE: {
902 return (byte) 'B';
903 }
904 case T_SHORT: {
905 return (byte) 'S';
906 }
907 case T_INT: {
908 return (byte) 'I';
909 }
910 case T_LONG: {
911 return (byte) 'J';
912 }
913 default: {
914 throw new IOException("Invalid type id of " + typeId);
915 }
916 }
917 }
918
919 private void readFlatArrays(long length) throws IOException {
920 while (length > 0) {
921 byte tag = in.readByte();
922 length--;
923 switch (tag) {
924 case HPROF_FLAT_ARRAY: {
925 long objId = readID();
926 length -= identifierSize;
927 long elementClassId = readID();
928 length -= identifierSize;
929 snapshot.addFlatArray(objId, elementClassId);
930 break;
931 }
932 default: {
933 throw new IOException("Invalid tag " + tag);
934 }
935 }
936 }
937 }
938
939 private void readInlinedFields(long length) throws IOException {
940 while (length > 0) {
941 byte tag = in.readByte();
942 length--;
943 switch (tag) {
944 case HPROF_CLASS_WITH_INLINED_FIELDS: {
945 long classID = readID();
946 length -= identifierSize;
947 int fieldNum = in.readUnsignedShort();
948 length -= 2;
949 Snapshot.ClassInlinedFields[] fields = new Snapshot.ClassInlinedFields[fieldNum];
950 for (int i = 0; i < fieldNum; i++) {
951 int fieldIndex = in.readUnsignedShort();
952 length -= 2;
953 int synthFieldCount = in.readUnsignedShort();
954 length -= 2;
955 String fieldName = getNameFromID(readID());
956 length -= identifierSize;
957 long fieldClassId = readID();
958 length -= identifierSize;
959 fields[i] = new Snapshot.ClassInlinedFields(fieldIndex, synthFieldCount, fieldName, fieldClassId);
960 }
961 snapshot.addClassInlinedFields(classID, fields);
962 break;
963 }
964 default: {
965 throw new IOException("Invalid tag " + tag);
966 }
967 }
968 }
969 }
970
971 private void handleEOF(EOFException exp, Snapshot snapshot) {
972 if (debugLevel > 0) {
973 exp.printStackTrace();
974 }
975 warn("Unexpected EOF. Will miss information...");
976 // we have EOF, we have to tolerate missing references
977 snapshot.setUnresolvedObjectsOK(true);
978 }
979
980 private void warn(String msg) {
981 System.out.println("WARNING: " + msg);
982 }
983
984 //
985 // A trivial data-holder class for HPROF_GC_ROOT_THREAD_OBJ.
986 //
987 private class ThreadObject {
988
989 long threadId;
990 int stackSeq;
|