30 #include "runtime/atomic.inline.hpp" |
30 #include "runtime/atomic.inline.hpp" |
31 #include "runtime/mutexLocker.hpp" |
31 #include "runtime/mutexLocker.hpp" |
32 #include "runtime/safepoint.hpp" |
32 #include "runtime/safepoint.hpp" |
33 #include "runtime/thread.inline.hpp" |
33 #include "runtime/thread.inline.hpp" |
34 |
34 |
|
35 DirtyCardQueue::DirtyCardQueue(DirtyCardQueueSet* qset, bool permanent) : |
|
36 // Dirty card queues are always active, so we create them with their |
|
37 // active field set to true. |
|
38 PtrQueue(qset, permanent, true /* active */) |
|
39 { } |
|
40 |
|
41 DirtyCardQueue::~DirtyCardQueue() { |
|
42 if (!is_permanent()) { |
|
43 flush(); |
|
44 } |
|
45 } |
|
46 |
35 bool DirtyCardQueue::apply_closure(CardTableEntryClosure* cl, |
47 bool DirtyCardQueue::apply_closure(CardTableEntryClosure* cl, |
36 bool consume, |
48 bool consume, |
37 uint worker_i) { |
49 uint worker_i) { |
38 bool res = true; |
50 bool res = true; |
39 if (_buf != NULL) { |
51 if (_buf != NULL) { |
40 res = apply_closure_to_buffer(cl, _buf, _index, _sz, |
52 res = apply_closure_to_buffer(cl, _buf, _index, _sz, |
41 consume, |
53 consume, |
42 worker_i); |
54 worker_i); |
43 if (res && consume) _index = _sz; |
55 if (res && consume) { |
|
56 _index = _sz; |
|
57 } |
44 } |
58 } |
45 return res; |
59 return res; |
46 } |
60 } |
47 |
61 |
48 bool DirtyCardQueue::apply_closure_to_buffer(CardTableEntryClosure* cl, |
62 bool DirtyCardQueue::apply_closure_to_buffer(CardTableEntryClosure* cl, |
49 void** buf, |
63 void** buf, |
50 size_t index, size_t sz, |
64 size_t index, size_t sz, |
51 bool consume, |
65 bool consume, |
52 uint worker_i) { |
66 uint worker_i) { |
53 if (cl == NULL) return true; |
67 if (cl == NULL) return true; |
54 for (size_t i = index; i < sz; i += oopSize) { |
68 size_t limit = byte_index_to_index(sz); |
55 int ind = byte_index_to_index((int)i); |
69 for (size_t i = byte_index_to_index(index); i < limit; ++i) { |
56 jbyte* card_ptr = (jbyte*)buf[ind]; |
70 jbyte* card_ptr = static_cast<jbyte*>(buf[i]); |
57 if (card_ptr != NULL) { |
71 if (card_ptr != NULL) { |
58 // Set the entry to null, so we don't do it again (via the test |
72 // Set the entry to null, so we don't do it again (via the test |
59 // above) if we reconsider this buffer. |
73 // above) if we reconsider this buffer. |
60 if (consume) buf[ind] = NULL; |
74 if (consume) { |
61 if (!cl->do_card_ptr(card_ptr, worker_i)) return false; |
75 buf[i] = NULL; |
|
76 } |
|
77 if (!cl->do_card_ptr(card_ptr, worker_i)) { |
|
78 return false; |
|
79 } |
62 } |
80 } |
63 } |
81 } |
64 return true; |
82 return true; |
65 } |
83 } |
66 |
84 |
67 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) : |
85 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) : |
68 PtrQueueSet(notify_when_complete), |
86 PtrQueueSet(notify_when_complete), |
69 _mut_process_closure(NULL), |
87 _mut_process_closure(NULL), |
70 _shared_dirty_card_queue(this, true /*perm*/), |
88 _shared_dirty_card_queue(this, true /* permanent */), |
71 _free_ids(NULL), |
89 _free_ids(NULL), |
72 _processed_buffers_mut(0), _processed_buffers_rs_thread(0) |
90 _processed_buffers_mut(0), _processed_buffers_rs_thread(0) |
73 { |
91 { |
74 _all_active = true; |
92 _all_active = true; |
75 } |
93 } |
77 // Determines how many mutator threads can process the buffers in parallel. |
95 // Determines how many mutator threads can process the buffers in parallel. |
78 uint DirtyCardQueueSet::num_par_ids() { |
96 uint DirtyCardQueueSet::num_par_ids() { |
79 return (uint)os::processor_count(); |
97 return (uint)os::processor_count(); |
80 } |
98 } |
81 |
99 |
82 void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock, |
100 void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl, |
|
101 Monitor* cbl_mon, |
|
102 Mutex* fl_lock, |
83 int process_completed_threshold, |
103 int process_completed_threshold, |
84 int max_completed_queue, |
104 int max_completed_queue, |
85 Mutex* lock, PtrQueueSet* fl_owner) { |
105 Mutex* lock, |
|
106 DirtyCardQueueSet* fl_owner) { |
86 _mut_process_closure = cl; |
107 _mut_process_closure = cl; |
87 PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, |
108 PtrQueueSet::initialize(cbl_mon, |
88 max_completed_queue, fl_owner); |
109 fl_lock, |
|
110 process_completed_threshold, |
|
111 max_completed_queue, |
|
112 fl_owner); |
89 set_buffer_size(G1UpdateBufferSize); |
113 set_buffer_size(G1UpdateBufferSize); |
90 _shared_dirty_card_queue.set_lock(lock); |
114 _shared_dirty_card_queue.set_lock(lock); |
91 _free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon); |
115 _free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon); |
92 } |
116 } |
93 |
117 |
97 |
121 |
98 void DirtyCardQueueSet::iterate_closure_all_threads(CardTableEntryClosure* cl, |
122 void DirtyCardQueueSet::iterate_closure_all_threads(CardTableEntryClosure* cl, |
99 bool consume, |
123 bool consume, |
100 uint worker_i) { |
124 uint worker_i) { |
101 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); |
125 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); |
102 for(JavaThread* t = Threads::first(); t; t = t->next()) { |
126 for (JavaThread* t = Threads::first(); t; t = t->next()) { |
103 bool b = t->dirty_card_queue().apply_closure(cl, consume); |
127 bool b = t->dirty_card_queue().apply_closure(cl, consume); |
104 guarantee(b, "Should not be interrupted."); |
128 guarantee(b, "Should not be interrupted."); |
105 } |
129 } |
106 bool b = shared_dirty_card_queue()->apply_closure(cl, |
130 bool b = shared_dirty_card_queue()->apply_closure(cl, |
107 consume, |
131 consume, |
172 if (_completed_buffers_head == NULL) |
195 if (_completed_buffers_head == NULL) |
173 _completed_buffers_tail = NULL; |
196 _completed_buffers_tail = NULL; |
174 _n_completed_buffers--; |
197 _n_completed_buffers--; |
175 assert(_n_completed_buffers >= 0, "Invariant"); |
198 assert(_n_completed_buffers >= 0, "Invariant"); |
176 } |
199 } |
177 debug_only(assert_completed_buffer_list_len_correct_locked()); |
200 DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked()); |
178 return nd; |
201 return nd; |
179 } |
202 } |
180 |
203 |
181 bool DirtyCardQueueSet:: |
204 bool DirtyCardQueueSet::apply_closure_to_completed_buffer_helper(CardTableEntryClosure* cl, |
182 apply_closure_to_completed_buffer_helper(CardTableEntryClosure* cl, |
205 uint worker_i, |
183 uint worker_i, |
206 BufferNode* nd) { |
184 BufferNode* nd) { |
|
185 if (nd != NULL) { |
207 if (nd != NULL) { |
186 void **buf = BufferNode::make_buffer_from_node(nd); |
208 void **buf = BufferNode::make_buffer_from_node(nd); |
187 size_t index = nd->index(); |
209 size_t index = nd->index(); |
188 bool b = |
210 bool b = |
189 DirtyCardQueue::apply_closure_to_buffer(cl, buf, |
211 DirtyCardQueue::apply_closure_to_buffer(cl, buf, |
253 nd->set_next(buffers_to_delete); |
275 nd->set_next(buffers_to_delete); |
254 buffers_to_delete = nd; |
276 buffers_to_delete = nd; |
255 } |
277 } |
256 _n_completed_buffers = 0; |
278 _n_completed_buffers = 0; |
257 _completed_buffers_tail = NULL; |
279 _completed_buffers_tail = NULL; |
258 debug_only(assert_completed_buffer_list_len_correct_locked()); |
280 DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked()); |
259 } |
281 } |
260 while (buffers_to_delete != NULL) { |
282 while (buffers_to_delete != NULL) { |
261 BufferNode* nd = buffers_to_delete; |
283 BufferNode* nd = buffers_to_delete; |
262 buffers_to_delete = nd->next(); |
284 buffers_to_delete = nd->next(); |
263 deallocate_buffer(BufferNode::make_buffer_from_node(nd)); |
285 deallocate_buffer(BufferNode::make_buffer_from_node(nd)); |
285 _max_completed_queue = max_jint; |
307 _max_completed_queue = max_jint; |
286 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); |
308 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); |
287 for (JavaThread* t = Threads::first(); t; t = t->next()) { |
309 for (JavaThread* t = Threads::first(); t; t = t->next()) { |
288 DirtyCardQueue& dcq = t->dirty_card_queue(); |
310 DirtyCardQueue& dcq = t->dirty_card_queue(); |
289 if (dcq.size() != 0) { |
311 if (dcq.size() != 0) { |
290 void **buf = t->dirty_card_queue().get_buf(); |
312 void** buf = dcq.get_buf(); |
291 // We must NULL out the unused entries, then enqueue. |
313 // We must NULL out the unused entries, then enqueue. |
292 for (size_t i = 0; i < t->dirty_card_queue().get_index(); i += oopSize) { |
314 size_t limit = dcq.byte_index_to_index(dcq.get_index()); |
293 buf[PtrQueue::byte_index_to_index((int)i)] = NULL; |
315 for (size_t i = 0; i < limit; ++i) { |
|
316 buf[i] = NULL; |
294 } |
317 } |
295 enqueue_complete_buffer(dcq.get_buf(), dcq.get_index()); |
318 enqueue_complete_buffer(dcq.get_buf(), dcq.get_index()); |
296 dcq.reinitialize(); |
319 dcq.reinitialize(); |
297 } |
320 } |
298 } |
321 } |