7190666: G1: assert(_unused == 0) failed: Inconsistency in PLAB stats
authorjohnc
Thu, 20 Sep 2012 09:52:56 -0700
changeset 13758 692e37683d34
parent 13757 8740ce357087
child 13760 e56b4dcced93
7190666: G1: assert(_unused == 0) failed: Inconsistency in PLAB stats Summary: Reset the fields in ParGCAllocBuffer, that are used for accumulating values for the ResizePLAB sensors in PLABStats, to zero after flushing the values to the PLABStats fields. Flush PLABStats values only when retiring the final allocation buffers prior to disposing of a G1ParScanThreadState object, rather than when retiring every allocation buffer. Reviewed-by: jwilhelm, jmasa, ysr
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp
hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Wed Sep 19 15:48:02 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Sep 20 09:52:56 2012 -0700
@@ -1851,9 +1851,7 @@
     if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
       G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose);
       add_to_alloc_buffer_waste(alloc_buf->words_remaining());
-      alloc_buf->flush_stats_and_retire(_g1h->stats_for_purpose(purpose),
-                                        false /* end_of_gc */,
-                                        false /* retain */);
+      alloc_buf->retire(false /* end_of_gc */, false /* retain */);
 
       HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size);
       if (buf == NULL) return NULL; // Let caller handle allocation failure.
--- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp	Wed Sep 19 15:48:02 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp	Thu Sep 20 09:52:56 2012 -0700
@@ -90,7 +90,14 @@
 void PLABStats::adjust_desired_plab_sz() {
   assert(ResizePLAB, "Not set");
   if (_allocated == 0) {
-    assert(_unused == 0, "Inconsistency in PLAB stats");
+    assert(_unused == 0,
+           err_msg("Inconsistency in PLAB stats: "
+                   "_allocated: "SIZE_FORMAT", "
+                   "_wasted: "SIZE_FORMAT", "
+                   "_unused: "SIZE_FORMAT", "
+                   "_used  : "SIZE_FORMAT,
+                   _allocated, _wasted, _unused, _used));
+
     _allocated = 1;
   }
   double wasted_frac    = (double)_unused/(double)_allocated;
--- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp	Wed Sep 19 15:48:02 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp	Thu Sep 20 09:52:56 2012 -0700
@@ -52,6 +52,10 @@
   static size_t FillerHeaderSize;
   static size_t AlignmentReserve;
 
+  // Flush the stats supporting ergonomic sizing of PLAB's
+  // Should not be called directly
+  void flush_stats(PLABStats* stats);
+
 public:
   // Initializes the buffer to be empty, but with the given "word_sz".
   // Must get initialized with "set_buf" for an allocation to succeed.
@@ -120,12 +124,22 @@
   }
 
   // Flush the stats supporting ergonomic sizing of PLAB's
-  void flush_stats(PLABStats* stats);
+  // and retire the current buffer.
   void flush_stats_and_retire(PLABStats* stats, bool end_of_gc, bool retain) {
     // We flush the stats first in order to get a reading of
     // unused space in the last buffer.
     if (ResizePLAB) {
       flush_stats(stats);
+
+      // Since we have flushed the stats we need to clear
+      // the _allocated and _wasted fields. Not doing so
+      // will artifically inflate the values in the stats
+      // to which we add them.
+      // The next time we flush these values, we will add
+      // what we have just flushed in addition to the size
+      // of the buffers allocated between now and then.
+      _allocated = 0;
+      _wasted = 0;
     }
     // Retire the last allocation buffer.
     retire(end_of_gc, retain);