74 using PtrQueue::byte_width_of_buf; |
74 using PtrQueue::byte_width_of_buf; |
75 |
75 |
76 }; |
76 }; |
77 |
77 |
78 class G1DirtyCardQueueSet: public PtrQueueSet { |
78 class G1DirtyCardQueueSet: public PtrQueueSet { |
|
79 Monitor* _cbl_mon; // Protects the fields below. |
|
80 BufferNode* _completed_buffers_head; |
|
81 BufferNode* _completed_buffers_tail; |
|
82 volatile size_t _n_completed_buffers; |
|
83 |
|
84 size_t _process_completed_buffers_threshold; |
|
85 volatile bool _process_completed_buffers; |
|
86 |
|
87 // If true, notify_all on _cbl_mon when the threshold is reached. |
|
88 bool _notify_when_complete; |
|
89 |
|
90 void assert_completed_buffers_list_len_correct_locked() NOT_DEBUG_RETURN; |
|
91 |
|
92 void abandon_completed_buffers(); |
|
93 |
79 // Apply the closure to the elements of "node" from it's index to |
94 // Apply the closure to the elements of "node" from it's index to |
80 // buffer_size. If all closure applications return true, then |
95 // buffer_size. If all closure applications return true, then |
81 // returns true. Stops processing after the first closure |
96 // returns true. Stops processing after the first closure |
82 // application that returns false, and returns false from this |
97 // application that returns false, and returns false from this |
83 // function. If "consume" is true, the node's index is updated to |
98 // function. If "consume" is true, the node's index is updated to |
109 |
124 |
110 // If the queue contains more buffers than configured here, the |
125 // If the queue contains more buffers than configured here, the |
111 // mutator must start doing some of the concurrent refinement work, |
126 // mutator must start doing some of the concurrent refinement work, |
112 size_t _max_completed_buffers; |
127 size_t _max_completed_buffers; |
113 size_t _completed_buffers_padding; |
128 size_t _completed_buffers_padding; |
114 static const size_t MaxCompletedBuffersUnlimited = ~size_t(0); |
129 static const size_t MaxCompletedBuffersUnlimited = SIZE_MAX; |
115 |
130 |
116 G1FreeIdSet* _free_ids; |
131 G1FreeIdSet* _free_ids; |
117 |
132 |
118 // The number of completed buffers processed by mutator and rs thread, |
133 // The number of completed buffers processed by mutator and rs thread, |
119 // respectively. |
134 // respectively. |
140 // Either process the entire buffer and return true, or enqueue the |
155 // Either process the entire buffer and return true, or enqueue the |
141 // buffer and return false. If the buffer is completely processed, |
156 // buffer and return false. If the buffer is completely processed, |
142 // it can be reused in place. |
157 // it can be reused in place. |
143 bool process_or_enqueue_completed_buffer(BufferNode* node); |
158 bool process_or_enqueue_completed_buffer(BufferNode* node); |
144 |
159 |
|
160 virtual void enqueue_completed_buffer(BufferNode* node); |
|
161 |
|
162 // If the number of completed buffers is > stop_at, then remove and |
|
163 // return a completed buffer from the list. Otherwise, return NULL. |
|
164 BufferNode* get_completed_buffer(size_t stop_at = 0); |
|
165 |
|
166 // The number of buffers in the list. Racy... |
|
167 size_t completed_buffers_num() const { return _n_completed_buffers; } |
|
168 |
|
169 bool process_completed_buffers() { return _process_completed_buffers; } |
|
170 void set_process_completed_buffers(bool x) { _process_completed_buffers = x; } |
|
171 |
|
172 // Get/Set the number of completed buffers that triggers log processing. |
|
173 // Log processing should be done when the number of buffers exceeds the |
|
174 // threshold. |
|
175 void set_process_completed_buffers_threshold(size_t sz) { |
|
176 _process_completed_buffers_threshold = sz; |
|
177 } |
|
178 size_t process_completed_buffers_threshold() const { |
|
179 return _process_completed_buffers_threshold; |
|
180 } |
|
181 static const size_t ProcessCompletedBuffersThresholdNever = SIZE_MAX; |
|
182 |
|
183 // Notify the consumer if the number of buffers crossed the threshold |
|
184 void notify_if_necessary(); |
|
185 |
|
186 void merge_bufferlists(G1DirtyCardQueueSet* src); |
|
187 |
145 // Apply G1RefineCardConcurrentlyClosure to completed buffers until there are stop_at |
188 // Apply G1RefineCardConcurrentlyClosure to completed buffers until there are stop_at |
146 // completed buffers remaining. |
189 // completed buffers remaining. |
147 bool refine_completed_buffer_concurrently(uint worker_i, size_t stop_at); |
190 bool refine_completed_buffer_concurrently(uint worker_i, size_t stop_at); |
148 |
191 |
149 // Apply the given closure to all completed buffers. The given closure's do_card_ptr |
192 // Apply the given closure to all completed buffers. The given closure's do_card_ptr |
150 // must never return false. Must only be called during GC. |
193 // must never return false. Must only be called during GC. |
151 bool apply_closure_during_gc(G1CardTableEntryClosure* cl, uint worker_i); |
194 bool apply_closure_during_gc(G1CardTableEntryClosure* cl, uint worker_i); |
152 |
195 |
153 void reset_for_par_iteration() { _cur_par_buffer_node = completed_buffers_head(); } |
196 void reset_for_par_iteration() { _cur_par_buffer_node = _completed_buffers_head; } |
154 // Applies the current closure to all completed buffers, non-consumptively. |
197 // Applies the current closure to all completed buffers, non-consumptively. |
155 // Can be used in parallel, all callers using the iteration state initialized |
198 // Can be used in parallel, all callers using the iteration state initialized |
156 // by reset_for_par_iteration. |
199 // by reset_for_par_iteration. |
157 void par_apply_closure_to_all_completed_buffers(G1CardTableEntryClosure* cl); |
200 void par_apply_closure_to_all_completed_buffers(G1CardTableEntryClosure* cl); |
158 |
201 |
159 // If a full collection is happening, reset partial logs, and ignore |
202 // If a full collection is happening, reset partial logs, and release |
160 // completed ones: the full collection will make them all irrelevant. |
203 // completed ones: the full collection will make them all irrelevant. |
161 void abandon_logs(); |
204 void abandon_logs(); |
162 |
205 |
163 // If any threads have partial logs, add them to the global list of logs. |
206 // If any threads have partial logs, add them to the global list of logs. |
164 void concatenate_logs(); |
207 void concatenate_logs(); |