changeset 4360:d44caacedf85

Merge
author neliasso
date Thu, 11 Apr 2013 04:25:49 -0400
parents d67b08a0b6c0 7c942384867f
children e40faea12793
files src/share/vm/trace/trace.xml
diffstat 14 files changed, 104 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Mon Mar 25 14:03:21 2013 +0100
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Thu Apr 11 04:25:49 2013 -0400
@@ -2205,6 +2205,7 @@
     } else {
       assert(_collectorState == Idling, "Should be idling before start.");
       _collectorState = InitialMarking;
+      register_gc_start(GCCause::_cms_concurrent_mark);
       // Reset the expansion cause, now that we are about to begin
       // a new cycle.
       clear_expansion_cause();
@@ -2427,13 +2428,16 @@
   }
 }
 
+void CMSCollector::register_foreground_gc_start(GCCause::Cause cause) {
+  if (!_cms_start_registered) {
+    register_gc_start(cause);
+  }
+}
+
 void CMSCollector::register_gc_start(GCCause::Cause cause) {
   _cms_start_registered = true;
   _gc_timer_cm->register_gc_start(os::elapsed_counter());
   _gc_tracer_cm->report_gc_start(cause, _gc_timer_cm->gc_start());
-
-  save_heap_summary();
-  report_heap_summary(GCWhen::BeforeGC);
 }
 
 void CMSCollector::register_gc_end() {
@@ -2489,7 +2493,7 @@
     }
     switch (_collectorState) {
       case InitialMarking:
-        register_gc_start(GenCollectedHeap::heap()->gc_cause());
+        register_foreground_gc_start(GenCollectedHeap::heap()->gc_cause());
         init_mark_was_synchronous = true;  // fact to be exploited in re-mark
         checkpointRootsInitial(false);
         assert(_collectorState == Marking, "Collector state should have changed"
@@ -3527,6 +3531,9 @@
   check_correct_thread_executing();
   TraceCMSMemoryManagerStats tms(_collectorState,GenCollectedHeap::heap()->gc_cause());
 
+  save_heap_summary();
+  report_heap_summary(GCWhen::BeforeGC);
+
   ReferenceProcessor* rp = ref_processor();
   SpecializationStats::clear();
   assert(_restart_addr == NULL, "Control point invariant");
@@ -5081,6 +5088,8 @@
     verify_after_remark();
   }
 
+  _gc_tracer_cm->report_object_count_after_gc(&_is_alive_closure);
+
   // Change under the freelistLocks.
   _collectorState = Sweeping;
   // Call isAllClear() under bitMapLock
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Mon Mar 25 14:03:21 2013 +0100
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Thu Apr 11 04:25:49 2013 -0400
@@ -621,6 +621,7 @@
   GCHeapSummary _last_heap_summary;
   PermGenSummary _last_perm_gen_summary;
 
+  void register_foreground_gc_start(GCCause::Cause cause);
   void register_gc_start(GCCause::Cause cause);
   void register_gc_end();
   void save_heap_summary();
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp	Mon Mar 25 14:03:21 2013 +0100
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp	Thu Apr 11 04:25:49 2013 -0400
@@ -145,7 +145,6 @@
                                 );
 #endif /* USDT2 */
 
-  _collector->register_gc_start(GCCause::_cms_concurrent_mark);
   _collector->_gc_timer_cm->register_gc_pause_start("Initial Mark", os::elapsed_counter());
 
   GenCollectedHeap* gch = GenCollectedHeap::heap();
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Mon Mar 25 14:03:21 2013 +0100
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu Apr 11 04:25:49 2013 -0400
@@ -1202,6 +1202,9 @@
   _remark_times.add((now - start) * 1000.0);
 
   g1p->record_concurrent_mark_remark_end();
+
+  G1CMIsAliveClosure is_alive(g1h);
+  g1h->gc_tracer_cm()->report_object_count_after_gc(&is_alive);
 }
 
 // Base class of the closures that finalize and verify the
--- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Mon Mar 25 14:03:21 2013 +0100
+++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Thu Apr 11 04:25:49 2013 -0400
@@ -206,6 +206,8 @@
     G1CollectedHeap* g1h = G1CollectedHeap::heap();
     gclog_or_tty->print_cr("]");
   }
+
+  gc_tracer()->report_object_count_after_gc(&GenMarkSweep::is_alive);
 }
 
 class G1PrepareCompactClosure: public HeapRegionClosure {
--- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Mon Mar 25 14:03:21 2013 +0100
+++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Thu Apr 11 04:25:49 2013 -0400
@@ -566,6 +566,7 @@
   SymbolTable::unlink();
 
   assert(_marking_stack.is_empty(), "stack should be empty by now");
+  _gc_tracer->report_object_count_after_gc(is_alive_closure());
 }
 
 
