package extra; import java.io.PrintStream; import java.io.InputStream; import java.io.FileInputStream; import java.io.BufferedInputStream; import java.io.IOException; import java.io.EOFException; /** * This is a simple utility to print the contents of a heap dump * generated by Avian's heapdump.cpp in a human-readable format. */ public class PrintDump { private static final int Root = 0; private static final int Size = 1; private static final int ClassName = 2; private static final int Push = 3; private static final int Pop = 4; private static void indent(PrintStream out, int level) { for (; level > 0; --level) out.print(" "); } private static int readInt(InputStream in) throws IOException { int b1 = in.read(); int b2 = in.read(); int b3 = in.read(); int b4 = in.read(); if (b4 == -1) throw new EOFException(); return (int) ((b1 << 24) | (b2 << 16) | (b3 << 8) | (b4)); } private static String readString(InputStream in) throws IOException { int count = readInt(in); byte[] b = new byte[count]; int offset = 0; int c; while ((c = in.read(b, offset, b.length - offset)) != -1 && offset < b.length) { offset += c; } if (offset != b.length) throw new EOFException(); return new String(b, "UTF-8"); } private static void pipe(InputStream in, PrintStream out) throws IOException { boolean done = false; boolean popped = false; int level = 0; while (! done) { int flag = in.read(); switch (flag) { case Root: { out.print("\nroot " + readInt(in)); popped = false; } break; case ClassName: { out.print(" class " + readString(in)); } break; case Push: { ++ level; out.println(); indent(out, level); if (! popped) { out.print("first "); } out.print("child " + readInt(in)); popped = false; } break; case Pop: { -- level; popped = true; } break; case Size: { out.print(" size " + readInt(in)); } break; case -1: out.println(); out.flush(); done = true; break; default: throw new RuntimeException("bad flag: " + flag); } } } public static void main(String[] args) throws Exception { pipe(new BufferedInputStream(new FileInputStream(args[0])), System.out); } }