39 // SATB queues are only active during marking cycles. We create |
39 // SATB queues are only active during marking cycles. We create |
40 // them with their active field set to false. If a thread is |
40 // them with their active field set to false. If a thread is |
41 // created during a cycle and its SATB queue needs to be activated |
41 // created during a cycle and its SATB queue needs to be activated |
42 // before the thread starts running, we'll need to set its active |
42 // before the thread starts running, we'll need to set its active |
43 // field to true. This must be done in the collector-specific |
43 // field to true. This must be done in the collector-specific |
44 // BarrierSet::on_thread_attach() implementation. |
44 // BarrierSet thread attachment protocol. |
45 PtrQueue(qset, permanent, false /* active */) |
45 PtrQueue(qset, permanent, false /* active */) |
46 { } |
46 { } |
47 |
47 |
48 void SATBMarkQueue::flush() { |
48 void SATBMarkQueue::flush() { |
49 // Filter now to possibly save work later. If filtering empties the |
49 // Filter now to possibly save work later. If filtering empties the |
55 // This method will first apply filtering to the buffer. If filtering |
55 // This method will first apply filtering to the buffer. If filtering |
56 // retains a small enough collection in the buffer, we can continue to |
56 // retains a small enough collection in the buffer, we can continue to |
57 // use the buffer as-is, instead of enqueueing and replacing it. |
57 // use the buffer as-is, instead of enqueueing and replacing it. |
58 |
58 |
59 bool SATBMarkQueue::should_enqueue_buffer() { |
59 bool SATBMarkQueue::should_enqueue_buffer() { |
60 assert(_lock == NULL || _lock->owned_by_self(), |
|
61 "we should have taken the lock before calling this"); |
|
62 |
|
63 // This method should only be called if there is a non-NULL buffer |
60 // This method should only be called if there is a non-NULL buffer |
64 // that is full. |
61 // that is full. |
65 assert(index() == 0, "pre-condition"); |
62 assert(index() == 0, "pre-condition"); |
66 assert(_buf != NULL, "pre-condition"); |
63 assert(_buf != NULL, "pre-condition"); |
67 |
64 |
105 |
102 |
106 #endif // PRODUCT |
103 #endif // PRODUCT |
107 |
104 |
108 SATBMarkQueueSet::SATBMarkQueueSet() : |
105 SATBMarkQueueSet::SATBMarkQueueSet() : |
109 PtrQueueSet(), |
106 PtrQueueSet(), |
110 _shared_satb_queue(this, true /* permanent */), |
|
111 _buffer_enqueue_threshold(0) |
107 _buffer_enqueue_threshold(0) |
112 {} |
108 {} |
113 |
109 |
114 void SATBMarkQueueSet::initialize(Monitor* cbl_mon, |
110 void SATBMarkQueueSet::initialize(Monitor* cbl_mon, |
115 BufferNode::Allocator* allocator, |
111 BufferNode::Allocator* allocator, |
116 size_t process_completed_buffers_threshold, |
112 size_t process_completed_buffers_threshold, |
117 uint buffer_enqueue_threshold_percentage, |
113 uint buffer_enqueue_threshold_percentage) { |
118 Mutex* lock) { |
|
119 PtrQueueSet::initialize(cbl_mon, allocator); |
114 PtrQueueSet::initialize(cbl_mon, allocator); |
120 set_process_completed_buffers_threshold(process_completed_buffers_threshold); |
115 set_process_completed_buffers_threshold(process_completed_buffers_threshold); |
121 _shared_satb_queue.set_lock(lock); |
|
122 assert(buffer_size() != 0, "buffer size not initialized"); |
116 assert(buffer_size() != 0, "buffer size not initialized"); |
123 // Minimum threshold of 1 ensures enqueuing of completely full buffers. |
117 // Minimum threshold of 1 ensures enqueuing of completely full buffers. |
124 size_t size = buffer_size(); |
118 size_t size = buffer_size(); |
125 size_t enqueue_qty = (size * buffer_enqueue_threshold_percentage) / 100; |
119 size_t enqueue_qty = (size * buffer_enqueue_threshold_percentage) / 100; |
126 _buffer_enqueue_threshold = MAX2(size - enqueue_qty, (size_t)1); |
120 _buffer_enqueue_threshold = MAX2(size - enqueue_qty, (size_t)1); |
129 #ifdef ASSERT |
123 #ifdef ASSERT |
130 void SATBMarkQueueSet::dump_active_states(bool expected_active) { |
124 void SATBMarkQueueSet::dump_active_states(bool expected_active) { |
131 log_error(gc, verify)("Expected SATB active state: %s", expected_active ? "ACTIVE" : "INACTIVE"); |
125 log_error(gc, verify)("Expected SATB active state: %s", expected_active ? "ACTIVE" : "INACTIVE"); |
132 log_error(gc, verify)("Actual SATB active states:"); |
126 log_error(gc, verify)("Actual SATB active states:"); |
133 log_error(gc, verify)(" Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE"); |
127 log_error(gc, verify)(" Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE"); |
134 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { |
128 |
135 log_error(gc, verify)(" Thread \"%s\" queue: %s", t->name(), satb_queue_for_thread(t).is_active() ? "ACTIVE" : "INACTIVE"); |
129 class DumpThreadStateClosure : public ThreadClosure { |
136 } |
130 SATBMarkQueueSet* _qset; |
137 log_error(gc, verify)(" Shared queue: %s", shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE"); |
131 public: |
|
132 DumpThreadStateClosure(SATBMarkQueueSet* qset) : _qset(qset) {} |
|
133 virtual void do_thread(Thread* t) { |
|
134 SATBMarkQueue& queue = _qset->satb_queue_for_thread(t); |
|
135 log_error(gc, verify)(" Thread \"%s\" queue: %s", |
|
136 t->name(), |
|
137 queue.is_active() ? "ACTIVE" : "INACTIVE"); |
|
138 } |
|
139 } closure(this); |
|
140 Threads::threads_do(&closure); |
138 } |
141 } |
139 |
142 |
140 void SATBMarkQueueSet::verify_active_states(bool expected_active) { |
143 void SATBMarkQueueSet::verify_active_states(bool expected_active) { |
141 // Verify queue set state |
144 // Verify queue set state |
142 if (is_active() != expected_active) { |
145 if (is_active() != expected_active) { |
143 dump_active_states(expected_active); |
146 dump_active_states(expected_active); |
144 guarantee(false, "SATB queue set has an unexpected active state"); |
147 fatal("SATB queue set has an unexpected active state"); |
145 } |
148 } |
146 |
149 |
147 // Verify thread queue states |
150 // Verify thread queue states |
148 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { |
151 class VerifyThreadStatesClosure : public ThreadClosure { |
149 if (satb_queue_for_thread(t).is_active() != expected_active) { |
152 SATBMarkQueueSet* _qset; |
150 dump_active_states(expected_active); |
153 bool _expected_active; |
151 guarantee(false, "Thread SATB queue has an unexpected active state"); |
154 public: |
152 } |
155 VerifyThreadStatesClosure(SATBMarkQueueSet* qset, bool expected_active) : |
153 } |
156 _qset(qset), _expected_active(expected_active) {} |
154 |
157 virtual void do_thread(Thread* t) { |
155 // Verify shared queue state |
158 if (_qset->satb_queue_for_thread(t).is_active() != _expected_active) { |
156 if (shared_satb_queue()->is_active() != expected_active) { |
159 _qset->dump_active_states(_expected_active); |
157 dump_active_states(expected_active); |
160 fatal("Thread SATB queue has an unexpected active state"); |
158 guarantee(false, "Shared SATB queue has an unexpected active state"); |
161 } |
159 } |
162 } |
|
163 } closure(this, expected_active); |
|
164 Threads::threads_do(&closure); |
160 } |
165 } |
161 #endif // ASSERT |
166 #endif // ASSERT |
162 |
167 |
163 void SATBMarkQueueSet::set_active_all_threads(bool active, bool expected_active) { |
168 void SATBMarkQueueSet::set_active_all_threads(bool active, bool expected_active) { |
164 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); |
169 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); |
165 #ifdef ASSERT |
170 #ifdef ASSERT |
166 verify_active_states(expected_active); |
171 verify_active_states(expected_active); |
167 #endif // ASSERT |
172 #endif // ASSERT |
168 _all_active = active; |
173 _all_active = active; |
169 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { |
174 |
170 satb_queue_for_thread(t).set_active(active); |
175 class SetThreadActiveClosure : public ThreadClosure { |
171 } |
176 SATBMarkQueueSet* _qset; |
172 shared_satb_queue()->set_active(active); |
177 bool _active; |
|
178 public: |
|
179 SetThreadActiveClosure(SATBMarkQueueSet* qset, bool active) : |
|
180 _qset(qset), _active(active) {} |
|
181 virtual void do_thread(Thread* t) { |
|
182 _qset->satb_queue_for_thread(t).set_active(_active); |
|
183 } |
|
184 } closure(this, active); |
|
185 Threads::threads_do(&closure); |
173 } |
186 } |
174 |
187 |
175 void SATBMarkQueueSet::filter_thread_buffers() { |
188 void SATBMarkQueueSet::filter_thread_buffers() { |
176 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { |
189 class FilterThreadBufferClosure : public ThreadClosure { |
177 satb_queue_for_thread(t).filter(); |
190 SATBMarkQueueSet* _qset; |
178 } |
191 public: |
179 shared_satb_queue()->filter(); |
192 FilterThreadBufferClosure(SATBMarkQueueSet* qset) : _qset(qset) {} |
|
193 virtual void do_thread(Thread* t) { |
|
194 _qset->satb_queue_for_thread(t).filter(); |
|
195 } |
|
196 } closure(this); |
|
197 Threads::threads_do(&closure); |
180 } |
198 } |
181 |
199 |
182 bool SATBMarkQueueSet::apply_closure_to_completed_buffer(SATBBufferClosure* cl) { |
200 bool SATBMarkQueueSet::apply_closure_to_completed_buffer(SATBBufferClosure* cl) { |
183 BufferNode* nd = get_completed_buffer(); |
201 BufferNode* nd = get_completed_buffer(); |
184 if (nd != NULL) { |
202 if (nd != NULL) { |
214 print_satb_buffer(buffer, buf, nd->index(), buffer_size()); |
232 print_satb_buffer(buffer, buf, nd->index(), buffer_size()); |
215 nd = nd->next(); |
233 nd = nd->next(); |
216 i += 1; |
234 i += 1; |
217 } |
235 } |
218 |
236 |
219 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { |
237 class PrintThreadClosure : public ThreadClosure { |
220 os::snprintf(buffer, SATB_PRINTER_BUFFER_SIZE, "Thread: %s", t->name()); |
238 SATBMarkQueueSet* _qset; |
221 satb_queue_for_thread(t).print(buffer); |
239 char* _buffer; |
222 } |
240 |
223 |
241 public: |
224 shared_satb_queue()->print("Shared"); |
242 PrintThreadClosure(SATBMarkQueueSet* qset, char* buffer) : |
|
243 _qset(qset), _buffer(buffer) {} |
|
244 |
|
245 virtual void do_thread(Thread* t) { |
|
246 os::snprintf(_buffer, SATB_PRINTER_BUFFER_SIZE, "Thread: %s", t->name()); |
|
247 _qset->satb_queue_for_thread(t).print(_buffer); |
|
248 } |
|
249 } closure(this, buffer); |
|
250 Threads::threads_do(&closure); |
225 |
251 |
226 tty->cr(); |
252 tty->cr(); |
227 } |
253 } |
228 #endif // PRODUCT |
254 #endif // PRODUCT |
229 |
255 |
230 void SATBMarkQueueSet::abandon_partial_marking() { |
256 void SATBMarkQueueSet::abandon_partial_marking() { |
|
257 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); |
231 abandon_completed_buffers(); |
258 abandon_completed_buffers(); |
232 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); |
259 |
233 // So we can safely manipulate these queues. |
260 class AbandonThreadQueueClosure : public ThreadClosure { |
234 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { |
261 SATBMarkQueueSet* _qset; |
235 satb_queue_for_thread(t).reset(); |
262 public: |
236 } |
263 AbandonThreadQueueClosure(SATBMarkQueueSet* qset) : _qset(qset) {} |
237 shared_satb_queue()->reset(); |
264 virtual void do_thread(Thread* t) { |
238 } |
265 _qset->satb_queue_for_thread(t).reset(); |
|
266 } |
|
267 } closure(this); |
|
268 Threads::threads_do(&closure); |
|
269 } |