Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/g1/ptrQueue.cpp @ 2149:7e37af9d69ef
7011379: G1: overly long concurrent marking cycles
Summary: This changeset introduces filtering of SATB buffers at the point when they are about to be enqueued. If this filtering clears enough entries on each buffer, the buffer can then be re-used and not enqueued. This cuts down the number of SATB buffers that need to be processed by the concurrent marking threads.
Reviewed-by: johnc, ysr
author | tonyp |
---|---|
date | Wed, 19 Jan 2011 09:35:17 -0500 |
parents | f95d63e2154a |
children | f08d439fab8c |
rev | line source |
---|---|
342 | 1 /* |
2149 | 2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. |
342 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
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 | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1317
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1317
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1317
diff
changeset
|
21 * questions. |
342 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "gc_implementation/g1/ptrQueue.hpp" | |
27 #include "memory/allocation.hpp" | |
28 #include "memory/allocation.inline.hpp" | |
29 #include "runtime/mutex.hpp" | |
30 #include "runtime/mutexLocker.hpp" | |
31 #ifdef TARGET_OS_FAMILY_linux | |
32 # include "thread_linux.inline.hpp" | |
33 #endif | |
34 #ifdef TARGET_OS_FAMILY_solaris | |
35 # include "thread_solaris.inline.hpp" | |
36 #endif | |
37 #ifdef TARGET_OS_FAMILY_windows | |
38 # include "thread_windows.inline.hpp" | |
39 #endif | |
342 | 40 |
2149 | 41 PtrQueue::PtrQueue(PtrQueueSet* qset, bool perm, bool active) : |
42 _qset(qset), _buf(NULL), _index(0), _active(active), | |
342 | 43 _perm(perm), _lock(NULL) |
44 {} | |
45 | |
441
da9cb4e97a5f
6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents:
342
diff
changeset
|
46 void PtrQueue::flush() { |
342 | 47 if (!_perm && _buf != NULL) { |
48 if (_index == _sz) { | |
49 // No work to do. | |
50 qset()->deallocate_buffer(_buf); | |
51 } else { | |
52 // We must NULL out the unused entries, then enqueue. | |
53 for (size_t i = 0; i < _index; i += oopSize) { | |
54 _buf[byte_index_to_index((int)i)] = NULL; | |
55 } | |
56 qset()->enqueue_complete_buffer(_buf); | |
57 } | |
441
da9cb4e97a5f
6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents:
342
diff
changeset
|
58 _buf = NULL; |
da9cb4e97a5f
6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents:
342
diff
changeset
|
59 _index = 0; |
342 | 60 } |
61 } | |
62 | |
63 | |
64 static int byte_index_to_index(int ind) { | |
65 assert((ind % oopSize) == 0, "Invariant."); | |
66 return ind / oopSize; | |
67 } | |
68 | |
69 static int index_to_byte_index(int byte_ind) { | |
70 return byte_ind * oopSize; | |
71 } | |
72 | |
73 void PtrQueue::enqueue_known_active(void* ptr) { | |
74 assert(0 <= _index && _index <= _sz, "Invariant."); | |
75 assert(_index == 0 || _buf != NULL, "invariant"); | |
76 | |
77 while (_index == 0) { | |
78 handle_zero_index(); | |
79 } | |
1111 | 80 |
342 | 81 assert(_index > 0, "postcondition"); |
82 _index -= oopSize; | |
83 _buf[byte_index_to_index((int)_index)] = ptr; | |
84 assert(0 <= _index && _index <= _sz, "Invariant."); | |
85 } | |
86 | |
87 void PtrQueue::locking_enqueue_completed_buffer(void** buf) { | |
88 assert(_lock->owned_by_self(), "Required."); | |
1169
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
89 |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
90 // We have to unlock _lock (which may be Shared_DirtyCardQ_lock) before |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
91 // we acquire DirtyCardQ_CBL_mon inside enqeue_complete_buffer as they |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
92 // have the same rank and we may get the "possible deadlock" message |
342 | 93 _lock->unlock(); |
1169
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
94 |
342 | 95 qset()->enqueue_complete_buffer(buf); |
96 // We must relock only because the caller will unlock, for the normal | |
97 // case. | |
98 _lock->lock_without_safepoint_check(); | |
99 } | |
100 | |
101 | |
102 PtrQueueSet::PtrQueueSet(bool notify_when_complete) : | |
103 _max_completed_queue(0), | |
104 _cbl_mon(NULL), _fl_lock(NULL), | |
105 _notify_when_complete(notify_when_complete), | |
106 _sz(0), | |
107 _completed_buffers_head(NULL), | |
108 _completed_buffers_tail(NULL), | |
109 _n_completed_buffers(0), | |
110 _process_completed_threshold(0), _process_completed(false), | |
111 _buf_free_list(NULL), _buf_free_list_sz(0) | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
112 { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
113 _fl_owner = this; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
114 } |
342 | 115 |
116 void** PtrQueueSet::allocate_buffer() { | |
117 assert(_sz > 0, "Didn't set a buffer size."); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
118 MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
119 if (_fl_owner->_buf_free_list != NULL) { |
1111 | 120 void** res = BufferNode::make_buffer_from_node(_fl_owner->_buf_free_list); |
121 _fl_owner->_buf_free_list = _fl_owner->_buf_free_list->next(); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
122 _fl_owner->_buf_free_list_sz--; |
342 | 123 return res; |
124 } else { | |
1111 | 125 // Allocate space for the BufferNode in front of the buffer. |
126 char *b = NEW_C_HEAP_ARRAY(char, _sz + BufferNode::aligned_size()); | |
127 return BufferNode::make_buffer_from_block(b); | |
342 | 128 } |
129 } | |
130 | |
131 void PtrQueueSet::deallocate_buffer(void** buf) { | |
132 assert(_sz > 0, "Didn't set a buffer size."); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
133 MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag); |
1111 | 134 BufferNode *node = BufferNode::make_node_from_buffer(buf); |
135 node->set_next(_fl_owner->_buf_free_list); | |
136 _fl_owner->_buf_free_list = node; | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
137 _fl_owner->_buf_free_list_sz++; |
342 | 138 } |
139 | |
140 void PtrQueueSet::reduce_free_list() { | |
1111 | 141 assert(_fl_owner == this, "Free list reduction is allowed only for the owner"); |
342 | 142 // For now we'll adopt the strategy of deleting half. |
143 MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag); | |
144 size_t n = _buf_free_list_sz / 2; | |
145 while (n > 0) { | |
146 assert(_buf_free_list != NULL, "_buf_free_list_sz must be wrong."); | |
1111 | 147 void* b = BufferNode::make_block_from_node(_buf_free_list); |
148 _buf_free_list = _buf_free_list->next(); | |
149 FREE_C_HEAP_ARRAY(char, b); | |
1084
5f932a151fd4
6895788: G1: SATB and update buffer allocation code allocates too much space
johnc
parents:
844
diff
changeset
|
150 _buf_free_list_sz --; |
342 | 151 n--; |
152 } | |
153 } | |
154 | |
1111 | 155 void PtrQueue::handle_zero_index() { |
2149 | 156 assert(_index == 0, "Precondition."); |
157 | |
1111 | 158 // This thread records the full buffer and allocates a new one (while |
159 // holding the lock if there is one). | |
160 if (_buf != NULL) { | |
2149 | 161 if (!should_enqueue_buffer()) { |
162 assert(_index > 0, "the buffer can only be re-used if it's not full"); | |
163 return; | |
164 } | |
165 | |
1111 | 166 if (_lock) { |
1169
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
167 assert(_lock->owned_by_self(), "Required."); |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
168 |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
169 // The current PtrQ may be the shared dirty card queue and |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
170 // may be being manipulated by more than one worker thread |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
171 // during a pause. Since the enqueuing of the completed |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
172 // buffer unlocks the Shared_DirtyCardQ_lock more than one |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
173 // worker thread can 'race' on reading the shared queue attributes |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
174 // (_buf and _index) and multiple threads can call into this |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
175 // routine for the same buffer. This will cause the completed |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
176 // buffer to be added to the CBL multiple times. |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
177 |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
178 // We "claim" the current buffer by caching value of _buf in |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
179 // a local and clearing the field while holding _lock. When |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
180 // _lock is released (while enqueueing the completed buffer) |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
181 // the thread that acquires _lock will skip this code, |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
182 // preventing the subsequent the multiple enqueue, and |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
183 // install a newly allocated buffer below. |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
184 |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
185 void** buf = _buf; // local pointer to completed buffer |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
186 _buf = NULL; // clear shared _buf field |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
187 |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
188 locking_enqueue_completed_buffer(buf); // enqueue completed buffer |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
189 |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
190 // While the current thread was enqueuing the buffer another thread |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
191 // may have a allocated a new buffer and inserted it into this pointer |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
192 // queue. If that happens then we just return so that the current |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
193 // thread doesn't overwrite the buffer allocated by the other thread |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
194 // and potentially losing some dirtied cards. |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
195 |
09646c4656ca
6915005: G1: Hang in PtrQueueSet::completed_buffers_list_length with gcl001
johnc
parents:
1111
diff
changeset
|
196 if (_buf != NULL) return; |
1111 | 197 } else { |
198 if (qset()->process_or_enqueue_complete_buffer(_buf)) { | |
199 // Recycle the buffer. No allocation. | |
200 _sz = qset()->buffer_size(); | |
201 _index = _sz; | |
202 return; | |
203 } | |
204 } | |
205 } | |
206 // Reallocate the buffer | |
207 _buf = qset()->allocate_buffer(); | |
208 _sz = qset()->buffer_size(); | |
209 _index = _sz; | |
210 assert(0 <= _index && _index <= _sz, "Invariant."); | |
211 } | |
342 | 212 |
1111 | 213 bool PtrQueueSet::process_or_enqueue_complete_buffer(void** buf) { |
214 if (Thread::current()->is_Java_thread()) { | |
215 // We don't lock. It is fine to be epsilon-precise here. | |
216 if (_max_completed_queue == 0 || _max_completed_queue > 0 && | |
217 _n_completed_buffers >= _max_completed_queue + _completed_queue_padding) { | |
218 bool b = mut_process_buffer(buf); | |
219 if (b) { | |
220 // True here means that the buffer hasn't been deallocated and the caller may reuse it. | |
221 return true; | |
222 } | |
342 | 223 } |
1111 | 224 } |
225 // The buffer will be enqueued. The caller will have to get a new one. | |
226 enqueue_complete_buffer(buf); | |
227 return false; | |
228 } | |
342 | 229 |
1111 | 230 void PtrQueueSet::enqueue_complete_buffer(void** buf, size_t index) { |
231 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag); | |
232 BufferNode* cbn = BufferNode::new_from_buffer(buf); | |
233 cbn->set_index(index); | |
342 | 234 if (_completed_buffers_tail == NULL) { |
235 assert(_completed_buffers_head == NULL, "Well-formedness"); | |
236 _completed_buffers_head = cbn; | |
237 _completed_buffers_tail = cbn; | |
238 } else { | |
1111 | 239 _completed_buffers_tail->set_next(cbn); |
342 | 240 _completed_buffers_tail = cbn; |
241 } | |
242 _n_completed_buffers++; | |
243 | |
1111 | 244 if (!_process_completed && _process_completed_threshold >= 0 && |
794 | 245 _n_completed_buffers >= _process_completed_threshold) { |
342 | 246 _process_completed = true; |
247 if (_notify_when_complete) | |
1111 | 248 _cbl_mon->notify(); |
342 | 249 } |
250 debug_only(assert_completed_buffer_list_len_correct_locked()); | |
251 } | |
252 | |
253 int PtrQueueSet::completed_buffers_list_length() { | |
254 int n = 0; | |
1111 | 255 BufferNode* cbn = _completed_buffers_head; |
342 | 256 while (cbn != NULL) { |
257 n++; | |
1111 | 258 cbn = cbn->next(); |
342 | 259 } |
260 return n; | |
261 } | |
262 | |
263 void PtrQueueSet::assert_completed_buffer_list_len_correct() { | |
264 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag); | |
265 assert_completed_buffer_list_len_correct_locked(); | |
266 } | |
267 | |
268 void PtrQueueSet::assert_completed_buffer_list_len_correct_locked() { | |
1111 | 269 guarantee(completed_buffers_list_length() == _n_completed_buffers, |
342 | 270 "Completed buffer length is wrong."); |
271 } | |
272 | |
273 void PtrQueueSet::set_buffer_size(size_t sz) { | |
274 assert(_sz == 0 && sz > 0, "Should be called only once."); | |
275 _sz = sz * oopSize; | |
276 } | |
277 | |
1111 | 278 // Merge lists of buffers. Notify the processing threads. |
279 // The source queue is emptied as a result. The queues | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
280 // must share the monitor. |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
281 void PtrQueueSet::merge_bufferlists(PtrQueueSet *src) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
282 assert(_cbl_mon == src->_cbl_mon, "Should share the same lock"); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
283 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
284 if (_completed_buffers_tail == NULL) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
285 assert(_completed_buffers_head == NULL, "Well-formedness"); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
286 _completed_buffers_head = src->_completed_buffers_head; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
287 _completed_buffers_tail = src->_completed_buffers_tail; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
288 } else { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
289 assert(_completed_buffers_head != NULL, "Well formedness"); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
290 if (src->_completed_buffers_head != NULL) { |
1111 | 291 _completed_buffers_tail->set_next(src->_completed_buffers_head); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
292 _completed_buffers_tail = src->_completed_buffers_tail; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
293 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
294 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
295 _n_completed_buffers += src->_n_completed_buffers; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
296 |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
297 src->_n_completed_buffers = 0; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
298 src->_completed_buffers_head = NULL; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
299 src->_completed_buffers_tail = NULL; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
300 |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
301 assert(_completed_buffers_head == NULL && _completed_buffers_tail == NULL || |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
302 _completed_buffers_head != NULL && _completed_buffers_tail != NULL, |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
303 "Sanity"); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
304 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
305 |
1111 | 306 void PtrQueueSet::notify_if_necessary() { |
307 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag); | |
308 if (_n_completed_buffers >= _process_completed_threshold || _max_completed_queue == 0) { | |
309 _process_completed = true; | |
310 if (_notify_when_complete) | |
311 _cbl_mon->notify(); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
312 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
470
diff
changeset
|
313 } |