--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Mon Mar 25 14:03:21 2013 +0100
+++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Thu Apr 11 04:25:49 2013 -0400
@@ -2443,6 +2443,7 @@
   SymbolTable::unlink();
 
   assert(cm->marking_stacks_empty(), "marking stacks should be empty");
+  _gc_tracer.report_object_count_after_gc(is_alive_closure());
 }
 
 // This should be moved to the shared markSweep code!
--- a/src/share/vm/gc_implementation/shared/gcTrace.cpp	Mon Mar 25 14:03:21 2013 +0100
+++ b/src/share/vm/gc_implementation/shared/gcTrace.cpp	Thu Apr 11 04:25:49 2013 -0400
@@ -27,6 +27,8 @@
 #include "gc_implementation/shared/gcTimer.hpp"
 #include "gc_implementation/shared/gcTrace.hpp"
 #include "gc_implementation/shared/copyFailedInfo.hpp"
+#include "memory/heapInspection.hpp"
+#include "memory/iterator.hpp"
 #include "memory/referenceProcessorStats.hpp"
 #include "utilities/globalDefinitions.hpp"
 
@@ -85,6 +87,29 @@
   send_reference_stats_event(REF_PHANTOM, rps.phantom_count());
 }
 
+class ObjectCountEventSenderClosure : public KlassInfoClosure {
+  GCTracer* _gc_tracer;
+ public:
+  ObjectCountEventSenderClosure(GCTracer* gc_tracer) : _gc_tracer(gc_tracer) {}
+ private:
+  void do_cinfo(KlassInfoEntry* entry) {
+    _gc_tracer->send_object_count_after_gc_event(entry->klass(), entry->count(),
+                                                 entry->words() * BytesPerWord);
+  }
+};
+
+void GCTracer::report_object_count_after_gc(BoolObjectClosure *is_alive_cl) {
+  if (should_send_object_count_after_gc_event()) {
+    ResourceMark rm;
+
+    KlassInfoTable cit(HeapInspection::start_of_perm_gen());
+    if (!cit.allocation_failed()) {
+      ObjectCountEventSenderClosure event_sender(this);
+      HeapInspection::instance_inspection(&cit, &event_sender, false, is_alive_cl);
+    }
+  }
+}
+
 void GCTracer::report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary, const PermGenSummary& perm_gen_summary) const {
   assert_set_gc_id();
 
--- a/src/share/vm/gc_implementation/shared/gcTrace.hpp	Mon Mar 25 14:03:21 2013 +0100
+++ b/src/share/vm/gc_implementation/shared/gcTrace.hpp	Thu Apr 11 04:25:49 2013 -0400
@@ -42,6 +42,7 @@
 class PSHeapSummary;
 class ReferenceProcessorStats;
 class TimePartitions;
+class BoolObjectClosure;
 
 class SharedGCInfo VALUE_OBJ_CLASS_SPEC {
   static const jlong UNSET_TIMESTAMP = -1;
@@ -109,6 +110,7 @@
 #endif // SERIALGC
 
 class GCTracer : public ResourceObj {
+  friend class ObjectCountEventSenderClosure;
  protected:
   SharedGCInfo _shared_gc_info;
 
@@ -117,6 +119,7 @@
   void report_gc_end(jlong timestamp, TimePartitions* time_partitions);
   void report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary, const PermGenSummary& perm_gen_summary) const;
   void report_gc_reference_stats(const ReferenceProcessorStats& rp) const;
+  void report_object_count_after_gc(BoolObjectClosure* object_filter);
 
   bool has_reported_gc_start() const;
 
@@ -131,6 +134,8 @@
   void send_perm_gen_summary_event(GCWhen::Type when, const PermGenSummary& perm_gen_summary) const;
   void send_reference_stats_event(ReferenceType type, size_t count) const;
   void send_phase_events(TimePartitions* time_partitions) const;
+  void send_object_count_after_gc_event(klassOop klass, jlong count, julong total_size) const;
+  bool should_send_object_count_after_gc_event() const;
 };
 
 class YoungGCTracer : public GCTracer {
--- a/src/share/vm/gc_implementation/shared/gcTraceSend.cpp	Mon Mar 25 14:03:21 2013 +0100
+++ b/src/share/vm/gc_implementation/shared/gcTraceSend.cpp	Thu Apr 11 04:25:49 2013 -0400
@@ -28,6 +28,7 @@
 #include "gc_implementation/shared/gcTrace.hpp"
 #include "gc_implementation/shared/gcWhen.hpp"
 #include "gc_implementation/shared/copyFailedInfo.hpp"
+#include "trace/traceBackend.hpp"
 #include "trace/tracing.hpp"
 #ifndef SERIALGC
 #include "gc_implementation/g1/g1YCTypes.hpp"
@@ -120,6 +121,25 @@
   }
 }
 
