in src/application/org.openjdk.jmc.joverflow/src/main/java/org/openjdk/jmc/joverflow/heap/parser/HprofReader.java [335:505]
private void doRead() throws DumpCorruptedException, IOException, HprofParsingCancelledException {
int magicNumber = in.readInt();
if (magicNumber != MAGIC_NUMBER) {
throw new DumpCorruptedException("unrecognized magic number: " + magicNumber);
}
version = readVersionHeader();
identifierSize = in.readInt();
if (identifierSize != 4 && identifierSize != 8) {
throw new DumpCorruptedException("unsupported format: " + "specifies pointer size of " + identifierSize
+ ". JOverflow supports only size 4 and 8.");
}
snpBuilder = new Snapshot.Builder(fileSize, identifierSize, explicitPointerSize, vc);
skipBytes(8); // long creationDate = in.readLong();
// System.out.println("Dump file created " + (new Date(creationDate)));
while (true) {
int type;
try {
type = in.readUnsignedByte();
} catch (EOFException ignored) {
break;
}
in.readInt(); // Timestamp of this record
// Length of record: readInt() will return negative value for record length >2GB. So store 32bit value in long to keep it unsigned.
long length = in.readInt() & 0xffffffffL;
// System.out.println("Read record type " + type + ", length " + length + " at position " + toHex(currPos));
if (length < 0) {
throw new DumpCorruptedException(
"bad record length of " + length + " at byte " + (in.position() - 4) + " of file.");
}
switch (type) {
case HPROF_UTF8: {
long id = readID();
byte[] chars = new byte[(int) length - identifierSize];
in.readFully(chars);
names.put(id, new String(chars));
break;
}
case HPROF_LOAD_CLASS: {
int serialNo = in.readInt(); // Not used
long classID = readID();
in.readInt(); // int stackTraceSerialNo, unused
long classNameID = readID();
String nm = getNameFromID(classNameID).replace('/', '.');
classNameFromObjectID.put(classID, nm);
if (classNameFromSerialNo != null) {
classNameFromSerialNo.put(serialNo, nm);
}
break;
}
case HPROF_HEAP_DUMP: {
if (dumpsToSkip <= 0) {
try {
vc.debug("Sub-dump of length " + length + " starts at position " + in.position());
readHeapDump(length);
} catch (EOFException exp) {
handleEOF(exp);
}
// System.out.println("Finished processing instances in heap dump.");
return;
} else {
dumpsToSkip--;
skipBytes(length);
}
break;
}
case HPROF_HEAP_DUMP_END: {
if (version >= VERSION_JDK6) {
if (dumpsToSkip <= 0) {
skipBytes(length); // should be no-op
return;
} else {
// skip this dump (of the end record for a sequence of dump segments)
dumpsToSkip--;
}
} else {
// HPROF_HEAP_DUMP_END only recognized in >= 1.0.2
vc.addWarning("Ignoring unrecognized record type", Integer.toString(type));
}
skipBytes(length); // should be no-op
break;
}
case HPROF_HEAP_DUMP_SEGMENT: {
if (version >= VERSION_JDK6) {
if (dumpsToSkip <= 0) {
try {
vc.debug("Segment of length " + length + " starts at position " + in.position());
// read the dump segment
readHeapDump(length);
} catch (EOFException exp) {
handleEOF(exp);
}
} else {
// all segments comprising the heap dump will be skipped
skipBytes(length);
}
} else {
// HPROF_HEAP_DUMP_SEGMENT only recognized in >= 1.0.2
vc.addWarning("Ignoring unrecognized record type", Integer.toString(type));
skipBytes(length);
}
break;
}
case HPROF_FRAME: {
if (stackFrames == null) {
skipBytes(length);
} else {
long id = readID();
String methodName = getNameFromID(readID());
String methodSig = getNameFromID(readID());
String sourceFile = getNameFromID(readID());
int classSer = in.readInt();
String className = classNameFromSerialNo.get(Integer.valueOf(classSer));
int lineNumber = in.readInt();
if (lineNumber < StackFrame.LINE_NUMBER_NATIVE) {
vc.addWarning("Weird stack frame line number", Integer.toString(lineNumber));
lineNumber = StackFrame.LINE_NUMBER_UNKNOWN;
}
stackFrames.put(id, new StackFrame(methodName, methodSig, className, sourceFile, lineNumber));
}
break;
}
case HPROF_TRACE: {
if (stackTraces == null) {
skipBytes(length);
} else {
int serialNo = in.readInt();
in.readInt(); // int threadSeq, not used
StackFrame[] frames = new StackFrame[in.readInt()];
for (int i = 0; i < frames.length; i++) {
long fid = readID();
frames[i] = stackFrames.get(Long.valueOf(fid));
if (frames[i] == null) {
throw new DumpCorruptedException("stack frame " + toHex(fid) + " not found");
}
}
stackTraces.put(serialNo, new StackTrace(frames));
}
break;
}
case HPROF_HEAP_SUMMARY:
case HPROF_UNLOAD_CLASS:
case HPROF_ALLOC_SITES:
case HPROF_START_THREAD:
case HPROF_END_THREAD:
case HPROF_CPU_SAMPLES:
case HPROF_CONTROL_SETTINGS:
case HPROF_LOCKSTATS_WAIT_TIME:
case HPROF_LOCKSTATS_HOLD_TIME: {
// Ignore these record types
skipBytes(length);
break;
}
default: {
skipBytes(length);
vc.addWarning("Ignoring unrecognized record type", Integer.toString(type));
}
}
}
}