< prev index next >

src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp

Print this page
rev 56065 : [mq]: node_list


  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc/g1/g1RedirtyCardsQueue.hpp"
  27 #include "runtime/atomic.hpp"
  28 #include "utilities/debug.hpp"
  29 #include "utilities/macros.hpp"
  30 
  31 // G1RedirtyCardsBufferList
  32 
  33 G1RedirtyCardsBufferList::G1RedirtyCardsBufferList() :
  34   _head(NULL), _tail(NULL), _entry_count(0) {}
  35 
  36 G1RedirtyCardsBufferList::G1RedirtyCardsBufferList(BufferNode* head,
  37                                                    BufferNode* tail,
  38                                                    size_t entry_count) :
  39   _head(head), _tail(tail), _entry_count(entry_count)
  40 {
  41   assert((_head == NULL) == (_tail == NULL), "invariant");
  42   assert((_head == NULL) == (_entry_count == 0), "invariant");
  43 }
  44 
  45 // G1RedirtyCardsQueueBase::LocalQSet
  46 
  47 G1RedirtyCardsQueueBase::LocalQSet::LocalQSet(G1RedirtyCardsQueueSet* shared_qset) :
  48   PtrQueueSet(),
  49   _shared_qset(shared_qset),
  50   _buffers()
  51 {
  52   PtrQueueSet::initialize(_shared_qset->allocator());
  53 }
  54 
  55 G1RedirtyCardsQueueBase::LocalQSet::~LocalQSet() {
  56   assert(_buffers._head == NULL, "unflushed qset");
  57   assert(_buffers._tail == NULL, "invariant");
  58   assert(_buffers._entry_count == 0, "invariant");
  59 }
  60 
  61 void G1RedirtyCardsQueueBase::LocalQSet::enqueue_completed_buffer(BufferNode* node) {
  62   _buffers._entry_count += buffer_size() - node->index();
  63   node->set_next(_buffers._head);
  64   _buffers._head = node;
  65   if (_buffers._tail == NULL) {
  66     _buffers._tail = node;
  67   }
  68 }
  69 
  70 G1RedirtyCardsBufferList G1RedirtyCardsQueueBase::LocalQSet::take_all_completed_buffers() {
  71   G1RedirtyCardsBufferList result = _buffers;
  72   _buffers = G1RedirtyCardsBufferList();
  73   return result;
  74 }
  75 
  76 void G1RedirtyCardsQueueBase::LocalQSet::flush() {
  77   _shared_qset->merge_bufferlist(this);
  78 }
  79 
  80 // G1RedirtyCardsQueue
  81 
  82 G1RedirtyCardsQueue::G1RedirtyCardsQueue(G1RedirtyCardsQueueSet* qset) :
  83   G1RedirtyCardsQueueBase(qset), // Init _local_qset before passing to PtrQueue.
  84   PtrQueue(&_local_qset, true /* active (always) */)
  85 {}
  86 
  87 G1RedirtyCardsQueue::~G1RedirtyCardsQueue() {
  88   flush();
  89 }
  90 
  91 void G1RedirtyCardsQueue::handle_completed_buffer() {
  92   enqueue_completed_buffer();


 109   initialize(allocator);
 110 }
 111 
 112 G1RedirtyCardsQueueSet::~G1RedirtyCardsQueueSet() {
 113   verify_empty();
 114 }
 115 
 116 #ifdef ASSERT
 117 void G1RedirtyCardsQueueSet::verify_empty() const {
 118   assert(_list.empty(), "precondition");
 119   assert(_tail == NULL, "invariant");
 120   assert(_entry_count == 0, "invariant");
 121 }
 122 #endif // ASSERT
 123 
 124 BufferNode* G1RedirtyCardsQueueSet::all_completed_buffers() const {
 125   DEBUG_ONLY(_collecting = false;)
 126   return _list.top();
 127 }
 128 
 129 G1RedirtyCardsBufferList G1RedirtyCardsQueueSet::take_all_completed_buffers() {
 130   DEBUG_ONLY(_collecting = false;)
 131   G1RedirtyCardsBufferList result(_list.pop_all(), _tail, _entry_count);
 132   _tail = NULL;
 133   _entry_count = 0;
 134   DEBUG_ONLY(_collecting = true;)
 135   return result;
 136 }
 137 
 138 void G1RedirtyCardsQueueSet::update_tail(BufferNode* node) {
 139   // Node is the tail of a (possibly single element) list just prepended to
 140   // _list.  If, after that prepend, node's follower is NULL, then node is
 141   // also the tail of _list, so record it as such.
 142   if (node->next() == NULL) {
 143     assert(_tail == NULL, "invariant");
 144     _tail = node;
 145   }
 146 }
 147 
 148 void G1RedirtyCardsQueueSet::enqueue_completed_buffer(BufferNode* node) {
 149   assert(_collecting, "precondition");
 150   Atomic::add(buffer_size() - node->index(), &_entry_count);
 151   _list.push(*node);
 152   update_tail(node);
 153 }
 154 
 155 void G1RedirtyCardsQueueSet::merge_bufferlist(LocalQSet* src) {
 156   assert(_collecting, "precondition");
 157   const G1RedirtyCardsBufferList from = src->take_all_completed_buffers();
 158   if (from._head != NULL) {
 159     assert(from._tail != NULL, "invariant");
 160     Atomic::add(from._entry_count, &_entry_count);
 161     _list.prepend(*from._head, *from._tail);
 162     update_tail(from._tail);
 163   }
 164 }


  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc/g1/g1RedirtyCardsQueue.hpp"
  27 #include "runtime/atomic.hpp"
  28 #include "utilities/debug.hpp"
  29 #include "utilities/macros.hpp"
  30 














  31 // G1RedirtyCardsQueueBase::LocalQSet
  32 
  33 G1RedirtyCardsQueueBase::LocalQSet::LocalQSet(G1RedirtyCardsQueueSet* shared_qset) :
  34   PtrQueueSet(),
  35   _shared_qset(shared_qset),
  36   _buffers()
  37 {
  38   PtrQueueSet::initialize(_shared_qset->allocator());
  39 }
  40 
  41 G1RedirtyCardsQueueBase::LocalQSet::~LocalQSet() {
  42   assert(_buffers._head == NULL, "unflushed qset");
  43   assert(_buffers._tail == NULL, "invariant");
  44   assert(_buffers._entry_count == 0, "invariant");
  45 }
  46 
  47 void G1RedirtyCardsQueueBase::LocalQSet::enqueue_completed_buffer(BufferNode* node) {
  48   _buffers._entry_count += buffer_size() - node->index();
  49   node->set_next(_buffers._head);
  50   _buffers._head = node;
  51   if (_buffers._tail == NULL) {
  52     _buffers._tail = node;
  53   }
  54 }
  55 
  56 G1BufferNodeList G1RedirtyCardsQueueBase::LocalQSet::take_all_completed_buffers() {
  57   G1BufferNodeList result = _buffers;
  58   _buffers = G1BufferNodeList();
  59   return result;
  60 }
  61 
  62 void G1RedirtyCardsQueueBase::LocalQSet::flush() {
  63   _shared_qset->merge_bufferlist(this);
  64 }
  65 
  66 // G1RedirtyCardsQueue
  67 
  68 G1RedirtyCardsQueue::G1RedirtyCardsQueue(G1RedirtyCardsQueueSet* qset) :
  69   G1RedirtyCardsQueueBase(qset), // Init _local_qset before passing to PtrQueue.
  70   PtrQueue(&_local_qset, true /* active (always) */)
  71 {}
  72 
  73 G1RedirtyCardsQueue::~G1RedirtyCardsQueue() {
  74   flush();
  75 }
  76 
  77 void G1RedirtyCardsQueue::handle_completed_buffer() {
  78   enqueue_completed_buffer();


  95   initialize(allocator);
  96 }
  97 
  98 G1RedirtyCardsQueueSet::~G1RedirtyCardsQueueSet() {
  99   verify_empty();
 100 }
 101 
 102 #ifdef ASSERT
 103 void G1RedirtyCardsQueueSet::verify_empty() const {
 104   assert(_list.empty(), "precondition");
 105   assert(_tail == NULL, "invariant");
 106   assert(_entry_count == 0, "invariant");
 107 }
 108 #endif // ASSERT
 109 
 110 BufferNode* G1RedirtyCardsQueueSet::all_completed_buffers() const {
 111   DEBUG_ONLY(_collecting = false;)
 112   return _list.top();
 113 }
 114 
 115 G1BufferNodeList G1RedirtyCardsQueueSet::take_all_completed_buffers() {
 116   DEBUG_ONLY(_collecting = false;)
 117   G1BufferNodeList result(_list.pop_all(), _tail, _entry_count);
 118   _tail = NULL;
 119   _entry_count = 0;
 120   DEBUG_ONLY(_collecting = true;)
 121   return result;
 122 }
 123 
 124 void G1RedirtyCardsQueueSet::update_tail(BufferNode* node) {
 125   // Node is the tail of a (possibly single element) list just prepended to
 126   // _list.  If, after that prepend, node's follower is NULL, then node is
 127   // also the tail of _list, so record it as such.
 128   if (node->next() == NULL) {
 129     assert(_tail == NULL, "invariant");
 130     _tail = node;
 131   }
 132 }
 133 
 134 void G1RedirtyCardsQueueSet::enqueue_completed_buffer(BufferNode* node) {
 135   assert(_collecting, "precondition");
 136   Atomic::add(buffer_size() - node->index(), &_entry_count);
 137   _list.push(*node);
 138   update_tail(node);
 139 }
 140 
 141 void G1RedirtyCardsQueueSet::merge_bufferlist(LocalQSet* src) {
 142   assert(_collecting, "precondition");
 143   const G1BufferNodeList from = src->take_all_completed_buffers();
 144   if (from._head != NULL) {
 145     assert(from._tail != NULL, "invariant");
 146     Atomic::add(from._entry_count, &_entry_count);
 147     _list.prepend(*from._head, *from._tail);
 148     update_tail(from._tail);
 149   }
 150 }
< prev index next >