+void GCTracer::send_object_count_after_gc_event(klassOop klass, jlong count, julong total_size) const {
+  EventObjectCountAfterGC e;
+  if (e.should_commit()) {
+    e.set_gcId(_shared_gc_info.id());
+    e.set_class(klass);
+    e.set_count(count);
+    e.set_totalSize(total_size);
+    e.commit();
+  }
+}
+
+bool GCTracer::should_send_object_count_after_gc_event() const {
+#if INCLUDE_TRACE
+  return Tracing::enabled(EventObjectCountAfterGC::eventId);
+#else
+  return false;
+#endif
+}
+
 #ifndef SERIALGC
 void G1NewTracer::send_g1_young_gc_event() {
   EventGCG1GarbageCollection e(UNTIMED);
--- a/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Mon Mar 25 14:03:21 2013 +0100
+++ b/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Thu Apr 11 04:25:49 2013 -0400
@@ -144,27 +144,33 @@
   return false;
 }
 
-void VM_GC_HeapInspection::doit() {
-  HandleMark hm;
+bool VM_GC_HeapInspection::collect() {
   CollectedHeap* ch = Universe::heap();
   ch->ensure_parsability(false); // must happen, even if collection does
                                  // not happen (e.g. due to GC_locker)
+
+  if (GC_locker::is_active()) {
+    return false;
+  }
+  ch->collect_as_vm_thread(GCCause::_heap_inspection);
+  return true;
+}
+
+void VM_GC_HeapInspection::doit() {
+  HandleMark hm;
   if (_full_gc) {
-    // The collection attempt below would be skipped anyway if
-    // the gc locker is held. The following dump may then be a tad
-    // misleading to someone expecting only live objects to show
-    // up in the dump (see CR 6944195). Just issue a suitable warning
-    // in that case and do not attempt to do a collection.
-    // The latter is a subtle point, because even a failed attempt
-    // to GC will, in fact, induce one in the future, which we
-    // probably want to avoid in this case because the GC that we may
-    // be about to attempt holds value for us only
-    // if it happens now and not if it happens in the eventual
-    // future.
-    if (GC_locker::is_active()) {
+    if (!collect()) {
+      // The collection attempt was skipped because the gc locker is held.
+      // The following dump may then be a tad misleading to someone expecting
+      // only live objects to show up in the dump (see CR 6944195). Just issue
+      // a suitable warning in that case and do not attempt to do a collection.
+      // The latter is a subtle point, because even a failed attempt
+      // to GC will, in fact, induce one in the future, which we
+      // probably want to avoid in this case because the GC that we may
+      // be about to attempt holds value for us only
+      // if it happens now and not if it happens in the eventual
+      // future.
       warning("GC locker is held; pre-dump GC was skipped");
-    } else {
-      ch->collect_as_vm_thread(GCCause::_heap_inspection);
     }
   }
   HeapInspection::heap_inspection(_out, _need_prologue /* need_prologue */);
--- a/src/share/vm/gc_implementation/shared/vmGCOperations.hpp	Mon Mar 25 14:03:21 2013 +0100
+++ b/src/share/vm/gc_implementation/shared/vmGCOperations.hpp	Thu Apr 11 04:25:49 2013 -0400
@@ -150,6 +150,8 @@
   virtual bool skip_operation() const;
   virtual bool doit_prologue();
   virtual void doit();
+ protected:
+  bool collect();
 };
 
 
--- a/src/share/vm/memory/genMarkSweep.cpp	Mon Mar 25 14:03:21 2013 +0100
+++ b/src/share/vm/memory/genMarkSweep.cpp	Thu Apr 11 04:25:49 2013 -0400
@@ -318,6 +318,8 @@
   SymbolTable::unlink();
 
   assert(_marking_stack.is_empty(), "stack should be empty by now");
+
+  gc_tracer()->report_object_count_after_gc(&is_alive);
 }
 
 
--- a/src/share/vm/trace/trace.xml	Mon Mar 25 14:03:21 2013 +0100
+++ b/src/share/vm/trace/trace.xml	Thu Apr 11 04:25:49 2013 -0400
@@ -198,6 +198,13 @@
       <value type="OSTHREAD" field="thread" label="Running thread"/>
     </struct>
 
+    <event id="ObjectCountAfterGC" path="vm/gc/detailed/object_count_after_gc" is_instant="true" label="Object Count After GC">
+      <value type="ULONG" field="gcId"  label="GC ID" relation="GC_ID" />
+      <value type="CLASS" field="class" label="Class" />
+      <value type="LONG" field="count" label="Count" />
+      <value type="BYTES64" field="totalSize" label="Total Size" />
+    </event>
+
     <event id="PromotionFailed" path="vm/gc/detailed/promotion_failed" label="Promotion Failed" is_instant="true"
            description="Promotion of an object failed">
       <value type="ULONG" field="gcId" label="GC ID" relation="GC_ID"/>