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