< 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 >