comparison src/share/vm/gc_implementation/g1/ptrQueue.cpp @ 616:4f360ec815ba

6720309: G1: don't synchronously update RSet during evacuation pauses 6720334: G1: don't update RSets of collection set regions during an evacuation pause Summary: Introduced a deferred update mechanism for delaying the rset updates during the collection pause Reviewed-by: apetrusenko, tonyp
author iveresov
date Fri, 06 Mar 2009 13:50:14 -0800
parents ad8c8ca4ab0f
children 315a5d70b295
comparison
equal deleted inserted replaced
615:c6c601a0f2d6 616:4f360ec815ba
89 _completed_buffers_head(NULL), 89 _completed_buffers_head(NULL),
90 _completed_buffers_tail(NULL), 90 _completed_buffers_tail(NULL),
91 _n_completed_buffers(0), 91 _n_completed_buffers(0),
92 _process_completed_threshold(0), _process_completed(false), 92 _process_completed_threshold(0), _process_completed(false),
93 _buf_free_list(NULL), _buf_free_list_sz(0) 93 _buf_free_list(NULL), _buf_free_list_sz(0)
94 {} 94 {
95 _fl_owner = this;
96 }
95 97
96 void** PtrQueueSet::allocate_buffer() { 98 void** PtrQueueSet::allocate_buffer() {
97 assert(_sz > 0, "Didn't set a buffer size."); 99 assert(_sz > 0, "Didn't set a buffer size.");
98 MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag); 100 MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag);
99 if (_buf_free_list != NULL) { 101 if (_fl_owner->_buf_free_list != NULL) {
100 void** res = _buf_free_list; 102 void** res = _fl_owner->_buf_free_list;
101 _buf_free_list = (void**)_buf_free_list[0]; 103 _fl_owner->_buf_free_list = (void**)_fl_owner->_buf_free_list[0];
102 _buf_free_list_sz--; 104 _fl_owner->_buf_free_list_sz--;
103 // Just override the next pointer with NULL, just in case we scan this part 105 // Just override the next pointer with NULL, just in case we scan this part
104 // of the buffer. 106 // of the buffer.
105 res[0] = NULL; 107 res[0] = NULL;
106 return res; 108 return res;
107 } else { 109 } else {
109 } 111 }
110 } 112 }
111 113
112 void PtrQueueSet::deallocate_buffer(void** buf) { 114 void PtrQueueSet::deallocate_buffer(void** buf) {
113 assert(_sz > 0, "Didn't set a buffer size."); 115 assert(_sz > 0, "Didn't set a buffer size.");
114 MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag); 116 MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag);
115 buf[0] = (void*)_buf_free_list; 117 buf[0] = (void*)_fl_owner->_buf_free_list;
116 _buf_free_list = buf; 118 _fl_owner->_buf_free_list = buf;
117 _buf_free_list_sz++; 119 _fl_owner->_buf_free_list_sz++;
118 } 120 }
119 121
120 void PtrQueueSet::reduce_free_list() { 122 void PtrQueueSet::reduce_free_list() {
121 // For now we'll adopt the strategy of deleting half. 123 // For now we'll adopt the strategy of deleting half.
122 MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag); 124 MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag);
205 } 207 }
206 208
207 void PtrQueueSet::set_process_completed_threshold(size_t sz) { 209 void PtrQueueSet::set_process_completed_threshold(size_t sz) {
208 _process_completed_threshold = sz; 210 _process_completed_threshold = sz;
209 } 211 }
212
213 // Merge lists of buffers. Notify waiting threads if the length of the list
214 // exceeds threshold. The source queue is emptied as a result. The queues
215 // must share the monitor.
216 void PtrQueueSet::merge_bufferlists(PtrQueueSet *src) {
217 assert(_cbl_mon == src->_cbl_mon, "Should share the same lock");
218 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
219 if (_completed_buffers_tail == NULL) {
220 assert(_completed_buffers_head == NULL, "Well-formedness");
221 _completed_buffers_head = src->_completed_buffers_head;
222 _completed_buffers_tail = src->_completed_buffers_tail;
223 } else {
224 assert(_completed_buffers_head != NULL, "Well formedness");
225 if (src->_completed_buffers_head != NULL) {
226 _completed_buffers_tail->next = src->_completed_buffers_head;
227 _completed_buffers_tail = src->_completed_buffers_tail;
228 }
229 }
230 _n_completed_buffers += src->_n_completed_buffers;
231
232 src->_n_completed_buffers = 0;
233 src->_completed_buffers_head = NULL;
234 src->_completed_buffers_tail = NULL;
235
236 assert(_completed_buffers_head == NULL && _completed_buffers_tail == NULL ||
237 _completed_buffers_head != NULL && _completed_buffers_tail != NULL,
238 "Sanity");
239
240 if (!_process_completed &&
241 _n_completed_buffers >= _process_completed_threshold) {
242 _process_completed = true;
243 if (_notify_when_complete)
244 _cbl_mon->notify_all();
245 }
246 }
247
248 // Merge free lists of the two queues. The free list of the source
249 // queue is emptied as a result. The queues must share the same
250 // mutex that guards free lists.
251 void PtrQueueSet::merge_freelists(PtrQueueSet* src) {
252 assert(_fl_lock == src->_fl_lock, "Should share the same lock");
253 MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag);
254 if (_buf_free_list != NULL) {
255 void **p = _buf_free_list;
256 while (*p != NULL) {
257 p = (void**)*p;
258 }
259 *p = src->_buf_free_list;
260 } else {
261 _buf_free_list = src->_buf_free_list;
262 }
263 _buf_free_list_sz += src->_buf_free_list_sz;
264 src->_buf_free_list = NULL;
265 src->_buf_free_list_sz = 0;
266 }