8150390: Move rs length sampling data to the sampling thread
authormgerdin
Thu, 25 Feb 2016 11:20:03 +0100
changeset 36365 bcc9c9afda49
parent 36364 5971776598e5
child 36370 9333c14b078f
child 36371 fd81a4f0ea00
8150390: Move rs length sampling data to the sampling thread Reviewed-by: drwhite, jwilhelm
hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp
hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp
hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp
hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp
hotspot/src/share/vm/gc/g1/g1YoungRemSetSamplingThread.cpp
hotspot/src/share/vm/gc/g1/youngList.cpp
hotspot/src/share/vm/gc/g1/youngList.hpp
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Thu Feb 25 13:09:17 2016 -0500
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Thu Feb 25 11:20:03 2016 +0100
@@ -1400,7 +1400,6 @@
       JavaThread::dirty_card_queue_set().abandon_logs();
       assert(dirty_card_queue_set().completed_buffers_num() == 0, "DCQS should be empty");
 
-      _young_list->reset_sampled_info();
       // At this point there should be no regions in the
       // entire heap tagged as young.
       assert(check_young_list_empty(true /* check_heap */),
@@ -3390,8 +3389,6 @@
 
         clear_cset_fast_test();
 
-        _young_list->reset_sampled_info();
-
         // Don't check the whole heap at this point as the
         // GC alloc regions from this pause have been tagged
         // as survivors and moved on to the survivor list.
@@ -5188,8 +5185,8 @@
   bool success() { return _success; }
 };
 
