Mercurial > hg > truffle
diff src/share/vm/services/heapDumper.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | 1d7922586cf6 |
children | d8ce2825b193 |
line wrap: on
line diff
--- a/src/share/vm/services/heapDumper.cpp Fri Aug 31 16:39:35 2012 -0700 +++ b/src/share/vm/services/heapDumper.cpp Sat Sep 01 13:25:18 2012 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -608,7 +608,7 @@ static hprofTag type2tag(BasicType type); // returns the size of the instance of the given class - static u4 instance_size(klassOop k); + static u4 instance_size(Klass* k); // dump a jfloat static void dump_float(DumpWriter* writer, jfloat f); @@ -617,26 +617,26 @@ // dumps the raw value of the given field static void dump_field_value(DumpWriter* writer, char type, address addr); // dumps static fields of the given class - static void dump_static_fields(DumpWriter* writer, klassOop k); + static void dump_static_fields(DumpWriter* writer, Klass* k); // dump the raw values of the instance fields of the given object static void dump_instance_fields(DumpWriter* writer, oop o); // dumps the definition of the instance fields for a given class - static void dump_instance_field_descriptors(DumpWriter* writer, klassOop k); + static void dump_instance_field_descriptors(DumpWriter* writer, Klass* k); // creates HPROF_GC_INSTANCE_DUMP record for the given object static void dump_instance(DumpWriter* writer, oop o); // creates HPROF_GC_CLASS_DUMP record for the given class and each of its // array classes - static void dump_class_and_array_classes(DumpWriter* writer, klassOop k); + static void dump_class_and_array_classes(DumpWriter* writer, Klass* k); // creates HPROF_GC_CLASS_DUMP record for a given primitive array // class (and each multi-dimensional array class too) - static void dump_basic_type_array_class(DumpWriter* writer, klassOop k); + static void dump_basic_type_array_class(DumpWriter* writer, Klass* k); // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array static void dump_object_array(DumpWriter* writer, objArrayOop array); // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array static void dump_prim_array(DumpWriter* writer, typeArrayOop array); // create HPROF_FRAME record for the given method and bci - static void dump_stack_frame(DumpWriter* writer, int frame_serial_num, int class_serial_num, methodOop m, int bci); + static void dump_stack_frame(DumpWriter* writer, int frame_serial_num, int class_serial_num, Method* m, int bci); }; // write a header of the given type @@ -719,17 +719,8 @@ } // reflection and sun.misc.Unsafe classes may have a reference to a - // klassOop so filter it out. - if (o != NULL && o->is_klass()) { - o = NULL; - } - - // FIXME: When sharing is enabled we don't emit field references to objects - // in shared spaces. We can remove this once we write records for the classes - // and strings that are shared. - if (o != NULL && o->is_shared()) { - o = NULL; - } + // Klass* so filter it out. + assert(o->is_oop_or_null(), "should always be an oop"); writer->write_objectID(o); break; } @@ -778,7 +769,7 @@ } // returns the size of the instance of the given class -u4 DumperSupport::instance_size(klassOop k) { +u4 DumperSupport::instance_size(Klass* k) { HandleMark hm; instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k); @@ -811,7 +802,7 @@ } // dumps static fields of the given class -void DumperSupport::dump_static_fields(DumpWriter* writer, klassOop k) { +void DumperSupport::dump_static_fields(DumpWriter* writer, Klass* k) { HandleMark hm; instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k); @@ -856,7 +847,7 @@ } // dumps the definition of the instance fields for a given class -void DumperSupport::dump_instance_field_descriptors(DumpWriter* writer, klassOop k) { +void DumperSupport::dump_instance_field_descriptors(DumpWriter* writer, Klass* k) { HandleMark hm; instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k); @@ -881,7 +872,7 @@ // creates HPROF_GC_INSTANCE_DUMP record for the given object void DumperSupport::dump_instance(DumpWriter* writer, oop o) { - klassOop k = o->klass(); + Klass* k = o->klass(); writer->write_u1(HPROF_GC_INSTANCE_DUMP); writer->write_objectID(o); @@ -899,10 +890,10 @@ // creates HPROF_GC_CLASS_DUMP record for the given class and each of // its array classes -void DumperSupport::dump_class_and_array_classes(DumpWriter* writer, klassOop k) { +void DumperSupport::dump_class_and_array_classes(DumpWriter* writer, Klass* k) { Klass* klass = Klass::cast(k); - assert(klass->oop_is_instance(), "not an instanceKlass"); - instanceKlass* ik = (instanceKlass*)klass; + assert(klass->oop_is_instance(), "not an InstanceKlass"); + InstanceKlass* ik = (InstanceKlass*)klass; writer->write_u1(HPROF_GC_CLASS_DUMP); @@ -911,9 +902,9 @@ writer->write_u4(STACK_TRACE_ID); // super class ID - klassOop java_super = ik->java_super(); + Klass* java_super = ik->java_super(); if (java_super == NULL) { - writer->write_objectID(NULL); + writer->write_objectID(oop(NULL)); } else { writer->write_classID(Klass::cast(java_super)); } @@ -923,8 +914,8 @@ writer->write_objectID(ik->protection_domain()); // reserved - writer->write_objectID(NULL); - writer->write_objectID(NULL); + writer->write_objectID(oop(NULL)); + writer->write_objectID(oop(NULL)); // instance size writer->write_u4(DumperSupport::instance_size(k)); @@ -957,8 +948,8 @@ writer->write_objectID(ik->signers()); writer->write_objectID(ik->protection_domain()); - writer->write_objectID(NULL); // reserved - writer->write_objectID(NULL); + writer->write_objectID(oop(NULL)); // reserved + writer->write_objectID(oop(NULL)); writer->write_u4(0); // instance size writer->write_u2(0); // constant pool writer->write_u2(0); // static fields @@ -971,7 +962,7 @@ // creates HPROF_GC_CLASS_DUMP record for a given primitive array // class (and each multi-dimensional array class too) -void DumperSupport::dump_basic_type_array_class(DumpWriter* writer, klassOop k) { +void DumperSupport::dump_basic_type_array_class(DumpWriter* writer, Klass* k) { // array classes while (k != NULL) { Klass* klass = Klass::cast(k); @@ -981,16 +972,16 @@ writer->write_u4(STACK_TRACE_ID); // super class of array classes is java.lang.Object - klassOop java_super = klass->java_super(); + Klass* java_super = klass->java_super(); assert(java_super != NULL, "checking"); writer->write_classID(Klass::cast(java_super)); - writer->write_objectID(NULL); // loader - writer->write_objectID(NULL); // signers - writer->write_objectID(NULL); // protection domain + writer->write_objectID(oop(NULL)); // loader + writer->write_objectID(oop(NULL)); // signers + writer->write_objectID(oop(NULL)); // protection domain - writer->write_objectID(NULL); // reserved - writer->write_objectID(NULL); + writer->write_objectID(oop(NULL)); // reserved + writer->write_objectID(oop(NULL)); writer->write_u4(0); // instance size writer->write_u2(0); // constant pool writer->write_u2(0); // static fields @@ -1004,9 +995,6 @@ // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array void DumperSupport::dump_object_array(DumpWriter* writer, objArrayOop array) { - // filter this - if (array->klass() == Universe::systemObjArrayKlassObj()) return; - writer->write_u1(HPROF_GC_OBJ_ARRAY_DUMP); writer->write_objectID(array); writer->write_u4(STACK_TRACE_ID); @@ -1111,11 +1099,11 @@ } } -// create a HPROF_FRAME record of the given methodOop and bci +// create a HPROF_FRAME record of the given Method* and bci void DumperSupport::dump_stack_frame(DumpWriter* writer, int frame_serial_num, int class_serial_num, - methodOop m, + Method* m, int bci) { int line_number; if (m->is_native()) { @@ -1129,8 +1117,8 @@ writer->write_symbolID(m->name()); // method's name writer->write_symbolID(m->signature()); // method's signature - assert(Klass::cast(m->method_holder())->oop_is_instance(), "not instanceKlass"); - writer->write_symbolID(instanceKlass::cast(m->method_holder())->source_file_name()); // source file name + assert(Klass::cast(m->method_holder())->oop_is_instance(), "not InstanceKlass"); + writer->write_symbolID(InstanceKlass::cast(m->method_holder())->source_file_name()); // source file name writer->write_u4(class_serial_num); // class serial number writer->write_u4((u4) line_number); // line number } @@ -1242,7 +1230,7 @@ // Support class used to generate HPROF_GC_ROOT_STICKY_CLASS records -class StickyClassDumper : public OopClosure { +class StickyClassDumper : public KlassClosure { private: DumpWriter* _writer; DumpWriter* writer() const { return _writer; } @@ -1250,23 +1238,14 @@ StickyClassDumper(DumpWriter* writer) { _writer = writer; } - void do_oop(oop* obj_p); - void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); } -}; - -void StickyClassDumper::do_oop(oop* obj_p) { - if (*obj_p != NULL) { - oop o = *obj_p; - if (o->is_klass()) { - klassOop k = klassOop(o); - if (Klass::cast(k)->oop_is_instance()) { - instanceKlass* ik = instanceKlass::cast(k); + void do_klass(Klass* k) { + if (k->oop_is_instance()) { + InstanceKlass* ik = InstanceKlass::cast(k); writer()->write_u1(HPROF_GC_ROOT_STICKY_CLASS); writer()->write_classID(ik); } } - } -} +}; class VM_HeapDumper; @@ -1298,9 +1277,6 @@ // hide the sentinel for deleted handles if (o == JNIHandles::deleted_handle()) return; - // ignore KlassKlass objects - if (o->is_klass()) return; - // skip classes as these emitted as HPROF_GC_CLASS_DUMP records if (o->klass() == SystemDictionary::Class_klass()) { if (!java_lang_Class::is_primitive(o)) { @@ -1334,7 +1310,7 @@ static DumpWriter* _global_writer; DumpWriter* _local_writer; JavaThread* _oome_thread; - methodOop _oome_constructor; + Method* _oome_constructor; bool _gc_before_heap_dump; bool _is_segmented_dump; jlong _dump_start; @@ -1364,15 +1340,15 @@ bool skip_operation() const; // writes a HPROF_LOAD_CLASS record - static void do_load_class(klassOop k); + static void do_load_class(Klass* k); // writes a HPROF_GC_CLASS_DUMP record for the given class // (and each array class too) - static void do_class_dump(klassOop k); + static void do_class_dump(Klass* k); // writes a HPROF_GC_CLASS_DUMP records for a given basic type // array (and each multi-dimensional array too) - static void do_basic_type_array_class_dump(klassOop k); + static void do_basic_type_array_class_dump(Klass* k); // HPROF_GC_ROOT_THREAD_OBJ records int do_thread(JavaThread* thread, u4 thread_serial_num); @@ -1411,7 +1387,7 @@ if (oome) { assert(!Thread::current()->is_VM_thread(), "Dump from OutOfMemoryError cannot be called by the VMThread"); // get OutOfMemoryError zero-parameter constructor - instanceKlass* oome_ik = instanceKlass::cast(SystemDictionary::OutOfMemoryError_klass()); + InstanceKlass* oome_ik = InstanceKlass::cast(SystemDictionary::OutOfMemoryError_klass()); _oome_constructor = oome_ik->find_method(vmSymbols::object_initializer_name(), vmSymbols::void_method_signature()); // get thread throwing OOME when generating the heap dump at OOME @@ -1535,7 +1511,7 @@ // writes a HPROF_LOAD_CLASS record for the class (and each of its // array classes) -void VM_HeapDumper::do_load_class(klassOop k) { +void VM_HeapDumper::do_load_class(Klass* k) { static u4 class_serial_num = 0; // len of HPROF_LOAD_CLASS record @@ -1552,7 +1528,7 @@ Klass* klass = Klass::cast(k); writer()->write_classID(klass); - // add the klassOop and class serial number pair + // add the Klass* and class serial number pair dumper()->add_class_serial_number(klass, class_serial_num); writer()->write_u4(STACK_TRACE_ID); @@ -1567,13 +1543,13 @@ } // writes a HPROF_GC_CLASS_DUMP record for the given class -void VM_HeapDumper::do_class_dump(klassOop k) { +void VM_HeapDumper::do_class_dump(Klass* k) { DumperSupport::dump_class_and_array_classes(writer(), k); } // writes a HPROF_GC_CLASS_DUMP records for a given basic type // array (and each multi-dimensional array too) -void VM_HeapDumper::do_basic_type_array_class_dump(klassOop k) { +void VM_HeapDumper::do_basic_type_array_class_dump(Klass* k) { DumperSupport::dump_basic_type_array_class(writer(), k); } @@ -1785,7 +1761,7 @@ // HPROF_GC_ROOT_STICKY_CLASS StickyClassDumper class_dumper(writer()); - SystemDictionary::always_strong_oops_do(&class_dumper); + SystemDictionary::always_strong_classes_do(&class_dumper); // fixes up the length of the dump record. In the case of a segmented // heap then the HPROF_HEAP_DUMP_END record is also written. @@ -1829,7 +1805,7 @@ } for (int j=0; j < depth; j++) { StackFrameInfo* frame = stack_trace->stack_frame_at(j); - methodOop m = frame->method(); + Method* m = frame->method(); int class_serial_num = _klass_map->find(Klass::cast(m->method_holder())); // the class serial number starts from 1 assert(class_serial_num > 0, "class not found");