149 }
150
151 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
152 PtrQueueSet(notify_when_complete),
153 _mut_process_closure(NULL),
154 _shared_dirty_card_queue(this, true /* permanent */),
155 _free_ids(NULL),
156 _processed_buffers_mut(0), _processed_buffers_rs_thread(0)
157 {
158 _all_active = true;
159 }
160
161 // Determines how many mutator threads can process the buffers in parallel.
162 uint DirtyCardQueueSet::num_par_ids() {
163 return (uint)os::processor_count();
164 }
165
166 void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl,
167 Monitor* cbl_mon,
168 Mutex* fl_lock,
169 int process_completed_threshold,
170 int max_completed_queue,
171 Mutex* lock,
172 DirtyCardQueueSet* fl_owner,
173 bool init_free_ids) {
174 _mut_process_closure = cl;
175 PtrQueueSet::initialize(cbl_mon,
176 fl_lock,
177 process_completed_threshold,
178 max_completed_queue,
179 fl_owner);
180 set_buffer_size(G1UpdateBufferSize);
181 _shared_dirty_card_queue.set_lock(lock);
182 if (init_free_ids) {
183 _free_ids = new FreeIdSet(num_par_ids(), _cbl_mon);
184 }
185 }
186
187 void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
188 t->dirty_card_queue().handle_zero_index();
189 }
190
191 bool DirtyCardQueueSet::mut_process_buffer(void** buf) {
192 guarantee(_free_ids != NULL, "must be");
193
194 // claim a par id
195 uint worker_i = _free_ids->claim_par_id();
196
197 bool b = DirtyCardQueue::apply_closure_to_buffer(_mut_process_closure, buf, 0,
198 _sz, true, worker_i);
199 if (b) {
200 Atomic::inc(&_processed_buffers_mut);
201 }
202
203 // release the id
204 _free_ids->release_par_id(worker_i);
205
206 return b;
207 }
208
209
210 BufferNode* DirtyCardQueueSet::get_completed_buffer(int stop_at) {
211 BufferNode* nd = NULL;
212 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
213
214 if ((int)_n_completed_buffers <= stop_at) {
215 _process_completed = false;
216 return NULL;
217 }
218
219 if (_completed_buffers_head != NULL) {
220 nd = _completed_buffers_head;
221 _completed_buffers_head = nd->next();
222 if (_completed_buffers_head == NULL)
223 _completed_buffers_tail = NULL;
224 _n_completed_buffers--;
225 assert(_n_completed_buffers >= 0, "Invariant");
226 }
227 DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
228 return nd;
229 }
230
231 bool DirtyCardQueueSet::apply_closure_to_completed_buffer(CardTableEntryClosure* cl,
232 uint worker_i,
233 int stop_at,
234 bool during_pause) {
235 assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause");
236 BufferNode* nd = get_completed_buffer(stop_at);
237 if (nd == NULL) {
238 return false;
239 } else {
240 void** buf = BufferNode::make_buffer_from_node(nd);
241 size_t index = nd->index();
242 if (DirtyCardQueue::apply_closure_to_buffer(cl,
243 buf, index, _sz,
244 true, worker_i)) {
245 // Done with fully processed buffer.
246 deallocate_buffer(buf);
247 Atomic::inc(&_processed_buffers_rs_thread);
248 return true;
249 } else {
250 // Return partially processed buffer to the queue.
251 enqueue_complete_buffer(buf, index);
252 return false;
253 }
306 }
307
308 }
309
310 void DirtyCardQueueSet::abandon_logs() {
311 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
312 clear();
313 // Since abandon is done only at safepoints, we can safely manipulate
314 // these queues.
315 for (JavaThread* t = Threads::first(); t; t = t->next()) {
316 t->dirty_card_queue().reset();
317 }
318 shared_dirty_card_queue()->reset();
319 }
320
321
322 void DirtyCardQueueSet::concatenate_logs() {
323 // Iterate over all the threads, if we find a partial log add it to
324 // the global list of logs. Temporarily turn off the limit on the number
325 // of outstanding buffers.
326 int save_max_completed_queue = _max_completed_queue;
327 _max_completed_queue = max_jint;
328 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
329 for (JavaThread* t = Threads::first(); t; t = t->next()) {
330 DirtyCardQueue& dcq = t->dirty_card_queue();
331 if (dcq.size() != 0) {
332 void** buf = dcq.get_buf();
333 // We must NULL out the unused entries, then enqueue.
334 size_t limit = dcq.byte_index_to_index(dcq.get_index());
335 for (size_t i = 0; i < limit; ++i) {
336 buf[i] = NULL;
337 }
338 enqueue_complete_buffer(dcq.get_buf(), dcq.get_index());
339 dcq.reinitialize();
340 }
341 }
342 if (_shared_dirty_card_queue.size() != 0) {
343 enqueue_complete_buffer(_shared_dirty_card_queue.get_buf(),
344 _shared_dirty_card_queue.get_index());
345 _shared_dirty_card_queue.reinitialize();
346 }
|
149 }
150
151 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
152 PtrQueueSet(notify_when_complete),
153 _mut_process_closure(NULL),
154 _shared_dirty_card_queue(this, true /* permanent */),
155 _free_ids(NULL),
156 _processed_buffers_mut(0), _processed_buffers_rs_thread(0)
157 {
158 _all_active = true;
159 }
160
161 // Determines how many mutator threads can process the buffers in parallel.
162 uint DirtyCardQueueSet::num_par_ids() {
163 return (uint)os::processor_count();
164 }
165
166 void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl,
167 Monitor* cbl_mon,
168 Mutex* fl_lock,
169 size_t process_completed_threshold,
170 size_t max_completed_queue,
171 Mutex* lock,
172 DirtyCardQueueSet* fl_owner,
173 bool init_free_ids) {
174 _mut_process_closure = cl;
175 PtrQueueSet::initialize(cbl_mon,
176 fl_lock,
177 process_completed_threshold,
178 max_completed_queue,
179 fl_owner);
180 set_buffer_size(G1UpdateBufferSize);
181 _shared_dirty_card_queue.set_lock(lock);
182 if (init_free_ids) {
183 _free_ids = new FreeIdSet(num_par_ids(), _cbl_mon);
184 }
185 }
186
187 void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
188 t->dirty_card_queue().handle_zero_index();
189 }
190
191 bool DirtyCardQueueSet::mut_process_buffer(void** buf) {
192 guarantee(_free_ids != NULL, "must be");
193
194 // claim a par id
195 uint worker_i = _free_ids->claim_par_id();
196
197 bool b = DirtyCardQueue::apply_closure_to_buffer(_mut_process_closure, buf, 0,
198 _sz, true, worker_i);
199 if (b) {
200 Atomic::inc(&_processed_buffers_mut);
201 }
202
203 // release the id
204 _free_ids->release_par_id(worker_i);
205
206 return b;
207 }
208
209
210 BufferNode* DirtyCardQueueSet::get_completed_buffer(size_t stop_at) {
211 BufferNode* nd = NULL;
212 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
213
214 if (_n_completed_buffers <= stop_at) {
215 _process_completed = false;
216 return NULL;
217 }
218
219 if (_completed_buffers_head != NULL) {
220 nd = _completed_buffers_head;
221 assert(_n_completed_buffers > 0, "Invariant");
222 _completed_buffers_head = nd->next();
223 _n_completed_buffers--;
224 if (_completed_buffers_head == NULL) {
225 assert(_n_completed_buffers == 0, "Invariant");
226 _completed_buffers_tail = NULL;
227 }
228 }
229 DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
230 return nd;
231 }
232
233 bool DirtyCardQueueSet::apply_closure_to_completed_buffer(CardTableEntryClosure* cl,
234 uint worker_i,
235 size_t stop_at,
236 bool during_pause) {
237 assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause");
238 BufferNode* nd = get_completed_buffer(stop_at);
239 if (nd == NULL) {
240 return false;
241 } else {
242 void** buf = BufferNode::make_buffer_from_node(nd);
243 size_t index = nd->index();
244 if (DirtyCardQueue::apply_closure_to_buffer(cl,
245 buf, index, _sz,
246 true, worker_i)) {
247 // Done with fully processed buffer.
248 deallocate_buffer(buf);
249 Atomic::inc(&_processed_buffers_rs_thread);
250 return true;
251 } else {
252 // Return partially processed buffer to the queue.
253 enqueue_complete_buffer(buf, index);
254 return false;
255 }
308 }
309
310 }
311
312 void DirtyCardQueueSet::abandon_logs() {
313 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
314 clear();
315 // Since abandon is done only at safepoints, we can safely manipulate
316 // these queues.
317 for (JavaThread* t = Threads::first(); t; t = t->next()) {
318 t->dirty_card_queue().reset();
319 }
320 shared_dirty_card_queue()->reset();
321 }
322
323
324 void DirtyCardQueueSet::concatenate_logs() {
325 // Iterate over all the threads, if we find a partial log add it to
326 // the global list of logs. Temporarily turn off the limit on the number
327 // of outstanding buffers.
328 size_t save_max_completed_queue = _max_completed_queue;
329 _max_completed_queue = max_jint;
330 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
331 for (JavaThread* t = Threads::first(); t; t = t->next()) {
332 DirtyCardQueue& dcq = t->dirty_card_queue();
333 if (dcq.size() != 0) {
334 void** buf = dcq.get_buf();
335 // We must NULL out the unused entries, then enqueue.
336 size_t limit = dcq.byte_index_to_index(dcq.get_index());
337 for (size_t i = 0; i < limit; ++i) {
338 buf[i] = NULL;
339 }
340 enqueue_complete_buffer(dcq.get_buf(), dcq.get_index());
341 dcq.reinitialize();
342 }
343 }
344 if (_shared_dirty_card_queue.size() != 0) {
345 enqueue_complete_buffer(_shared_dirty_card_queue.get_buf(),
346 _shared_dirty_card_queue.get_index());
347 _shared_dirty_card_queue.reinitialize();
348 }
|