< prev index next >
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java
Print this page
@@ -307,10 +307,13 @@
*
*/
public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
+ // Record which Symbol names have been dumped already.
+ private HashSet<Symbol> names;
+
private static final long HPROF_SEGMENTED_HEAP_DUMP_THRESHOLD = 2L * 0x40000000;
// The approximate size of a heap segment. Used to calculate when to create
// a new segment.
private static final long HPROF_SEGMENTED_HEAP_DUMP_SEGMENT_SIZE = 1L * 0x40000000;
@@ -379,21 +382,21 @@
private static final long MAX_U4_VALUE = 0xFFFFFFFFL;
int serialNum = 1;
public HeapHprofBinWriter() {
this.KlassMap = new ArrayList<Klass>();
+ this.names = new HashSet<Symbol>();
}
public synchronized void write(String fileName) throws IOException {
// open file stream and create buffered data output stream
fos = new FileOutputStream(fileName);
out = new DataOutputStream(new BufferedOutputStream(fos));
VM vm = VM.getVM();
dbg = vm.getDebugger();
objectHeap = vm.getObjectHeap();
- symTbl = vm.getSymbolTable();
OBJ_ID_SIZE = (int) vm.getOopSize();
BOOLEAN_BASE_OFFSET = TypeArray.baseOffsetInBytes(BasicType.T_BOOLEAN);
BYTE_BASE_OFFSET = TypeArray.baseOffsetInBytes(BasicType.T_BYTE);
@@ -743,10 +746,15 @@
if (m.isNative()) {
lineNumber = -3; // native frame
} else {
lineNumber = m.getLineNumberFromBCI(bci);
}
+ // First dump UTF8 if needed
+ writeSymbol(m.getName()); // method's name
+ writeSymbol(m.getSignature()); // method's signature
+ writeSymbol(m.getMethodHolder().getSourceFileName()); // source file name
+ // Then write FRAME descriptor
writeHeader(HPROF_FRAME, 4 * (int)VM.getVM().getOopSize() + 2 * (int)INT_SIZE);
writeObjectID(frameSN); // frame serial number
writeSymbolID(m.getName()); // method's name
writeSymbolID(m.getSignature()); // method's signature
writeSymbolID(m.getMethodHolder().getSourceFileName()); // source file name
@@ -953,11 +961,11 @@
throws IOException {
// ik == null for instance fields.
out.writeShort((short) fields.size());
for (Iterator itr = fields.iterator(); itr.hasNext();) {
Field field = (Field) itr.next();
- Symbol name = symTbl.probe(field.getID().getName());
+ Symbol name = field.getName();
writeSymbolID(name);
char typeCode = (char) field.getSignature().getByteAt(0);
int kind = signatureToHprofKind(typeCode);
out.writeByte((byte)kind);
if (ik != null) {
@@ -1047,32 +1055,49 @@
out.writeInt(DUMMY_STACK_TRACE_ID);
out.writeInt(0);
out.writeInt(0);
}
+ private void writeClassSymbols(Klass k) throws IOException {
+ writeSymbol(k.getName());
+ if (k instanceof InstanceKlass) {
+ InstanceKlass ik = (InstanceKlass) k;
+ List declaredFields = ik.getImmediateFields();
+ for (Iterator itr = declaredFields.iterator(); itr.hasNext();) {
+ Field field = (Field) itr.next();
+ writeSymbol(field.getName());
+ }
+ }
+ }
+
private void writeSymbols() throws IOException {
+ // Write all the symbols that are used by the classes
+ ClassLoaderDataGraph cldGraph = VM.getVM().getClassLoaderDataGraph();
try {
- symTbl.symbolsDo(new SymbolTable.SymbolVisitor() {
- public void visit(Symbol sym) {
+ cldGraph.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
+ public void visit(Klass k) {
try {
- writeSymbol(sym);
- } catch (IOException exp) {
- throw new RuntimeException(exp);
+ writeClassSymbols(k);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
}
}
});
} catch (RuntimeException re) {
handleRuntimeException(re);
}
}
private void writeSymbol(Symbol sym) throws IOException {
+ // If name is already written don't write it again.
+ if (names.add(sym)) {
byte[] buf = sym.asString().getBytes("UTF-8");
writeHeader(HPROF_UTF8, buf.length + OBJ_ID_SIZE);
writeSymbolID(sym);
out.write(buf);
}
+ }
private void writeClasses() throws IOException {
// write class list (id, name) association
ClassLoaderDataGraph cldGraph = VM.getVM().getClassLoaderDataGraph();
try {
@@ -1116,10 +1141,11 @@
long address = getAddressValue(handle);
writeObjectID(address);
}
private void writeSymbolID(Symbol sym) throws IOException {
+ assert names.contains(sym);
writeObjectID(getAddressValue(sym.getAddress()));
}
private void writeObjectID(long address) throws IOException {
if (OBJ_ID_SIZE == 4) {
@@ -1193,11 +1219,10 @@
private DataOutputStream out;
private FileOutputStream fos;
private Debugger dbg;
private ObjectHeap objectHeap;
- private SymbolTable symTbl;
private ArrayList<Klass> KlassMap;
// oopSize of the debuggee
private int OBJ_ID_SIZE;
< prev index next >