-bool G1CollectedHeap::check_young_list_empty(bool check_heap, bool check_sample) {
-  bool ret = _young_list->check_list_empty(check_sample);
+bool G1CollectedHeap::check_young_list_empty(bool check_heap) {
+  bool ret = _young_list->check_list_empty();
 
   if (check_heap) {
     NoYoungRegionsClosure closure;
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Thu Feb 25 13:09:17 2016 -0500
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Thu Feb 25 11:20:03 2016 +0100
@@ -1333,8 +1333,7 @@
     return _young_list->check_list_well_formed();
   }
 
-  bool check_young_list_empty(bool check_heap,
-                              bool check_sample = true);
+  bool check_young_list_empty(bool check_heap);
 
   // *** Stuff related to concurrent marking.  It's not clear to me that so
   // many of these need to be public.
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Thu Feb 25 13:09:17 2016 -0500
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Thu Feb 25 11:20:03 2016 +0100
@@ -787,10 +787,9 @@
   return survivor_regions_evac_time;
 }
 
-void G1CollectorPolicy::revise_young_list_target_length_if_necessary() {
+void G1CollectorPolicy::revise_young_list_target_length_if_necessary(size_t rs_lengths) {
   guarantee( adaptive_young_list_length(), "should not call this otherwise" );
 
-  size_t rs_lengths = _g1->young_list()->sampled_rs_lengths();
   if (rs_lengths > _rs_lengths_prediction) {
     // add 10% to avoid having to recalculate often
     size_t rs_lengths_prediction = rs_lengths * 1100 / 1000;
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Thu Feb 25 13:09:17 2016 -0500
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Thu Feb 25 11:20:03 2016 +0100
@@ -471,7 +471,7 @@
   // Check the current value of the young list RSet lengths and
   // compare it against the last prediction. If the current value is
   // higher, recalculate the young list target length prediction.
-  void revise_young_list_target_length_if_necessary();
+  void revise_young_list_target_length_if_necessary(size_t rs_lengths);
 
   // This should be called after the heap is resized.
   void record_new_heap_size(uint new_number_of_regions);
--- a/hotspot/src/share/vm/gc/g1/g1YoungRemSetSamplingThread.cpp	Thu Feb 25 13:09:17 2016 -0500
+++ b/hotspot/src/share/vm/gc/g1/g1YoungRemSetSamplingThread.cpp	Thu Feb 25 11:20:03 2016 +0100
@@ -26,6 +26,8 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
 #include "gc/g1/g1YoungRemSetSamplingThread.hpp"
+#include "gc/g1/heapRegion.inline.hpp"
+#include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/g1/suspendibleThreadSet.hpp"
 #include "runtime/mutexLocker.hpp"
 
@@ -100,22 +102,35 @@
   G1CollectorPolicy* g1p = g1h->g1_policy();
   if (g1p->adaptive_young_list_length()) {
     int regions_visited = 0;
-    g1h->young_list()->rs_length_sampling_init();
-    while (g1h->young_list()->rs_length_sampling_more()) {
-      g1h->young_list()->rs_length_sampling_next();
+    HeapRegion* hr = g1h->young_list()->first_region();
+    size_t sampled_rs_lengths = 0;
+
+    while (hr != NULL) {
+      size_t rs_length = hr->rem_set()->occupied();
+      sampled_rs_lengths += rs_length;
+
+      // The current region may not yet have been added to the
+      // incremental collection set (it gets added when it is
+      // retired as the current allocation region).
+      if (hr->in_collection_set()) {
+        // Update the collection set policy information for this region
+        g1p->update_incremental_cset_info(hr, rs_length);
+      }
+
       ++regions_visited;
 
       // we try to yield every time we visit 10 regions
       if (regions_visited == 10) {
         if (sts.should_yield()) {
           sts.yield();
-          // we just abandon the iteration
-          break;
+          // A gc may have occurred and our sampling data is stale and further
+          // traversal of the young list is unsafe
+          return;
         }
         regions_visited = 0;
       }
+      hr = hr->get_next_young_region();
     }
-
-    g1p->revise_young_list_target_length_if_necessary();
+    g1p->revise_young_list_target_length_if_necessary(sampled_rs_lengths);
   }
 }
--- a/hotspot/src/share/vm/gc/g1/youngList.cpp	Thu Feb 25 13:09:17 2016 -0500
+++ b/hotspot/src/share/vm/gc/g1/youngList.cpp	Thu Feb 25 11:20:03 2016 +0100
@@ -33,9 +33,9 @@
 #include "utilities/ostream.hpp"
 
 YoungList::YoungList(G1CollectedHeap* g1h) :
-    _g1h(g1h), _head(NULL), _length(0), _last_sampled_rs_lengths(0),
+    _g1h(g1h), _head(NULL), _length(0),
     _survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0) {
-  guarantee(check_list_empty(false), "just making sure...");
+  guarantee(check_list_empty(), "just making sure...");
 }
 
 void YoungList::push_region(HeapRegion *hr) {
@@ -86,9 +86,7 @@
   _survivor_tail = NULL;
   _survivor_length = 0;
 
-  _last_sampled_rs_lengths = 0;
-
-  assert(check_list_empty(false), "just making sure...");
+  assert(check_list_empty(), "just making sure...");
 }
 
 bool YoungList::check_list_well_formed() {
@@ -119,17 +117,13 @@
   return ret;
 }
 
-bool YoungList::check_list_empty(bool check_sample) {
+bool YoungList::check_list_empty() {
   bool ret = true;
 
   if (_length != 0) {
     log_error(gc, verify)("### YOUNG LIST should have 0 length, not %u", _length);
     ret = false;
   }
-  if (check_sample && _last_sampled_rs_lengths != 0) {
-    log_error(gc, verify)("### YOUNG LIST has non-zero last sampled RS lengths");
-    ret = false;
-  }
   if (_head != NULL) {
     log_error(gc, verify)("### YOUNG LIST does not have a NULL head");
     ret = false;
@@ -142,38 +136,6 @@
 }
 
 void
-YoungList::rs_length_sampling_init() {
-  _sampled_rs_lengths = 0;
-  _curr               = _head;
-}
-
-bool
-YoungList::rs_length_sampling_more() {
-  return _curr != NULL;
-}
-
-void
-YoungList::rs_length_sampling_next() {
-  assert( _curr != NULL, "invariant" );
-  size_t rs_length = _curr->rem_set()->occupied();
-
-  _sampled_rs_lengths += rs_length;
-
-  // The current region may not yet have been added to the
-  // incremental collection set (it gets added when it is
-  // retired as the current allocation region).
-  if (_curr->in_collection_set()) {
-    // Update the collection set policy information for this region
-    _g1h->g1_policy()->update_incremental_cset_info(_curr, rs_length);
-  }
-
-  _curr = _curr->get_next_young_region();
-  if (_curr == NULL) {
-    _last_sampled_rs_lengths = _sampled_rs_lengths;
-  }
-}
-
-void
 YoungList::reset_auxilary_lists() {
   guarantee( is_empty(), "young list should be empty" );
   assert(check_list_well_formed(), "young list should be well formed");
--- a/hotspot/src/share/vm/gc/g1/youngList.hpp	Thu Feb 25 13:09:17 2016 -0500
+++ b/hotspot/src/share/vm/gc/g1/youngList.hpp	Thu Feb 25 11:20:03 2016 +0100
@@ -37,14 +37,9 @@
   HeapRegion* _survivor_head;
   HeapRegion* _survivor_tail;
 
-  HeapRegion* _curr;
-
   uint        _length;
   uint        _survivor_length;
 
-  size_t      _last_sampled_rs_lengths;
-  size_t      _sampled_rs_lengths;
-
   void         empty_list(HeapRegion* list);
 
 public:
@@ -72,15 +67,6 @@
     return (size_t) survivor_length() * HeapRegion::GrainBytes;
   }
 
-  void rs_length_sampling_init();
-  bool rs_length_sampling_more();
-  void rs_length_sampling_next();
-
-  void reset_sampled_info() {
-    _last_sampled_rs_lengths =   0;
-  }
-  size_t sampled_rs_lengths() { return _last_sampled_rs_lengths; }
-
   // for development purposes
   void reset_auxilary_lists();
   void clear() { _head = NULL; _length = 0; }
@@ -97,7 +83,7 @@
 
   // debugging
   bool          check_list_well_formed();
-  bool          check_list_empty(bool check_sample = true);
+  bool          check_list_empty();
   void          print();
 };