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");