1 /* |
1 /* |
2 * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2001, 2010, 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. |
176 debug_only(assert_completed_buffer_list_len_correct_locked()); |
176 debug_only(assert_completed_buffer_list_len_correct_locked()); |
177 return nd; |
177 return nd; |
178 } |
178 } |
179 |
179 |
180 bool DirtyCardQueueSet:: |
180 bool DirtyCardQueueSet:: |
181 apply_closure_to_completed_buffer_helper(int worker_i, |
181 apply_closure_to_completed_buffer_helper(CardTableEntryClosure* cl, |
|
182 int worker_i, |
182 BufferNode* nd) { |
183 BufferNode* nd) { |
183 if (nd != NULL) { |
184 if (nd != NULL) { |
184 void **buf = BufferNode::make_buffer_from_node(nd); |
185 void **buf = BufferNode::make_buffer_from_node(nd); |
185 size_t index = nd->index(); |
186 size_t index = nd->index(); |
186 bool b = |
187 bool b = |
187 DirtyCardQueue::apply_closure_to_buffer(_closure, buf, |
188 DirtyCardQueue::apply_closure_to_buffer(cl, buf, |
188 index, _sz, |
189 index, _sz, |
189 true, worker_i); |
190 true, worker_i); |
190 if (b) { |
191 if (b) { |
191 deallocate_buffer(buf); |
192 deallocate_buffer(buf); |
192 return true; // In normal case, go on to next buffer. |
193 return true; // In normal case, go on to next buffer. |
197 } else { |
198 } else { |
198 return false; |
199 return false; |
199 } |
200 } |
200 } |
201 } |
201 |
202 |
|
203 bool DirtyCardQueueSet::apply_closure_to_completed_buffer(CardTableEntryClosure* cl, |
|
204 int worker_i, |
|
205 int stop_at, |
|
206 bool during_pause) { |
|
207 assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause"); |
|
208 BufferNode* nd = get_completed_buffer(stop_at); |
|
209 bool res = apply_closure_to_completed_buffer_helper(cl, worker_i, nd); |
|
210 if (res) Atomic::inc(&_processed_buffers_rs_thread); |
|
211 return res; |
|
212 } |
|
213 |
202 bool DirtyCardQueueSet::apply_closure_to_completed_buffer(int worker_i, |
214 bool DirtyCardQueueSet::apply_closure_to_completed_buffer(int worker_i, |
203 int stop_at, |
215 int stop_at, |
204 bool during_pause) |
216 bool during_pause) { |
205 { |
217 return apply_closure_to_completed_buffer(_closure, worker_i, |
206 assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause"); |
218 stop_at, during_pause); |
207 BufferNode* nd = get_completed_buffer(stop_at); |
|
208 bool res = apply_closure_to_completed_buffer_helper(worker_i, nd); |
|
209 if (res) Atomic::inc(&_processed_buffers_rs_thread); |
|
210 return res; |
|
211 } |
219 } |
212 |
220 |
213 void DirtyCardQueueSet::apply_closure_to_all_completed_buffers() { |
221 void DirtyCardQueueSet::apply_closure_to_all_completed_buffers() { |
214 BufferNode* nd = _completed_buffers_head; |
222 BufferNode* nd = _completed_buffers_head; |
215 while (nd != NULL) { |
223 while (nd != NULL) { |
220 guarantee(b, "Should not stop early."); |
228 guarantee(b, "Should not stop early."); |
221 nd = nd->next(); |
229 nd = nd->next(); |
222 } |
230 } |
223 } |
231 } |
224 |
232 |
225 void DirtyCardQueueSet::abandon_logs() { |
233 // Deallocates any completed log buffers |
226 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); |
234 void DirtyCardQueueSet::clear() { |
227 BufferNode* buffers_to_delete = NULL; |
235 BufferNode* buffers_to_delete = NULL; |
228 { |
236 { |
229 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag); |
237 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag); |
230 while (_completed_buffers_head != NULL) { |
238 while (_completed_buffers_head != NULL) { |
231 BufferNode* nd = _completed_buffers_head; |
239 BufferNode* nd = _completed_buffers_head; |
240 while (buffers_to_delete != NULL) { |
248 while (buffers_to_delete != NULL) { |
241 BufferNode* nd = buffers_to_delete; |
249 BufferNode* nd = buffers_to_delete; |
242 buffers_to_delete = nd->next(); |
250 buffers_to_delete = nd->next(); |
243 deallocate_buffer(BufferNode::make_buffer_from_node(nd)); |
251 deallocate_buffer(BufferNode::make_buffer_from_node(nd)); |
244 } |
252 } |
|
253 |
|
254 } |
|
255 |
|
256 void DirtyCardQueueSet::abandon_logs() { |
|
257 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); |
|
258 clear(); |
245 // Since abandon is done only at safepoints, we can safely manipulate |
259 // Since abandon is done only at safepoints, we can safely manipulate |
246 // these queues. |
260 // these queues. |
247 for (JavaThread* t = Threads::first(); t; t = t->next()) { |
261 for (JavaThread* t = Threads::first(); t; t = t->next()) { |
248 t->dirty_card_queue().reset(); |
262 t->dirty_card_queue().reset(); |
249 } |
263 } |