1 /* |
1 /* |
2 * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
226 } |
226 } |
227 DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked()); |
227 DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked()); |
228 return nd; |
228 return nd; |
229 } |
229 } |
230 |
230 |
231 bool DirtyCardQueueSet::apply_closure_to_completed_buffer_helper(CardTableEntryClosure* cl, |
|
232 uint worker_i, |
|
233 BufferNode* nd) { |
|
234 if (nd != NULL) { |
|
235 void **buf = BufferNode::make_buffer_from_node(nd); |
|
236 size_t index = nd->index(); |
|
237 bool b = |
|
238 DirtyCardQueue::apply_closure_to_buffer(cl, buf, |
|
239 index, _sz, |
|
240 true, worker_i); |
|
241 if (b) { |
|
242 deallocate_buffer(buf); |
|
243 return true; // In normal case, go on to next buffer. |
|
244 } else { |
|
245 enqueue_complete_buffer(buf, index); |
|
246 return false; |
|
247 } |
|
248 } else { |
|
249 return false; |
|
250 } |
|
251 } |
|
252 |
|
253 bool DirtyCardQueueSet::apply_closure_to_completed_buffer(CardTableEntryClosure* cl, |
231 bool DirtyCardQueueSet::apply_closure_to_completed_buffer(CardTableEntryClosure* cl, |
254 uint worker_i, |
232 uint worker_i, |
255 int stop_at, |
233 int stop_at, |
256 bool during_pause) { |
234 bool during_pause) { |
257 assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause"); |
235 assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause"); |
258 BufferNode* nd = get_completed_buffer(stop_at); |
236 BufferNode* nd = get_completed_buffer(stop_at); |
259 bool res = apply_closure_to_completed_buffer_helper(cl, worker_i, nd); |
237 if (nd == NULL) { |
260 if (res) Atomic::inc(&_processed_buffers_rs_thread); |
238 return false; |
261 return res; |
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 } |
|
254 } |
262 } |
255 } |
263 |
256 |
264 void DirtyCardQueueSet::apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl) { |
257 void DirtyCardQueueSet::apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl) { |
265 BufferNode* nd = _completed_buffers_head; |
258 BufferNode* nd = _completed_buffers_head; |
266 while (nd != NULL) { |
259 while (nd != NULL) { |