Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp @ 20804:7848fc12602b
Merge with jdk8u40-b25
author | Gilles Duboscq <gilles.m.duboscq@oracle.com> |
---|---|
date | Tue, 07 Apr 2015 14:58:49 +0200 |
parents | 570cb6369f17 |
children |
comparison
equal
deleted
inserted
replaced
20184:84105dcdb05b | 20804:7848fc12602b |
---|---|
68 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list | 68 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list |
69 #endif // _MSC_VER | 69 #endif // _MSC_VER |
70 | 70 |
71 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) : | 71 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) : |
72 PtrQueueSet(notify_when_complete), | 72 PtrQueueSet(notify_when_complete), |
73 _closure(NULL), | 73 _mut_process_closure(NULL), |
74 _shared_dirty_card_queue(this, true /*perm*/), | 74 _shared_dirty_card_queue(this, true /*perm*/), |
75 _free_ids(NULL), | 75 _free_ids(NULL), |
76 _processed_buffers_mut(0), _processed_buffers_rs_thread(0) | 76 _processed_buffers_mut(0), _processed_buffers_rs_thread(0) |
77 { | 77 { |
78 _all_active = true; | 78 _all_active = true; |
81 // Determines how many mutator threads can process the buffers in parallel. | 81 // Determines how many mutator threads can process the buffers in parallel. |
82 uint DirtyCardQueueSet::num_par_ids() { | 82 uint DirtyCardQueueSet::num_par_ids() { |
83 return (uint)os::processor_count(); | 83 return (uint)os::processor_count(); |
84 } | 84 } |
85 | 85 |
86 void DirtyCardQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock, | 86 void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock, |
87 int process_completed_threshold, | 87 int process_completed_threshold, |
88 int max_completed_queue, | 88 int max_completed_queue, |
89 Mutex* lock, PtrQueueSet* fl_owner) { | 89 Mutex* lock, PtrQueueSet* fl_owner) { |
90 _mut_process_closure = cl; | |
90 PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, | 91 PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, |
91 max_completed_queue, fl_owner); | 92 max_completed_queue, fl_owner); |
92 set_buffer_size(G1UpdateBufferSize); | 93 set_buffer_size(G1UpdateBufferSize); |
93 _shared_dirty_card_queue.set_lock(lock); | 94 _shared_dirty_card_queue.set_lock(lock); |
94 _free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon); | 95 _free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon); |
96 | 97 |
97 void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) { | 98 void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) { |
98 t->dirty_card_queue().handle_zero_index(); | 99 t->dirty_card_queue().handle_zero_index(); |
99 } | 100 } |
100 | 101 |
101 void DirtyCardQueueSet::set_closure(CardTableEntryClosure* closure) { | 102 void DirtyCardQueueSet::iterate_closure_all_threads(CardTableEntryClosure* cl, |
102 _closure = closure; | 103 bool consume, |
103 } | |
104 | |
105 void DirtyCardQueueSet::iterate_closure_all_threads(bool consume, | |
106 uint worker_i) { | 104 uint worker_i) { |
107 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); | 105 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); |
108 for(JavaThread* t = Threads::first(); t; t = t->next()) { | 106 for(JavaThread* t = Threads::first(); t; t = t->next()) { |
109 bool b = t->dirty_card_queue().apply_closure(_closure, consume); | 107 bool b = t->dirty_card_queue().apply_closure(cl, consume); |
110 guarantee(b, "Should not be interrupted."); | 108 guarantee(b, "Should not be interrupted."); |
111 } | 109 } |
112 bool b = shared_dirty_card_queue()->apply_closure(_closure, | 110 bool b = shared_dirty_card_queue()->apply_closure(cl, |
113 consume, | 111 consume, |
114 worker_i); | 112 worker_i); |
115 guarantee(b, "Should not be interrupted."); | 113 guarantee(b, "Should not be interrupted."); |
116 } | 114 } |
117 | 115 |
141 thread->set_claimed_par_id(worker_i); | 139 thread->set_claimed_par_id(worker_i); |
142 } | 140 } |
143 | 141 |
144 bool b = false; | 142 bool b = false; |
145 if (worker_i != UINT_MAX) { | 143 if (worker_i != UINT_MAX) { |
146 b = DirtyCardQueue::apply_closure_to_buffer(_closure, buf, 0, | 144 b = DirtyCardQueue::apply_closure_to_buffer(_mut_process_closure, buf, 0, |
147 _sz, true, worker_i); | 145 _sz, true, worker_i); |
148 if (b) Atomic::inc(&_processed_buffers_mut); | 146 if (b) Atomic::inc(&_processed_buffers_mut); |
149 | 147 |
150 // If we had not claimed an id before entering the method | 148 // If we had not claimed an id before entering the method |
151 // then we must release the id. | 149 // then we must release the id. |
216 bool res = apply_closure_to_completed_buffer_helper(cl, worker_i, nd); | 214 bool res = apply_closure_to_completed_buffer_helper(cl, worker_i, nd); |
217 if (res) Atomic::inc(&_processed_buffers_rs_thread); | 215 if (res) Atomic::inc(&_processed_buffers_rs_thread); |
218 return res; | 216 return res; |
219 } | 217 } |
220 | 218 |
221 bool DirtyCardQueueSet::apply_closure_to_completed_buffer(uint worker_i, | 219 void DirtyCardQueueSet::apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl) { |
222 int stop_at, | |
223 bool during_pause) { | |
224 return apply_closure_to_completed_buffer(_closure, worker_i, | |
225 stop_at, during_pause); | |
226 } | |
227 | |
228 void DirtyCardQueueSet::apply_closure_to_all_completed_buffers() { | |
229 BufferNode* nd = _completed_buffers_head; | 220 BufferNode* nd = _completed_buffers_head; |
230 while (nd != NULL) { | 221 while (nd != NULL) { |
231 bool b = | 222 bool b = |
232 DirtyCardQueue::apply_closure_to_buffer(_closure, | 223 DirtyCardQueue::apply_closure_to_buffer(cl, |
233 BufferNode::make_buffer_from_node(nd), | 224 BufferNode::make_buffer_from_node(nd), |
234 0, _sz, false); | 225 0, _sz, false); |
235 guarantee(b, "Should not stop early."); | 226 guarantee(b, "Should not stop early."); |
236 nd = nd->next(); | 227 nd = nd->next(); |
228 } | |
229 } | |
230 | |
231 void DirtyCardQueueSet::par_apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl) { | |
232 BufferNode* nd = _cur_par_buffer_node; | |
233 while (nd != NULL) { | |
234 BufferNode* next = (BufferNode*)nd->next(); | |
235 BufferNode* actual = (BufferNode*)Atomic::cmpxchg_ptr((void*)next, (volatile void*)&_cur_par_buffer_node, (void*)nd); | |
236 if (actual == nd) { | |
237 bool b = | |
238 DirtyCardQueue::apply_closure_to_buffer(cl, | |
239 BufferNode::make_buffer_from_node(actual), | |
240 0, _sz, false); | |
241 guarantee(b, "Should not stop early."); | |
242 nd = next; | |
243 } else { | |
244 nd = actual; | |
245 } | |
237 } | 246 } |
238 } | 247 } |
239 | 248 |
240 // Deallocates any completed log buffers | 249 // Deallocates any completed log buffers |
241 void DirtyCardQueueSet::clear() { | 250 void DirtyCardQueueSet::clear() { |