Mercurial > hg > truffle
comparison src/share/vm/services/heapDumper.cpp @ 2177:3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
Summary: move symbols from permgen into C heap and reference count them
Reviewed-by: never, acorn, jmasa, stefank
author | coleenp |
---|---|
date | Thu, 27 Jan 2011 16:11:27 -0800 |
parents | 17c778814856 |
children | c798c277ddd1 |
comparison
equal
deleted
inserted
replaced
2176:27e4ea99855d | 2177:3582bf76420e |
---|---|
423 void write_u1(u1 x) { write_raw((void*)&x, 1); } | 423 void write_u1(u1 x) { write_raw((void*)&x, 1); } |
424 void write_u2(u2 x); | 424 void write_u2(u2 x); |
425 void write_u4(u4 x); | 425 void write_u4(u4 x); |
426 void write_u8(u8 x); | 426 void write_u8(u8 x); |
427 void write_objectID(oop o); | 427 void write_objectID(oop o); |
428 void write_symbolID(Symbol* o); | |
428 void write_classID(Klass* k); | 429 void write_classID(Klass* k); |
429 void write_id(u4 x); | 430 void write_id(u4 x); |
430 }; | 431 }; |
431 | 432 |
432 DumpWriter::DumpWriter(const char* path) { | 433 DumpWriter::DumpWriter(const char* path) { |
566 #else | 567 #else |
567 write_u4((u4)a); | 568 write_u4((u4)a); |
568 #endif | 569 #endif |
569 } | 570 } |
570 | 571 |
572 void DumpWriter::write_symbolID(Symbol* s) { | |
573 address a = (address)((uintptr_t)s); | |
574 #ifdef _LP64 | |
575 write_u8((u8)a); | |
576 #else | |
577 write_u4((u4)a); | |
578 #endif | |
579 } | |
580 | |
571 void DumpWriter::write_id(u4 x) { | 581 void DumpWriter::write_id(u4 x) { |
572 #ifdef _LP64 | 582 #ifdef _LP64 |
573 write_u8((u8) x); | 583 write_u8((u8) x); |
574 #else | 584 #else |
575 write_u4(x); | 585 write_u4(x); |
590 | 600 |
591 // write a header of the given type | 601 // write a header of the given type |
592 static void write_header(DumpWriter* writer, hprofTag tag, u4 len); | 602 static void write_header(DumpWriter* writer, hprofTag tag, u4 len); |
593 | 603 |
594 // returns hprof tag for the given type signature | 604 // returns hprof tag for the given type signature |
595 static hprofTag sig2tag(symbolOop sig); | 605 static hprofTag sig2tag(Symbol* sig); |
596 // returns hprof tag for the given basic type | 606 // returns hprof tag for the given basic type |
597 static hprofTag type2tag(BasicType type); | 607 static hprofTag type2tag(BasicType type); |
598 | 608 |
599 // returns the size of the instance of the given class | 609 // returns the size of the instance of the given class |
600 static u4 instance_size(klassOop k); | 610 static u4 instance_size(klassOop k); |
634 writer->write_u4(0); // current ticks | 644 writer->write_u4(0); // current ticks |
635 writer->write_u4(len); | 645 writer->write_u4(len); |
636 } | 646 } |
637 | 647 |
638 // returns hprof tag for the given type signature | 648 // returns hprof tag for the given type signature |
639 hprofTag DumperSupport::sig2tag(symbolOop sig) { | 649 hprofTag DumperSupport::sig2tag(Symbol* sig) { |
640 switch (sig->byte_at(0)) { | 650 switch (sig->byte_at(0)) { |
641 case JVM_SIGNATURE_CLASS : return HPROF_NORMAL_OBJECT; | 651 case JVM_SIGNATURE_CLASS : return HPROF_NORMAL_OBJECT; |
642 case JVM_SIGNATURE_ARRAY : return HPROF_NORMAL_OBJECT; | 652 case JVM_SIGNATURE_ARRAY : return HPROF_NORMAL_OBJECT; |
643 case JVM_SIGNATURE_BYTE : return HPROF_BYTE; | 653 case JVM_SIGNATURE_BYTE : return HPROF_BYTE; |
644 case JVM_SIGNATURE_CHAR : return HPROF_CHAR; | 654 case JVM_SIGNATURE_CHAR : return HPROF_CHAR; |
773 | 783 |
774 int size = 0; | 784 int size = 0; |
775 | 785 |
776 for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) { | 786 for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) { |
777 if (!fld.access_flags().is_static()) { | 787 if (!fld.access_flags().is_static()) { |
778 symbolOop sig = fld.signature(); | 788 Symbol* sig = fld.signature(); |
779 switch (sig->byte_at(0)) { | 789 switch (sig->byte_at(0)) { |
780 case JVM_SIGNATURE_CLASS : | 790 case JVM_SIGNATURE_CLASS : |
781 case JVM_SIGNATURE_ARRAY : size += oopSize; break; | 791 case JVM_SIGNATURE_ARRAY : size += oopSize; break; |
782 | 792 |
783 case JVM_SIGNATURE_BYTE : | 793 case JVM_SIGNATURE_BYTE : |
813 writer->write_u2(field_count); | 823 writer->write_u2(field_count); |
814 | 824 |
815 // pass 2 - dump the field descriptors and raw values | 825 // pass 2 - dump the field descriptors and raw values |
816 for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) { | 826 for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) { |
817 if (fld.access_flags().is_static()) { | 827 if (fld.access_flags().is_static()) { |
818 symbolOop sig = fld.signature(); | 828 Symbol* sig = fld.signature(); |
819 | 829 |
820 writer->write_objectID(fld.name()); // name | 830 writer->write_symbolID(fld.name()); // name |
821 writer->write_u1(sig2tag(sig)); // type | 831 writer->write_u1(sig2tag(sig)); // type |
822 | 832 |
823 // value | 833 // value |
824 int offset = fld.offset(); | 834 int offset = fld.offset(); |
825 address addr = (address)k + offset; | 835 address addr = (address)k + offset; |
834 HandleMark hm; | 844 HandleMark hm; |
835 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), o->klass()); | 845 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), o->klass()); |
836 | 846 |
837 for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) { | 847 for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) { |
838 if (!fld.access_flags().is_static()) { | 848 if (!fld.access_flags().is_static()) { |
839 symbolOop sig = fld.signature(); | 849 Symbol* sig = fld.signature(); |
840 address addr = (address)o + fld.offset(); | 850 address addr = (address)o + fld.offset(); |
841 | 851 |
842 dump_field_value(writer, sig->byte_at(0), addr); | 852 dump_field_value(writer, sig->byte_at(0), addr); |
843 } | 853 } |
844 } | 854 } |
858 writer->write_u2(field_count); | 868 writer->write_u2(field_count); |
859 | 869 |
860 // pass 2 - dump the field descriptors | 870 // pass 2 - dump the field descriptors |
861 for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) { | 871 for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) { |
862 if (!fld.access_flags().is_static()) { | 872 if (!fld.access_flags().is_static()) { |
863 symbolOop sig = fld.signature(); | 873 Symbol* sig = fld.signature(); |
864 | 874 |
865 writer->write_objectID(fld.name()); // name | 875 writer->write_symbolID(fld.name()); // name |
866 writer->write_u1(sig2tag(sig)); // type | 876 writer->write_u1(sig2tag(sig)); // type |
867 } | 877 } |
868 } | 878 } |
869 } | 879 } |
870 | 880 |
1113 line_number = m->line_number_from_bci(bci); | 1123 line_number = m->line_number_from_bci(bci); |
1114 } | 1124 } |
1115 | 1125 |
1116 write_header(writer, HPROF_FRAME, 4*oopSize + 2*sizeof(u4)); | 1126 write_header(writer, HPROF_FRAME, 4*oopSize + 2*sizeof(u4)); |
1117 writer->write_id(frame_serial_num); // frame serial number | 1127 writer->write_id(frame_serial_num); // frame serial number |
1118 writer->write_objectID(m->name()); // method's name | 1128 writer->write_symbolID(m->name()); // method's name |
1119 writer->write_objectID(m->signature()); // method's signature | 1129 writer->write_symbolID(m->signature()); // method's signature |
1120 | 1130 |
1121 assert(Klass::cast(m->method_holder())->oop_is_instance(), "not instanceKlass"); | 1131 assert(Klass::cast(m->method_holder())->oop_is_instance(), "not instanceKlass"); |
1122 writer->write_objectID(instanceKlass::cast(m->method_holder())->source_file_name()); // source file name | 1132 writer->write_symbolID(instanceKlass::cast(m->method_holder())->source_file_name()); // source file name |
1123 writer->write_u4(class_serial_num); // class serial number | 1133 writer->write_u4(class_serial_num); // class serial number |
1124 writer->write_u4((u4) line_number); // line number | 1134 writer->write_u4((u4) line_number); // line number |
1125 } | 1135 } |
1126 | 1136 |
1137 | |
1127 // Support class used to generate HPROF_UTF8 records from the entries in the | 1138 // Support class used to generate HPROF_UTF8 records from the entries in the |
1128 // SymbolTable. | 1139 // SymbolTable. |
1129 | 1140 |
1130 class SymbolTableDumper : public OopClosure { | 1141 class SymbolTableDumper : public SymbolClosure { |
1131 private: | 1142 private: |
1132 DumpWriter* _writer; | 1143 DumpWriter* _writer; |
1133 DumpWriter* writer() const { return _writer; } | 1144 DumpWriter* writer() const { return _writer; } |
1134 public: | 1145 public: |
1135 SymbolTableDumper(DumpWriter* writer) { _writer = writer; } | 1146 SymbolTableDumper(DumpWriter* writer) { _writer = writer; } |
1136 void do_oop(oop* obj_p); | 1147 void do_symbol(Symbol** p); |
1137 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); } | |
1138 }; | 1148 }; |
1139 | 1149 |
1140 void SymbolTableDumper::do_oop(oop* obj_p) { | 1150 void SymbolTableDumper::do_symbol(Symbol** p) { |
1141 ResourceMark rm; | 1151 ResourceMark rm; |
1142 symbolOop sym = (symbolOop)*obj_p; | 1152 Symbol* sym = load_symbol(p); |
1143 | |
1144 int len = sym->utf8_length(); | 1153 int len = sym->utf8_length(); |
1145 if (len > 0) { | 1154 if (len > 0) { |
1146 char* s = sym->as_utf8(); | 1155 char* s = sym->as_utf8(); |
1147 DumperSupport::write_header(writer(), HPROF_UTF8, oopSize + len); | 1156 DumperSupport::write_header(writer(), HPROF_UTF8, oopSize + len); |
1148 writer()->write_objectID(sym); | 1157 writer()->write_symbolID(sym); |
1149 writer()->write_raw(s, len); | 1158 writer()->write_raw(s, len); |
1150 } | 1159 } |
1151 } | 1160 } |
1152 | |
1153 | 1161 |
1154 // Support class used to generate HPROF_GC_ROOT_JNI_LOCAL records | 1162 // Support class used to generate HPROF_GC_ROOT_JNI_LOCAL records |
1155 | 1163 |
1156 class JNILocalsDumper : public OopClosure { | 1164 class JNILocalsDumper : public OopClosure { |
1157 private: | 1165 private: |
1546 dumper()->add_class_serial_number(klass, class_serial_num); | 1554 dumper()->add_class_serial_number(klass, class_serial_num); |
1547 | 1555 |
1548 writer()->write_u4(STACK_TRACE_ID); | 1556 writer()->write_u4(STACK_TRACE_ID); |
1549 | 1557 |
1550 // class name ID | 1558 // class name ID |
1551 symbolOop name = klass->name(); | 1559 Symbol* name = klass->name(); |
1552 writer()->write_objectID(name); | 1560 writer()->write_symbolID(name); |
1553 | 1561 |
1554 // write a LOAD_CLASS record for the array type (if it exists) | 1562 // write a LOAD_CLASS record for the array type (if it exists) |
1555 k = klass->array_klass_or_null(); | 1563 k = klass->array_klass_or_null(); |
1556 } while (k != NULL); | 1564 } while (k != NULL); |
1557 } | 1565 } |
1725 writer()->write_u4(oopSize); | 1733 writer()->write_u4(oopSize); |
1726 writer()->write_u8(os::javaTimeMillis()); | 1734 writer()->write_u8(os::javaTimeMillis()); |
1727 | 1735 |
1728 // HPROF_UTF8 records | 1736 // HPROF_UTF8 records |
1729 SymbolTableDumper sym_dumper(writer()); | 1737 SymbolTableDumper sym_dumper(writer()); |
1730 SymbolTable::oops_do(&sym_dumper); | 1738 SymbolTable::symbols_do(&sym_dumper); |
1731 | 1739 |
1732 // write HPROF_LOAD_CLASS records | 1740 // write HPROF_LOAD_CLASS records |
1733 SystemDictionary::classes_do(&do_load_class); | 1741 SystemDictionary::classes_do(&do_load_class); |
1734 Universe::basic_type_classes_do(&do_load_class); | 1742 Universe::basic_type_classes_do(&do_load_class); |
1735 | 1743 |