377 private static final int JVM_SIGNATURE_CLASS = 'L'; |
377 private static final int JVM_SIGNATURE_CLASS = 'L'; |
378 |
378 |
379 private static final long MAX_U4_VALUE = 0xFFFFFFFFL; |
379 private static final long MAX_U4_VALUE = 0xFFFFFFFFL; |
380 int serialNum = 1; |
380 int serialNum = 1; |
381 |
381 |
|
382 public HeapHprofBinWriter() { |
|
383 this.KlassMap = new ArrayList<Klass>(); |
|
384 } |
|
385 |
382 public synchronized void write(String fileName) throws IOException { |
386 public synchronized void write(String fileName) throws IOException { |
383 // open file stream and create buffered data output stream |
387 // open file stream and create buffered data output stream |
384 fos = new FileOutputStream(fileName); |
388 fos = new FileOutputStream(fileName); |
385 out = new DataOutputStream(new BufferedOutputStream(fos)); |
389 out = new DataOutputStream(new BufferedOutputStream(fos)); |
386 |
390 |
696 // no static fields for array klasses |
703 // no static fields for array klasses |
697 out.writeShort((short) 0); |
704 out.writeShort((short) 0); |
698 // no instance fields for array klasses |
705 // no instance fields for array klasses |
699 out.writeShort((short) 0); |
706 out.writeShort((short) 0); |
700 } |
707 } |
|
708 } |
|
709 |
|
710 private void dumpStackTraces() throws IOException { |
|
711 // write a HPROF_TRACE record without any frames to be referenced as object alloc sites |
|
712 writeHeader(HPROF_TRACE, 3 * (int)INT_SIZE ); |
|
713 out.writeInt(DUMMY_STACK_TRACE_ID); |
|
714 out.writeInt(0); // thread number |
|
715 out.writeInt(0); // frame count |
|
716 |
|
717 int frameSerialNum = 0; |
|
718 int numThreads = 0; |
|
719 Threads threads = VM.getVM().getThreads(); |
|
720 |
|
721 for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) { |
|
722 Oop threadObj = thread.getThreadObj(); |
|
723 if (threadObj != null && !thread.isExiting() && !thread.isHiddenFromExternalView()) { |
|
724 |
|
725 // dump thread stack trace |
|
726 ThreadStackTrace st = new ThreadStackTrace(thread); |
|
727 st.dumpStack(-1); |
|
728 numThreads++; |
|
729 |
|
730 // write HPROF_FRAME records for this thread's stack trace |
|
731 int depth = st.getStackDepth(); |
|
732 int threadFrameStart = frameSerialNum; |
|
733 for (int j=0; j < depth; j++) { |
|
734 StackFrameInfo frame = st.stackFrameAt(j); |
|
735 Method m = frame.getMethod(); |
|
736 int classSerialNum = KlassMap.indexOf(m.getMethodHolder()) + 1; |
|
737 // the class serial number starts from 1 |
|
738 assert classSerialNum > 0:"class not found"; |
|
739 dumpStackFrame(++frameSerialNum, classSerialNum, m, frame.getBCI()); |
|
740 } |
|
741 |
|
742 // write HPROF_TRACE record for one thread |
|
743 writeHeader(HPROF_TRACE, 3 * (int)INT_SIZE + depth * (int)VM.getVM().getOopSize()); |
|
744 int stackSerialNum = numThreads + DUMMY_STACK_TRACE_ID; |
|
745 out.writeInt(stackSerialNum); // stack trace serial number |
|
746 out.writeInt(numThreads); // thread serial number |
|
747 out.writeInt(depth); // frame count |
|
748 for (int j=1; j <= depth; j++) { |
|
749 writeObjectID(threadFrameStart + j); |
|
750 } |
|
751 } |
|
752 } |
|
753 } |
|
754 |
|
755 private void dumpStackFrame(int frameSN, int classSN, Method m, int bci) throws IOException { |
|
756 int lineNumber; |
|
757 if (m.isNative()) { |
|
758 lineNumber = -3; // native frame |
|
759 } else { |
|
760 lineNumber = m.getLineNumberFromBCI(bci); |
|
761 } |
|
762 writeHeader(HPROF_FRAME, 4 * (int)VM.getVM().getOopSize() + 2 * (int)INT_SIZE); |
|
763 writeObjectID(frameSN); // frame serial number |
|
764 writeSymbolID(m.getName()); // method's name |
|
765 writeSymbolID(m.getSignature()); // method's signature |
|
766 writeSymbolID(m.getMethodHolder().getSourceFileName()); // source file name |
|
767 out.writeInt(classSN); // class serial number |
|
768 out.writeInt(lineNumber); // line number |
701 } |
769 } |
702 |
770 |
703 protected void writeJavaThread(JavaThread jt, int index) throws IOException { |
771 protected void writeJavaThread(JavaThread jt, int index) throws IOException { |
704 out.writeByte((byte) HPROF_GC_ROOT_THREAD_OBJ); |
772 out.writeByte((byte) HPROF_GC_ROOT_THREAD_OBJ); |
705 writeObjectID(jt.getThreadObj()); |
773 writeObjectID(jt.getThreadObj()); |
1028 try { |
1096 try { |
1029 Instance clazz = k.getJavaMirror(); |
1097 Instance clazz = k.getJavaMirror(); |
1030 writeHeader(HPROF_LOAD_CLASS, 2 * (OBJ_ID_SIZE + 4)); |
1098 writeHeader(HPROF_LOAD_CLASS, 2 * (OBJ_ID_SIZE + 4)); |
1031 out.writeInt(serialNum); |
1099 out.writeInt(serialNum); |
1032 writeObjectID(clazz); |
1100 writeObjectID(clazz); |
|
1101 KlassMap.add(serialNum - 1, k); |
1033 out.writeInt(DUMMY_STACK_TRACE_ID); |
1102 out.writeInt(DUMMY_STACK_TRACE_ID); |
1034 writeSymbolID(k.getName()); |
1103 writeSymbolID(k.getName()); |
1035 serialNum++; |
1104 serialNum++; |
1036 } catch (IOException exp) { |
1105 } catch (IOException exp) { |
1037 throw new RuntimeException(exp); |
1106 throw new RuntimeException(exp); |
1043 try { |
1112 try { |
1044 Instance clazz = k.getJavaMirror(); |
1113 Instance clazz = k.getJavaMirror(); |
1045 writeHeader(HPROF_LOAD_CLASS, 2 * (OBJ_ID_SIZE + 4)); |
1114 writeHeader(HPROF_LOAD_CLASS, 2 * (OBJ_ID_SIZE + 4)); |
1046 out.writeInt(serialNum); |
1115 out.writeInt(serialNum); |
1047 writeObjectID(clazz); |
1116 writeObjectID(clazz); |
|
1117 KlassMap.add(serialNum - 1, k); |
1048 out.writeInt(DUMMY_STACK_TRACE_ID); |
1118 out.writeInt(DUMMY_STACK_TRACE_ID); |
1049 writeSymbolID(k.getName()); |
1119 writeSymbolID(k.getName()); |
1050 serialNum++; |
1120 serialNum++; |
1051 } catch (IOException exp) { |
1121 } catch (IOException exp) { |
1052 throw new RuntimeException(exp); |
1122 throw new RuntimeException(exp); |
1155 private DataOutputStream out; |
1225 private DataOutputStream out; |
1156 private FileOutputStream fos; |
1226 private FileOutputStream fos; |
1157 private Debugger dbg; |
1227 private Debugger dbg; |
1158 private ObjectHeap objectHeap; |
1228 private ObjectHeap objectHeap; |
1159 private SymbolTable symTbl; |
1229 private SymbolTable symTbl; |
|
1230 private ArrayList<Klass> KlassMap; |
1160 |
1231 |
1161 // oopSize of the debuggee |
1232 // oopSize of the debuggee |
1162 private int OBJ_ID_SIZE; |
1233 private int OBJ_ID_SIZE; |
1163 |
1234 |
1164 // Added for hprof file format 1.0.2 support |
1235 // Added for hprof file format 1.0.2 support |