1 /*
  2  * Copyright (c) 2001, 2024, 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_SHARED_SATBMARKQUEUE_HPP
 26 #define SHARE_GC_SHARED_SATBMARKQUEUE_HPP
 27 
 28 #include "gc/shared/ptrQueue.hpp"
 29 #include "memory/allocation.hpp"
 30 #include "memory/padded.hpp"
 31 #include "oops/oopsHierarchy.hpp"
 32 
 33 class Thread;
 34 class Monitor;
 35 class SATBMarkQueueSet;
 36 
 37 // Base class for processing the contents of a SATB buffer.
 38 class SATBBufferClosure : public StackObj {
 39 protected:
 40   ~SATBBufferClosure() { }
 41 
 42 public:
 43   // Process the SATB entries in the designated buffer range.
 44   virtual void do_buffer(void** buffer, size_t size) = 0;
 45 };
 46 
 47 // A PtrQueue whose elements are (possibly stale) pointers to object heads.
 48 class SATBMarkQueue: public PtrQueue {
 49   friend class VMStructs;
 50   friend class SATBMarkQueueSet;
 51 
 52 private:
 53   // Per-queue (so thread-local) cache of the SATBMarkQueueSet's
 54   // active state, to support inline barriers in compiled code.
 55   bool _active;
 56 
 57 public:
 58   SATBMarkQueue(SATBMarkQueueSet* qset);
 59 
 60   bool is_active() const { return _active; }
 61   void set_active(bool value) { _active = value; }
 62 
 63 #ifndef PRODUCT
 64   // Helpful for debugging
 65   void print(const char* name);
 66 #endif // PRODUCT
 67 
 68   // Compiler support.
 69   static ByteSize byte_offset_of_index() {
 70     return PtrQueue::byte_offset_of_index<SATBMarkQueue>();
 71   }
 72   using PtrQueue::byte_width_of_index;
 73 
 74   static ByteSize byte_offset_of_buf() {
 75     return PtrQueue::byte_offset_of_buf<SATBMarkQueue>();
 76   }
 77   using PtrQueue::byte_width_of_buf;
 78 
 79   static ByteSize byte_offset_of_active() {
 80     return byte_offset_of(SATBMarkQueue, _active);
 81   }
 82 
 83   static ByteSize byte_width_of_active() { return in_ByteSize(sizeof(bool)); }
 84 };
 85 
 86 class SATBMarkQueueSet: public PtrQueueSet {
 87 
 88   DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, 0);
 89   PaddedEnd<BufferNode::Stack> _list;
 90   volatile size_t _count_and_process_flag;
 91   // These are rarely (if ever) changed, so same cache line as count.
 92   size_t _process_completed_buffers_threshold;
 93   size_t _buffer_enqueue_threshold;
 94   // SATB is only active during marking.  Enqueuing is only done when active.
 95   bool _all_active;
 96   DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, 4 * sizeof(size_t));
 97 
 98   BufferNode* get_completed_buffer();
 99   void abandon_completed_buffers();
100 
101 #ifdef ASSERT
102   void dump_active_states(bool expected_active);
103   void verify_active_states(bool expected_active);
104 #endif // ASSERT
105 
106 protected:
107   SATBMarkQueueSet(BufferNode::Allocator* allocator);
108   ~SATBMarkQueueSet();
109 
110   void handle_zero_index(SATBMarkQueue& queue);
111 
112   // Return true if the queue's buffer should be enqueued, even if not full.
113   // The default method uses the buffer enqueue threshold.
114   bool should_enqueue_buffer(SATBMarkQueue& queue);
115 
116   template<typename Filter>
117   void apply_filter(Filter filter, SATBMarkQueue& queue);
118 
119 public:
120   virtual SATBMarkQueue& satb_queue_for_thread(Thread* const t) const = 0;
121 
122   bool is_active() const { return _all_active; }
123 
124   // Apply "set_active(active)" to all SATB queues in the set. It should be
125   // called only with the world stopped. The method will assert that the
126   // SATB queues of all threads it visits, as well as the SATB queue
127   // set itself, has an active value same as expected_active.
128   void set_active_all_threads(bool active, bool expected_active);
129 
130   void set_process_completed_buffers_threshold(size_t value);
131 
132   size_t buffer_enqueue_threshold() const { return _buffer_enqueue_threshold; }
133   void set_buffer_enqueue_threshold_percentage(uint value);
134 
135   // If there exists some completed buffer, pop and process it, and
136   // return true.  Otherwise return false.  Processing a buffer
137   // consists of applying the closure to the active range of the
138   // buffer; the leading entries may be excluded due to filtering.
139   bool apply_closure_to_completed_buffer(SATBBufferClosure* cl);
140 
141   void flush_queue(SATBMarkQueue& queue);
142 
143   // Add obj to queue.  This qset and the queue must be active.
144   void enqueue_known_active(SATBMarkQueue& queue, oop obj);
145   virtual void filter(SATBMarkQueue& queue) = 0;
146   virtual void enqueue_completed_buffer(BufferNode* node);
147 
148   // The number of buffers in the list.  Racy and not updated atomically
149   // with the set of completed buffers.
150   size_t completed_buffers_num() const {
151     return _count_and_process_flag >> 1;
152   }
153 
154   // Return true if completed buffers should be processed.
155   bool process_completed_buffers() const {
156     return (_count_and_process_flag & 1) != 0;
157   }
158 
159 #ifndef PRODUCT
160   // Helpful for debugging
161   void print_all(const char* msg);
162 #endif // PRODUCT
163 
164   // If a marking is being abandoned, reset any unprocessed log buffers.
165   void abandon_partial_marking();
166 };
167 
168 // Removes entries from queue's buffer that are no longer needed, as
169 // determined by filter. If e is a void* entry in queue's buffer,
170 // filter_out(e) must be a valid expression whose value is convertible
171 // to bool. Entries are removed (filtered out) if the result is true,
172 // retained if false.
173 template<typename Filter>
174 inline void SATBMarkQueueSet::apply_filter(Filter filter_out, SATBMarkQueue& queue) {
175   void** buf = queue.buffer();
176 
177   if (buf == nullptr) {
178     // Nothing to do, and avoid pointer arithmetic on nullptr below.
179     return;
180   }
181 
182   // Two-fingered compaction toward the end.
183   void** src = buf + queue.index();
184   void** dst = buf + queue.current_capacity();
185   assert(src <= dst, "invariant");
186   for ( ; src < dst; ++src) {
187     // Search low to high for an entry to keep.
188     void* entry = *src;
189     if (!filter_out(entry)) {
190       // Found keeper.  Search high to low for an entry to discard.
191       while (src < --dst) {
192         if (filter_out(*dst)) {
193           *dst = entry;         // Replace discard with keeper.
194           break;
195         }
196       }
197       // If discard search failed (src == dst), the outer loop will also end.
198     }
199   }
200   // dst points to the lowest retained entry, or the end of the buffer
201   // if all the entries were filtered out.
202   queue.set_index(dst - buf);
203 }
204 
205 #endif // SHARE_GC_SHARED_SATBMARKQUEUE_HPP