src/share/vm/memory/heapInspection.cpp

Print this page
rev 4274 : 8008920: Tracing events for heap statistics

@@ -226,63 +226,88 @@
 
 class RecordInstanceClosure : public ObjectClosure {
  private:
   KlassInfoTable* _cit;
   size_t _missed_count;
+  BoolObjectClosure* _filter;
  public:
-  RecordInstanceClosure(KlassInfoTable* cit) :
-    _cit(cit), _missed_count(0) {}
+  RecordInstanceClosure(BoolObjectClosure* filter, KlassInfoTable* cit) :
+    _cit(cit), _missed_count(0), _filter(filter) {}
 
   void do_object(oop obj) {
+    if (should_visit(obj)) {
     if (!_cit->record_instance(obj)) {
       _missed_count++;
     }
   }
+  }
 
   size_t missed_count() { return _missed_count; }
+
+ private:
+  bool should_visit(oop obj) {
+    return _filter == NULL || _filter->do_object_b(obj);
+  }
 };
 
-void HeapInspection::heap_inspection(outputStream* st, bool need_prologue) {
+size_t HeapInspection::iterate_over_heap(KlassInfoTable* cit) {
+  return iterate_over_heap(NULL, cit);
+}
+
+size_t HeapInspection::iterate_over_heap(BoolObjectClosure* object_filter, KlassInfoTable* cit) {
+  RecordInstanceClosure ric(object_filter, cit);
+  Universe::heap()->object_iterate(&ric);
+  return ric.missed_count();
+}
+
+void HeapInspection::instance_inspection(KlassInfoClosure* closure) {
+  return instance_inspection(NULL, closure);
+}
+
+void HeapInspection::instance_inspection(BoolObjectClosure* object_filter,
+                                         KlassInfoClosure* closure) {
   ResourceMark rm;
-  HeapWord* ref;
 
-  CollectedHeap* heap = Universe::heap();
-  bool is_shared_heap = false;
-  switch (heap->kind()) {
-    case CollectedHeap::G1CollectedHeap:
-    case CollectedHeap::GenCollectedHeap: {
-      is_shared_heap = true;
-      SharedHeap* sh = (SharedHeap*)heap;
-      if (need_prologue) {
-        sh->gc_prologue(false /* !full */); // get any necessary locks, etc.
+  KlassInfoTable cit(KlassInfoTable::cit_size, create_random_seed());
+
+  if (!cit.allocation_failed()) {
+    iterate_over_heap(object_filter, &cit);
+    cit.iterate(closure);
       }
-      ref = sh->perm_gen()->used_region().start();
-      break;
+}
+
+HeapWord* HeapInspection::create_random_seed() {
+  if (is_shared_heap()) {
+    SharedHeap* sh = (SharedHeap*)Universe::heap();
+    return sh->perm_gen()->used_region().start();
     }
 #ifndef SERIALGC
-    case CollectedHeap::ParallelScavengeHeap: {
-      ParallelScavengeHeap* psh = (ParallelScavengeHeap*)heap;
-      ref = psh->perm_gen()->object_space()->used_region().start();
-      break;
-    }
+  ParallelScavengeHeap* psh = (ParallelScavengeHeap*)Universe::heap();
+  return psh->perm_gen()->object_space()->used_region().start();
 #endif // SERIALGC
-    default:
-      ShouldNotReachHere(); // Unexpected heap kind for this op
+  ShouldNotReachHere();
+  return NULL;
+}
+
+bool HeapInspection::is_shared_heap() {
+  CollectedHeap* heap = Universe::heap();
+  return heap->kind() == CollectedHeap::G1CollectedHeap ||
+         heap->kind() == CollectedHeap::GenCollectedHeap;
+}
+
+void HeapInspection::heap_inspection(outputStream* st, bool need_prologue) {
+  ResourceMark rm;
+
+  if (need_prologue && is_shared_heap()) {
+    SharedHeap* sh = (SharedHeap*)Universe::heap();
+    sh->gc_prologue(false /* !full */); // get any necessary locks, etc.
   }
+
   // Collect klass instance info
-  KlassInfoTable cit(KlassInfoTable::cit_size, ref);
+  KlassInfoTable cit(KlassInfoTable::cit_size, create_random_seed());
   if (!cit.allocation_failed()) {
-    // Iterate over objects in the heap
-    RecordInstanceClosure ric(&cit);
-    // If this operation encounters a bad object when using CMS,
-    // consider using safe_object_iterate() which avoids perm gen
-    // objects that may contain bad references.
-    Universe::heap()->object_iterate(&ric);
-
-    // Report if certain classes are not counted because of
-    // running out of C-heap for the histogram.
-    size_t missed_count = ric.missed_count();
+    size_t missed_count = iterate_over_heap(&cit);
     if (missed_count != 0) {
       st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT
                    " total instances in data below",
                    missed_count);
     }

@@ -298,12 +323,12 @@
   } else {
     st->print_cr("WARNING: Ran out of C-heap; histogram not generated");
   }
   st->flush();
 
-  if (need_prologue && is_shared_heap) {
-    SharedHeap* sh = (SharedHeap*)heap;
+  if (need_prologue && is_shared_heap()) {
+    SharedHeap* sh = (SharedHeap*)Universe::heap();
     sh->gc_epilogue(false /* !full */); // release all acquired locks, etc.
   }
 }
 
 class FindInstanceClosure : public ObjectClosure {