Mercurial > hg > truffle
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 } |