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 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/g1/dirtyCardQueue.hpp"
27 #include "gc/g1/g1CollectedHeap.inline.hpp"
28 #include "gc/g1/g1RemSet.hpp"
29 #include "gc/g1/heapRegionRemSet.hpp"
30 #include "gc/shared/workgroup.hpp"
31 #include "runtime/atomic.hpp"
32 #include "runtime/mutexLocker.hpp"
33 #include "runtime/safepoint.hpp"
34 #include "runtime/thread.inline.hpp"
35 #include "runtime/threadSMR.hpp"
36
37 // Closure used for updating remembered sets and recording references that
38 // point into the collection set while the mutator is running.
39 // Assumed to be only executed concurrently with the mutator. Yields via
40 // SuspendibleThreadSet after every card.
41 class G1RefineCardConcurrentlyClosure: public CardTableEntryClosure {
42 public:
43 bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
44 G1CollectedHeap::heap()->g1_rem_set()->refine_card_concurrently(card_ptr, worker_i);
45
46 if (SuspendibleThreadSet::should_yield()) {
47 // Caller will actually yield.
48 return false;
147 void DirtyCardQueueSet::initialize(Monitor* cbl_mon,
148 Mutex* fl_lock,
149 int process_completed_threshold,
150 int max_completed_queue,
151 Mutex* lock,
152 DirtyCardQueueSet* fl_owner,
153 bool init_free_ids) {
154 PtrQueueSet::initialize(cbl_mon,
155 fl_lock,
156 process_completed_threshold,
157 max_completed_queue,
158 fl_owner);
159 set_buffer_size(G1UpdateBufferSize);
160 _shared_dirty_card_queue.set_lock(lock);
161 if (init_free_ids) {
162 _free_ids = new FreeIdSet(num_par_ids(), _cbl_mon);
163 }
164 }
165
166 void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
167 t->dirty_card_queue().handle_zero_index();
168 }
169
170 bool DirtyCardQueueSet::apply_closure_to_buffer(CardTableEntryClosure* cl,
171 BufferNode* node,
172 bool consume,
173 uint worker_i) {
174 if (cl == NULL) return true;
175 bool result = true;
176 void** buf = BufferNode::make_buffer_from_node(node);
177 size_t i = node->index();
178 size_t limit = buffer_size();
179 for ( ; i < limit; ++i) {
180 jbyte* card_ptr = static_cast<jbyte*>(buf[i]);
181 assert(card_ptr != NULL, "invariant");
182 if (!cl->do_card_ptr(card_ptr, worker_i)) {
183 result = false; // Incomplete processing.
184 break;
185 }
186 }
187 if (consume) {
304 buffers_to_delete = nd;
305 }
306 _n_completed_buffers = 0;
307 _completed_buffers_tail = NULL;
308 DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
309 }
310 while (buffers_to_delete != NULL) {
311 BufferNode* nd = buffers_to_delete;
312 buffers_to_delete = nd->next();
313 deallocate_buffer(nd);
314 }
315
316 }
317
318 void DirtyCardQueueSet::abandon_logs() {
319 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
320 clear();
321 // Since abandon is done only at safepoints, we can safely manipulate
322 // these queues.
323 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
324 t->dirty_card_queue().reset();
325 }
326 shared_dirty_card_queue()->reset();
327 }
328
329 void DirtyCardQueueSet::concatenate_log(DirtyCardQueue& dcq) {
330 if (!dcq.is_empty()) {
331 dcq.flush();
332 }
333 }
334
335 void DirtyCardQueueSet::concatenate_logs() {
336 // Iterate over all the threads, if we find a partial log add it to
337 // the global list of logs. Temporarily turn off the limit on the number
338 // of outstanding buffers.
339 int save_max_completed_queue = _max_completed_queue;
340 _max_completed_queue = max_jint;
341 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
342 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
343 concatenate_log(t->dirty_card_queue());
344 }
345 concatenate_log(_shared_dirty_card_queue);
346 // Restore the completed buffer queue limit.
347 _max_completed_queue = save_max_completed_queue;
348 }
|
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 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/g1/dirtyCardQueue.hpp"
27 #include "gc/g1/g1CollectedHeap.inline.hpp"
28 #include "gc/g1/g1RemSet.hpp"
29 #include "gc/g1/g1ThreadLocalData.hpp"
30 #include "gc/g1/heapRegionRemSet.hpp"
31 #include "gc/shared/workgroup.hpp"
32 #include "runtime/atomic.hpp"
33 #include "runtime/mutexLocker.hpp"
34 #include "runtime/safepoint.hpp"
35 #include "runtime/thread.inline.hpp"
36 #include "runtime/threadSMR.hpp"
37
38 // Closure used for updating remembered sets and recording references that
39 // point into the collection set while the mutator is running.
40 // Assumed to be only executed concurrently with the mutator. Yields via
41 // SuspendibleThreadSet after every card.
42 class G1RefineCardConcurrentlyClosure: public CardTableEntryClosure {
43 public:
44 bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
45 G1CollectedHeap::heap()->g1_rem_set()->refine_card_concurrently(card_ptr, worker_i);
46
47 if (SuspendibleThreadSet::should_yield()) {
48 // Caller will actually yield.
49 return false;
148 void DirtyCardQueueSet::initialize(Monitor* cbl_mon,
149 Mutex* fl_lock,
150 int process_completed_threshold,
151 int max_completed_queue,
152 Mutex* lock,
153 DirtyCardQueueSet* fl_owner,
154 bool init_free_ids) {
155 PtrQueueSet::initialize(cbl_mon,
156 fl_lock,
157 process_completed_threshold,
158 max_completed_queue,
159 fl_owner);
160 set_buffer_size(G1UpdateBufferSize);
161 _shared_dirty_card_queue.set_lock(lock);
162 if (init_free_ids) {
163 _free_ids = new FreeIdSet(num_par_ids(), _cbl_mon);
164 }
165 }
166
167 void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
168 G1ThreadLocalData::dirty_card_queue(t).handle_zero_index();
169 }
170
171 bool DirtyCardQueueSet::apply_closure_to_buffer(CardTableEntryClosure* cl,
172 BufferNode* node,
173 bool consume,
174 uint worker_i) {
175 if (cl == NULL) return true;
176 bool result = true;
177 void** buf = BufferNode::make_buffer_from_node(node);
178 size_t i = node->index();
179 size_t limit = buffer_size();
180 for ( ; i < limit; ++i) {
181 jbyte* card_ptr = static_cast<jbyte*>(buf[i]);
182 assert(card_ptr != NULL, "invariant");
183 if (!cl->do_card_ptr(card_ptr, worker_i)) {
184 result = false; // Incomplete processing.
185 break;
186 }
187 }
188 if (consume) {
305 buffers_to_delete = nd;
306 }
307 _n_completed_buffers = 0;
308 _completed_buffers_tail = NULL;
309 DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
310 }
311 while (buffers_to_delete != NULL) {
312 BufferNode* nd = buffers_to_delete;
313 buffers_to_delete = nd->next();
314 deallocate_buffer(nd);
315 }
316
317 }
318
319 void DirtyCardQueueSet::abandon_logs() {
320 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
321 clear();
322 // Since abandon is done only at safepoints, we can safely manipulate
323 // these queues.
324 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
325 G1ThreadLocalData::dirty_card_queue(t).reset();
326 }
327 shared_dirty_card_queue()->reset();
328 }
329
330 void DirtyCardQueueSet::concatenate_log(DirtyCardQueue& dcq) {
331 if (!dcq.is_empty()) {
332 dcq.flush();
333 }
334 }
335
336 void DirtyCardQueueSet::concatenate_logs() {
337 // Iterate over all the threads, if we find a partial log add it to
338 // the global list of logs. Temporarily turn off the limit on the number
339 // of outstanding buffers.
340 int save_max_completed_queue = _max_completed_queue;
341 _max_completed_queue = max_jint;
342 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
343 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
344 concatenate_log(G1ThreadLocalData::dirty_card_queue(t));
345 }
346 concatenate_log(_shared_dirty_card_queue);
347 // Restore the completed buffer queue limit.
348 _max_completed_queue = save_max_completed_queue;
349 }
|