8214278: Cleanup process_completed_threshold and related state
authorkbarrett
Wed, 28 Nov 2018 16:05:48 -0500
changeset 52726 9cfa2e273b77
parent 52725 c470f977ade8
child 52727 396dfb0e8ba5
8214278: Cleanup process_completed_threshold and related state Summary: Change types, normalize names, remove special values. Reviewed-by: tschatzl, sjohanss
src/hotspot/share/gc/g1/dirtyCardQueue.cpp
src/hotspot/share/gc/g1/dirtyCardQueue.hpp
src/hotspot/share/gc/g1/g1CollectedHeap.cpp
src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
src/hotspot/share/gc/g1/g1SATBMarkQueueSet.cpp
src/hotspot/share/gc/g1/g1SATBMarkQueueSet.hpp
src/hotspot/share/gc/shared/ptrQueue.cpp
src/hotspot/share/gc/shared/ptrQueue.hpp
src/hotspot/share/gc/shared/satbMarkQueue.cpp
src/hotspot/share/gc/shared/satbMarkQueue.hpp
--- a/src/hotspot/share/gc/g1/dirtyCardQueue.cpp	Wed Nov 28 16:04:36 2018 -0500
+++ b/src/hotspot/share/gc/g1/dirtyCardQueue.cpp	Wed Nov 28 16:05:48 2018 -0500
@@ -31,6 +31,7 @@
 #include "gc/shared/suspendibleThreadSet.hpp"
 #include "gc/shared/workgroup.hpp"
 #include "runtime/atomic.hpp"
+#include "runtime/flags/flagSetting.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.inline.hpp"
@@ -148,14 +149,9 @@
 
 void DirtyCardQueueSet::initialize(Monitor* cbl_mon,
                                    BufferNode::Allocator* allocator,
-                                   int process_completed_threshold,
-                                   int max_completed_queue,
                                    Mutex* lock,
                                    bool init_free_ids) {
-  PtrQueueSet::initialize(cbl_mon,
-                          allocator,
-                          process_completed_threshold,
-                          max_completed_queue);
+  PtrQueueSet::initialize(cbl_mon, allocator);
   _shared_dirty_card_queue.set_lock(lock);
   if (init_free_ids) {
     _free_ids = new FreeIdSet(num_par_ids(), _cbl_mon);
@@ -334,13 +330,11 @@
   // Iterate over all the threads, if we find a partial log add it to
   // the global list of logs.  Temporarily turn off the limit on the number
   // of outstanding buffers.
-  int save_max_completed_queue = _max_completed_queue;
-  _max_completed_queue = max_jint;
   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
+  SizeTFlagSetting local_max(_max_completed_buffers,
+                             MaxCompletedBuffersUnlimited);
   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     concatenate_log(G1ThreadLocalData::dirty_card_queue(t));
   }
   concatenate_log(_shared_dirty_card_queue);
-  // Restore the completed buffer queue limit.
-  _max_completed_queue = save_max_completed_queue;
 }
--- a/src/hotspot/share/gc/g1/dirtyCardQueue.hpp	Wed Nov 28 16:04:36 2018 -0500
+++ b/src/hotspot/share/gc/g1/dirtyCardQueue.hpp	Wed Nov 28 16:05:48 2018 -0500
@@ -119,8 +119,6 @@
 
   void initialize(Monitor* cbl_mon,
                   BufferNode::Allocator* allocator,
-                  int process_completed_threshold,
-                  int max_completed_queue,
                   Mutex* lock,
                   bool init_free_ids = false);
 
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Wed Nov 28 16:04:36 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Wed Nov 28 16:05:48 2018 -0500
@@ -1659,19 +1659,15 @@
                                                  G1SATBBufferEnqueueingThresholdPercent,
                                                  Shared_SATB_Q_lock);
 
-  // process_completed_threshold and max_completed_queue are updated
+  // process_completed_buffers_threshold and max_completed_buffers are updated
   // later, based on the concurrent refinement object.
   G1BarrierSet::dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
                                                   &bs->dirty_card_queue_buffer_allocator(),
-                                                  -1, // temp. never trigger
-                                                  -1, // temp. no limit
                                                   Shared_DirtyCardQ_lock,
                                                   true); // init_free_ids
 
   dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
                                     &bs->dirty_card_queue_buffer_allocator(),
