1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 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 #ifndef SHARE_GC_G1_G1REDIRTYCARDSQUEUE_HPP 26 #define SHARE_GC_G1_G1REDIRTYCARDSQUEUE_HPP 27 28 #include "gc/g1/g1BufferNodeList.hpp" 29 #include "gc/shared/ptrQueue.hpp" 30 #include "memory/allocation.hpp" 31 #include "memory/padded.hpp" 32 33 class G1CardTableEntryClosure; 34 class G1RedirtyCardsQueue; 35 class G1RedirtyCardsQueueSet; 36 37 // Provide G1RedirtyCardsQueue with a thread-local qset. It provides an 38 // uncontended staging area for completed buffers, to be flushed to the 39 // shared qset en masse. Using the "base from member" idiom so the local 40 // qset is constructed before being passed to the PtrQueue constructor. 41 class G1RedirtyCardsQueueBase { 42 friend class G1RedirtyCardsQueue; 43 friend class G1RedirtyCardsQueueSet; 44 45 class LocalQSet : public PtrQueueSet { 46 G1RedirtyCardsQueueSet* _shared_qset; 47 G1BufferNodeList _buffers; 48 49 public: 50 LocalQSet(G1RedirtyCardsQueueSet* shared_qset); 51 ~LocalQSet(); 52 53 // Add the buffer to the local list. 54 virtual void enqueue_completed_buffer(BufferNode* node); 55 56 // Transfer all completed buffers to the shared qset. 57 void flush(); 58 59 G1BufferNodeList take_all_completed_buffers(); 60 }; 61 62 G1RedirtyCardsQueueBase(G1RedirtyCardsQueueSet* shared_qset) : 63 _local_qset(shared_qset) {} 64 65 ~G1RedirtyCardsQueueBase() {} 66 67 LocalQSet _local_qset; 68 }; 69 70 // Worker-local queues of card table entries. 71 class G1RedirtyCardsQueue : private G1RedirtyCardsQueueBase, public PtrQueue { 72 protected: 73 virtual void handle_completed_buffer(); 74 75 public: 76 G1RedirtyCardsQueue(G1RedirtyCardsQueueSet* qset); 77 78 // Flushes the queue. 79 ~G1RedirtyCardsQueue(); 80 81 // Flushes all enqueued cards to qset. 82 void flush(); 83 }; 84 85 // Card table entries to be redirtied and the cards reprocessed later. 86 // Has two phases, collecting and processing. During the collecting 87 // phase buffers are added to the set. Once collecting is complete and 88 // processing starts, buffers can no longer be added. Taking all the 89 // collected (and processed) buffers reverts back to collecting, allowing 90 // the set to be reused for another round of redirtying. 91 class G1RedirtyCardsQueueSet : public PtrQueueSet { 92 DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0); 93 BufferNode::Stack _list; 94 DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(size_t)); 95 volatile size_t _entry_count; 96 DEFINE_PAD_MINUS_SIZE(3, DEFAULT_CACHE_LINE_SIZE, sizeof(BufferNode*)); 97 BufferNode* _tail; 98 DEBUG_ONLY(mutable bool _collecting;) 99 100 typedef G1RedirtyCardsQueueBase::LocalQSet LocalQSet; 101 102 void update_tail(BufferNode* node); 103 104 public: 105 G1RedirtyCardsQueueSet(BufferNode::Allocator* allocator); 106 ~G1RedirtyCardsQueueSet(); 107 108 void verify_empty() const NOT_DEBUG_RETURN; 109 110 // Collect buffers. These functions are thread-safe. 111 // precondition: Must not be concurrent with buffer processing. 112 virtual void enqueue_completed_buffer(BufferNode* node); 113 void merge_bufferlist(LocalQSet* src); 114 115 // Processing phase operations. 116 // precondition: Must not be concurrent with buffer collection. 117 BufferNode* all_completed_buffers() const; 118 G1BufferNodeList take_all_completed_buffers(); 119 }; 120 121 #endif // SHARE_GC_G1_G1REDIRTYCARDSQUEUE_HPP