annotate src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp @ 795:215f81b4d9b3

6841831: G1: assert(contains_reference(from),"We just added it!") fires Summary: During parallel rset updating we have to make sure that the worker ids of the refinement threads do not intersect with the worker ids that can be claimed by the mutator threads. Reviewed-by: tonyp
author iveresov
date Mon, 18 May 2009 11:52:46 -0700
parents 315a5d70b295
children bd02caa94611 27f6a9b9c311
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
1 /*
470
ad8c8ca4ab0f 6785258: Update copyright year
xdono
parents: 364
diff changeset
2 * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
4 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
7 * published by the Free Software Foundation.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
8 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
13 * accompanied this code).
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
14 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
18 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
21 * have any questions.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
22 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
23 */
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
24
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
25 # include "incls/_precompiled.incl"
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
26 # include "incls/_dirtyCardQueue.cpp.incl"
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
27
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
28 bool DirtyCardQueue::apply_closure(CardTableEntryClosure* cl,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
29 bool consume,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
30 size_t worker_i) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
31 bool res = true;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
32 if (_buf != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
33 res = apply_closure_to_buffer(cl, _buf, _index, _sz,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
34 consume,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
35 (int) worker_i);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
36 if (res && consume) _index = _sz;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
37 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
38 return res;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
39 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
40
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
41 bool DirtyCardQueue::apply_closure_to_buffer(CardTableEntryClosure* cl,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
42 void** buf,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
43 size_t index, size_t sz,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
44 bool consume,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
45 int worker_i) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
46 if (cl == NULL) return true;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
47 for (size_t i = index; i < sz; i += oopSize) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
48 int ind = byte_index_to_index((int)i);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
49 jbyte* card_ptr = (jbyte*)buf[ind];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
50 if (card_ptr != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
51 // Set the entry to null, so we don't do it again (via the test
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
52 // above) if we reconsider this buffer.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
53 if (consume) buf[ind] = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
54 if (!cl->do_card_ptr(card_ptr, worker_i)) return false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
55 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
56 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
57 return true;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
58 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
59
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
60 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
61 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
62 #endif // _MSC_VER
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
63
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
64 DirtyCardQueueSet::DirtyCardQueueSet() :
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
65 PtrQueueSet(true /*notify_when_complete*/),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
66 _closure(NULL),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
67 _shared_dirty_card_queue(this, true /*perm*/),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
68 _free_ids(NULL),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
69 _processed_buffers_mut(0), _processed_buffers_rs_thread(0)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
70 {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
71 _all_active = true;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
72 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
73
795
215f81b4d9b3 6841831: G1: assert(contains_reference(from),"We just added it!") fires
iveresov
parents: 794
diff changeset
74 // Determines how many mutator threads can process the buffers in parallel.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
75 size_t DirtyCardQueueSet::num_par_ids() {
795
215f81b4d9b3 6841831: G1: assert(contains_reference(from),"We just added it!") fires
iveresov
parents: 794
diff changeset
76 return os::processor_count();
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
77 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
78
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
79 void DirtyCardQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
80 int max_completed_queue,
616
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
81 Mutex* lock, PtrQueueSet* fl_owner) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 470
diff changeset
82 PtrQueueSet::initialize(cbl_mon, fl_lock, max_completed_queue, fl_owner);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
83 set_buffer_size(DCQBarrierQueueBufferSize);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
84 set_process_completed_threshold(DCQBarrierProcessCompletedThreshold);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
85
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
86 _shared_dirty_card_queue.set_lock(lock);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
87 _free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
88 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
89
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
90 void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
91 t->dirty_card_queue().handle_zero_index();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
92 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
93
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
94 void DirtyCardQueueSet::set_closure(CardTableEntryClosure* closure) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
95 _closure = closure;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
96 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
97
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
98 void DirtyCardQueueSet::iterate_closure_all_threads(bool consume,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
99 size_t worker_i) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
100 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
101 for(JavaThread* t = Threads::first(); t; t = t->next()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
102 bool b = t->dirty_card_queue().apply_closure(_closure, consume);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
103 guarantee(b, "Should not be interrupted.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
104 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
105 bool b = shared_dirty_card_queue()->apply_closure(_closure,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
106 consume,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
107 worker_i);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
108 guarantee(b, "Should not be interrupted.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
109 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
110
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
111 bool DirtyCardQueueSet::mut_process_buffer(void** buf) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
112
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
113 // Used to determine if we had already claimed a par_id
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
114 // before entering this method.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
115 bool already_claimed = false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
116
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
117 // We grab the current JavaThread.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
118 JavaThread* thread = JavaThread::current();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
119
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
120 // We get the the number of any par_id that this thread
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
121 // might have already claimed.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
122 int worker_i = thread->get_claimed_par_id();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
123
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
124 // If worker_i is not -1 then the thread has already claimed
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
125 // a par_id. We make note of it using the already_claimed value
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
126 if (worker_i != -1) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
127 already_claimed = true;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
128 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
129
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
130 // Otherwise we need to claim a par id
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
131 worker_i = _free_ids->claim_par_id();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
132
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
133 // And store the par_id value in the thread
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
134 thread->set_claimed_par_id(worker_i);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
135 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
136
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
137 bool b = false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
138 if (worker_i != -1) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
139 b = DirtyCardQueue::apply_closure_to_buffer(_closure, buf, 0,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
140 _sz, true, worker_i);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
141 if (b) Atomic::inc(&_processed_buffers_mut);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
142
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
143 // If we had not claimed an id before entering the method
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
144 // then we must release the id.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
145 if (!already_claimed) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
146
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
147 // we release the id
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
148 _free_ids->release_par_id(worker_i);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
149
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
150 // and set the claimed_id in the thread to -1
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
151 thread->set_claimed_par_id(-1);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
152 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
153 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
154 return b;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
155 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
156
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
157 DirtyCardQueueSet::CompletedBufferNode*
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
158 DirtyCardQueueSet::get_completed_buffer_lock(int stop_at) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
159 CompletedBufferNode* nd = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
160 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
161
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
162 if ((int)_n_completed_buffers <= stop_at) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
163 _process_completed = false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
164 return NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
165 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
166
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
167 if (_completed_buffers_head != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
168 nd = _completed_buffers_head;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
169 _completed_buffers_head = nd->next;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
170 if (_completed_buffers_head == NULL)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
171 _completed_buffers_tail = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
172 _n_completed_buffers--;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
173 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
174 debug_only(assert_completed_buffer_list_len_correct_locked());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
175 return nd;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
176 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
177
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
178 // We only do this in contexts where there is no concurrent enqueueing.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
179 DirtyCardQueueSet::CompletedBufferNode*
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
180 DirtyCardQueueSet::get_completed_buffer_CAS() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
181 CompletedBufferNode* nd = _completed_buffers_head;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
182
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
183 while (nd != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
184 CompletedBufferNode* next = nd->next;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
185 CompletedBufferNode* result =
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
186 (CompletedBufferNode*)Atomic::cmpxchg_ptr(next,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
187 &_completed_buffers_head,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
188 nd);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
189 if (result == nd) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
190 return result;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
191 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
192 nd = _completed_buffers_head;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
193 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
194 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
195 assert(_completed_buffers_head == NULL, "Loop post");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
196 _completed_buffers_tail = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
197 return NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
198 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
199
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
200 bool DirtyCardQueueSet::
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
201 apply_closure_to_completed_buffer_helper(int worker_i,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
202 CompletedBufferNode* nd) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
203 if (nd != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
204 bool b =
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
205 DirtyCardQueue::apply_closure_to_buffer(_closure, nd->buf,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
206 nd->index, _sz,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
207 true, worker_i);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
208 void** buf = nd->buf;
364
919e7959392a 6742641: G1: NullPointerException during GCOld
tonyp
parents: 342
diff changeset
209 size_t index = nd->index;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
210 delete nd;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
211 if (b) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
212 deallocate_buffer(buf);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
213 return true; // In normal case, go on to next buffer.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
214 } else {
364
919e7959392a 6742641: G1: NullPointerException during GCOld
tonyp
parents: 342
diff changeset
215 enqueue_complete_buffer(buf, index, true);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
216 return false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
217 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
218 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
219 return false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
220 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
221 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
222
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
223 bool DirtyCardQueueSet::apply_closure_to_completed_buffer(int worker_i,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
224 int stop_at,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
225 bool with_CAS)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
226 {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
227 CompletedBufferNode* nd = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
228 if (with_CAS) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
229 guarantee(stop_at == 0, "Precondition");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
230 nd = get_completed_buffer_CAS();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
231 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
232 nd = get_completed_buffer_lock(stop_at);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
233 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
234 bool res = apply_closure_to_completed_buffer_helper(worker_i, nd);
794
315a5d70b295 6484957: G1: parallel concurrent refinement
iveresov
parents: 616
diff changeset
235 if (res) Atomic::inc(&_processed_buffers_rs_thread);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
236 return res;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
237 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
238
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
239 void DirtyCardQueueSet::apply_closure_to_all_completed_buffers() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
240 CompletedBufferNode* nd = _completed_buffers_head;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
241 while (nd != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
242 bool b =
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
243 DirtyCardQueue::apply_closure_to_buffer(_closure, nd->buf, 0, _sz,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
244 false);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
245 guarantee(b, "Should not stop early.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
246 nd = nd->next;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
247 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
248 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
249
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
250 void DirtyCardQueueSet::abandon_logs() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
251 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
252 CompletedBufferNode* buffers_to_delete = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
253 {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
254 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
255 while (_completed_buffers_head != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
256 CompletedBufferNode* nd = _completed_buffers_head;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
257 _completed_buffers_head = nd->next;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
258 nd->next = buffers_to_delete;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
259 buffers_to_delete = nd;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
260 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
261 _n_completed_buffers = 0;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
262 _completed_buffers_tail = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
263 debug_only(assert_completed_buffer_list_len_correct_locked());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
264 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
265 while (buffers_to_delete != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
266 CompletedBufferNode* nd = buffers_to_delete;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
267 buffers_to_delete = nd->next;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
268 deallocate_buffer(nd->buf);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
269 delete nd;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
270 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
271 // Since abandon is done only at safepoints, we can safely manipulate
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
272 // these queues.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
273 for (JavaThread* t = Threads::first(); t; t = t->next()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
274 t->dirty_card_queue().reset();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
275 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
276 shared_dirty_card_queue()->reset();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
277 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
278
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
279
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
280 void DirtyCardQueueSet::concatenate_logs() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
281 // Iterate over all the threads, if we find a partial log add it to
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
282 // the global list of logs. Temporarily turn off the limit on the number
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
283 // of outstanding buffers.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
284 int save_max_completed_queue = _max_completed_queue;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
285 _max_completed_queue = max_jint;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
286 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
287 for (JavaThread* t = Threads::first(); t; t = t->next()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
288 DirtyCardQueue& dcq = t->dirty_card_queue();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
289 if (dcq.size() != 0) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
290 void **buf = t->dirty_card_queue().get_buf();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
291 // We must NULL out the unused entries, then enqueue.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
292 for (size_t i = 0; i < t->dirty_card_queue().get_index(); i += oopSize) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
293 buf[PtrQueue::byte_index_to_index((int)i)] = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
294 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
295 enqueue_complete_buffer(dcq.get_buf(), dcq.get_index());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
296 dcq.reinitialize();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
297 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
298 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
299 if (_shared_dirty_card_queue.size() != 0) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
300 enqueue_complete_buffer(_shared_dirty_card_queue.get_buf(),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
301 _shared_dirty_card_queue.get_index());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
302 _shared_dirty_card_queue.reinitialize();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
303 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
304 // Restore the completed buffer queue limit.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
305 _max_completed_queue = save_max_completed_queue;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
306 }