-                                    -1, // never trigger processing
-                                    -1, // no limit on length
                                     Shared_DirtyCardQ_lock);
 
   // Create the hot card cache.
@@ -1782,8 +1778,8 @@
 
   {
     DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
-    dcqs.set_process_completed_threshold((int)concurrent_refine()->yellow_zone());
-    dcqs.set_max_completed_queue((int)concurrent_refine()->red_zone());
+    dcqs.set_process_completed_buffers_threshold(concurrent_refine()->yellow_zone());
+    dcqs.set_max_completed_buffers(concurrent_refine()->red_zone());
   }
 
   // Here we allocate the dummy HeapRegion that is required by the
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp	Wed Nov 28 16:04:36 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp	Wed Nov 28 16:05:48 2018 -0500
@@ -144,7 +144,7 @@
 STATIC_ASSERT(sizeof(LP64_ONLY(jint) NOT_LP64(jshort)) <= (sizeof(size_t)/2));
 const size_t max_yellow_zone = LP64_ONLY(max_jint) NOT_LP64(max_jshort);
 const size_t max_green_zone = max_yellow_zone / 2;
-const size_t max_red_zone = INT_MAX; // For dcqs.set_max_completed_queue.
+const size_t max_red_zone = INT_MAX; // For dcqs.set_max_completed_buffers.
 STATIC_ASSERT(max_yellow_zone <= max_red_zone);
 
 // Range check assertions for green zone values.
@@ -386,21 +386,22 @@
     // Change the barrier params
     if (max_num_threads() == 0) {
       // Disable dcqs notification when there are no threads to notify.
-      dcqs.set_process_completed_threshold(INT_MAX);
+      dcqs.set_process_completed_buffers_threshold(DirtyCardQueueSet::ProcessCompletedBuffersThresholdNever);
     } else {
       // Worker 0 is the primary; wakeup is via dcqs notification.
       STATIC_ASSERT(max_yellow_zone <= INT_MAX);
       size_t activate = activation_threshold(0);
-      dcqs.set_process_completed_threshold((int)activate);
+      dcqs.set_process_completed_buffers_threshold(activate);
     }
-    dcqs.set_max_completed_queue((int)red_zone());
+    dcqs.set_max_completed_buffers(red_zone());
   }
 
   size_t curr_queue_size = dcqs.completed_buffers_num();
-  if (curr_queue_size >= yellow_zone()) {
-    dcqs.set_completed_queue_padding(curr_queue_size);
+  if ((dcqs.max_completed_buffers() > 0) &&
+      (curr_queue_size >= yellow_zone())) {
+    dcqs.set_completed_buffers_padding(curr_queue_size);
   } else {
-    dcqs.set_completed_queue_padding(0);
+    dcqs.set_completed_buffers_padding(0);
   }
   dcqs.notify_if_necessary();
 }
@@ -433,8 +434,8 @@
   // that means that the transition period after the evacuation pause has ended.
   // Since the value written to the DCQS is the same for all threads, there is no
   // need to synchronize.
