// Deallocates any completed log buffers void DirtyCardQueueSet::clear() { BufferNode* buffers_to_delete = NULL; { MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag); while (_completed_buffers_head != NULL) { BufferNode* nd = _completed_buffers_head; _completed_buffers_head = nd->next(); nd->set_next(buffers_to_delete); buffers_to_delete = nd; } _n_completed_buffers = 0; _completed_buffers_tail = NULL; DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked()); } while (buffers_to_delete != NULL) { BufferNode* nd = buffers_to_delete; buffers_to_delete = nd->next(); deallocate_buffer(nd); } }
bool DirtyCardQueueSet::apply_closure_to_completed_buffer(CardTableEntryClosure* cl, uint worker_i, size_t stop_at, bool during_pause) { assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause"); BufferNode* nd = get_completed_buffer(stop_at); if (nd == NULL) { return false; } else { if (apply_closure_to_buffer(cl, nd, true, worker_i)) { assert_fully_consumed(nd, buffer_size()); // Done with fully processed buffer. deallocate_buffer(nd); Atomic::inc(&_processed_buffers_rs_thread); } else { // Return partially processed buffer to the queue. guarantee(!during_pause, "Should never stop early"); enqueue_complete_buffer(nd); } return true; } }
bool DirtyCardQueueSet:: apply_closure_to_completed_buffer_helper(CardTableEntryClosure* cl, int worker_i, BufferNode* nd) { if (nd != NULL) { void **buf = BufferNode::make_buffer_from_node(nd); size_t index = nd->index(); bool b = DirtyCardQueue::apply_closure_to_buffer(cl, buf, index, _sz, true, worker_i); if (b) { deallocate_buffer(buf); return true; // In normal case, go on to next buffer. } else { enqueue_complete_buffer(buf, index); return false; } } else { return false; } }