-  if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= yellow_zone()) {
-    dcqs.set_completed_queue_padding(0);
+  if (dcqs.completed_buffers_padding() > 0 && curr_buffer_num <= yellow_zone()) {
+    dcqs.set_completed_buffers_padding(0);
   }
 
   maybe_activate_more_threads(worker_id, curr_buffer_num);
--- a/src/hotspot/share/gc/g1/g1SATBMarkQueueSet.cpp	Wed Nov 28 16:04:36 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1SATBMarkQueueSet.cpp	Wed Nov 28 16:05:48 2018 -0500
@@ -37,12 +37,12 @@
 void G1SATBMarkQueueSet::initialize(G1CollectedHeap* g1h,
                                     Monitor* cbl_mon,
                                     BufferNode::Allocator* allocator,
-                                    int process_completed_threshold,
+                                    size_t process_completed_buffers_threshold,
                                     uint buffer_enqueue_threshold_percentage,
                                     Mutex* lock) {
   SATBMarkQueueSet::initialize(cbl_mon,
                                allocator,
-                               process_completed_threshold,
+                               process_completed_buffers_threshold,
                                buffer_enqueue_threshold_percentage,
                                lock);
   _g1h = g1h;
--- a/src/hotspot/share/gc/g1/g1SATBMarkQueueSet.hpp	Wed Nov 28 16:04:36 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1SATBMarkQueueSet.hpp	Wed Nov 28 16:05:48 2018 -0500
@@ -39,7 +39,7 @@
   void initialize(G1CollectedHeap* g1h,
                   Monitor* cbl_mon,
                   BufferNode::Allocator* allocator,
-                  int process_completed_threshold,
+                  size_t process_completed_buffers_threshold,
                   uint buffer_enqueue_threshold_percentage,
                   Mutex* lock);
 
--- a/src/hotspot/share/gc/shared/ptrQueue.cpp	Wed Nov 28 16:04:36 2018 -0500
+++ b/src/hotspot/share/gc/shared/ptrQueue.cpp	Wed Nov 28 16:05:48 2018 -0500
@@ -164,12 +164,12 @@
   _completed_buffers_head(NULL),
   _completed_buffers_tail(NULL),
   _n_completed_buffers(0),
-  _process_completed_threshold(0),
+  _process_completed_buffers_threshold(ProcessCompletedBuffersThresholdNever),
   _process_completed(false),
   _all_active(false),
   _notify_when_complete(notify_when_complete),
-  _max_completed_queue(0),
-  _completed_queue_padding(0)
+  _max_completed_buffers(MaxCompletedBuffersUnlimited),
+  _completed_buffers_padding(0)
 {}
 
 PtrQueueSet::~PtrQueueSet() {
@@ -179,12 +179,7 @@
 }
 
 void PtrQueueSet::initialize(Monitor* cbl_mon,
-                             BufferNode::Allocator* allocator,
-                             int process_completed_threshold,
-                             int max_completed_queue) {
-  _max_completed_queue = max_completed_queue;
-  _process_completed_threshold = process_completed_threshold;
-  _completed_queue_padding = 0;
+                             BufferNode::Allocator* allocator) {
   assert(cbl_mon != NULL && allocator != NULL, "Init order issue?");
   _cbl_mon = cbl_mon;
   _allocator = allocator;
@@ -238,13 +233,14 @@
 
 bool PtrQueueSet::process_or_enqueue_complete_buffer(BufferNode* node) {
   if (Thread::current()->is_Java_thread()) {
-    // We don't lock. It is fine to be epsilon-precise here.
-    if (_max_completed_queue == 0 ||
-        (_max_completed_queue > 0 &&
-          _n_completed_buffers >= _max_completed_queue + _completed_queue_padding)) {
-      bool b = mut_process_buffer(node);
-      if (b) {
-        // True here means that the buffer hasn't been deallocated and the caller may reuse it.
+    // If the number of buffers exceeds the limit, make this Java
+    // thread do the processing itself.  We don't lock to access
+    // buffer count or padding; it is fine to be imprecise here.  The
+    // add of padding could overflow, which is treated as unlimited.
+    size_t limit = _max_completed_buffers + _completed_buffers_padding;
+    if ((_n_completed_buffers > limit) && (limit >= _max_completed_buffers)) {
+      if (mut_process_buffer(node)) {
+        // Successfully processed; return true to allow buffer reuse.
         return true;
       }
     }
@@ -267,8 +263,8 @@
   }
   _n_completed_buffers++;
 
-  if (!_process_completed && _process_completed_threshold >= 0 &&
-      _n_completed_buffers >= (size_t)_process_completed_threshold) {
+  if (!_process_completed &&
+      (_n_completed_buffers > _process_completed_buffers_threshold)) {
     _process_completed = true;
     if (_notify_when_complete) {
       _cbl_mon->notify();
@@ -327,8 +323,7 @@
 
 void PtrQueueSet::notify_if_necessary() {
   MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
-  assert(_process_completed_threshold >= 0, "_process_completed_threshold is negative");
-  if (_n_completed_buffers >= (size_t)_process_completed_threshold || _max_completed_queue == 0) {
+  if (_n_completed_buffers > _process_completed_buffers_threshold) {
     _process_completed = true;
     if (_notify_when_complete)
       _cbl_mon->notify();
--- a/src/hotspot/share/gc/shared/ptrQueue.hpp	Wed Nov 28 16:04:36 2018 -0500
+++ b/src/hotspot/share/gc/shared/ptrQueue.hpp	Wed Nov 28 16:05:48 2018 -0500
@@ -284,7 +284,7 @@
   BufferNode* _completed_buffers_head;
   BufferNode* _completed_buffers_tail;
   size_t _n_completed_buffers;
-  int _process_completed_threshold;
+  size_t _process_completed_buffers_threshold;
   volatile bool _process_completed;
 
   bool _all_active;
@@ -293,9 +293,9 @@
   bool _notify_when_complete;
 
   // Maximum number of elements allowed on completed queue: after that,
-  // enqueuer does the work itself.  Zero indicates no maximum.
-  int _max_completed_queue;
-  size_t _completed_queue_padding;
+  // enqueuer does the work itself.
+  size_t _max_completed_buffers;
+  size_t _completed_buffers_padding;
 
   size_t completed_buffers_list_length();
   void assert_completed_buffer_list_len_correct_locked();
@@ -316,10 +316,7 @@
 
   // Because of init-order concerns, we can't pass these as constructor
   // arguments.
-  void initialize(Monitor* cbl_mon,
-                  BufferNode::Allocator* allocator,
-                  int process_completed_threshold,
-                  int max_completed_queue);
+  void initialize(Monitor* cbl_mon, BufferNode::Allocator* allocator);
 
 public:
 
@@ -350,18 +347,34 @@
   }
 
   // Get/Set the number of completed buffers that triggers log processing.
-  void set_process_completed_threshold(int sz) { _process_completed_threshold = sz; }
-  int process_completed_threshold() const { return _process_completed_threshold; }
+  // Log processing should be done when the number of buffers exceeds the
+  // threshold.
+  void set_process_completed_buffers_threshold(size_t sz) {
+    _process_completed_buffers_threshold = sz;
+  }
+  size_t process_completed_buffers_threshold() const {
+    return _process_completed_buffers_threshold;
+  }
+  static const size_t ProcessCompletedBuffersThresholdNever = ~size_t(0);
 
-  size_t completed_buffers_num() { return _n_completed_buffers; }
+  size_t completed_buffers_num() const { return _n_completed_buffers; }
 
   void merge_bufferlists(PtrQueueSet* src);
 
-  void set_max_completed_queue(int m) { _max_completed_queue = m; }
-  int max_completed_queue() { return _max_completed_queue; }
+  void set_max_completed_buffers(size_t m) {
+    _max_completed_buffers = m;
+  }
+  size_t max_completed_buffers() const {
+    return _max_completed_buffers;
+  }
+  static const size_t MaxCompletedBuffersUnlimited = ~size_t(0);
 
-  void set_completed_queue_padding(size_t padding) { _completed_queue_padding = padding; }
-  size_t completed_queue_padding() { return _completed_queue_padding; }
+  void set_completed_buffers_padding(size_t padding) {
+    _completed_buffers_padding = padding;
+  }
+  size_t completed_buffers_padding() const {
+    return _completed_buffers_padding;
+  }
 
   // Notify the consumer if the number of buffers crossed the threshold
   void notify_if_necessary();
--- a/src/hotspot/share/gc/shared/satbMarkQueue.cpp	Wed Nov 28 16:04:36 2018 -0500
+++ b/src/hotspot/share/gc/shared/satbMarkQueue.cpp	Wed Nov 28 16:05:48 2018 -0500
@@ -113,10 +113,11 @@
 
 void SATBMarkQueueSet::initialize(Monitor* cbl_mon,
                                   BufferNode::Allocator* allocator,
-                                  int process_completed_threshold,
+                                  size_t process_completed_buffers_threshold,
                                   uint buffer_enqueue_threshold_percentage,
                                   Mutex* lock) {
-  PtrQueueSet::initialize(cbl_mon, allocator, process_completed_threshold, -1);
+  PtrQueueSet::initialize(cbl_mon, allocator);
+  set_process_completed_buffers_threshold(process_completed_buffers_threshold);
   _shared_satb_queue.set_lock(lock);
   assert(buffer_size() != 0, "buffer size not initialized");
   // Minimum threshold of 1 ensures enqueuing of completely full buffers.
--- a/src/hotspot/share/gc/shared/satbMarkQueue.hpp	Wed Nov 28 16:04:36 2018 -0500
+++ b/src/hotspot/share/gc/shared/satbMarkQueue.hpp	Wed Nov 28 16:05:48 2018 -0500
@@ -110,7 +110,7 @@
 
   void initialize(Monitor* cbl_mon,
                   BufferNode::Allocator* allocator,
-                  int process_completed_threshold,
+                  size_t process_completed_buffers_threshold,
                   uint buffer_enqueue_threshold_percentage,
                   Mutex* lock);