Tue, 23 Nov 2010 13:22:55 -0800
6989984: Use standard include model for Hospot
Summary: Replaced MakeDeps and the includeDB files with more standardized solutions.
Reviewed-by: coleenp, kvn, kamg
1 /*
2 * Copyright (c) 2007, 2010 Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
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 */
25 #include "precompiled.hpp"
26 #include "memory/allocation.inline.hpp"
27 #include "memory/cardTableModRefBS.hpp"
28 #include "memory/cardTableRS.hpp"
29 #include "memory/sharedHeap.hpp"
30 #include "memory/space.inline.hpp"
31 #include "memory/universe.hpp"
32 #include "runtime/java.hpp"
33 #include "runtime/mutexLocker.hpp"
34 #include "runtime/virtualspace.hpp"
36 void CardTableModRefBS::par_non_clean_card_iterate_work(Space* sp, MemRegion mr,
37 DirtyCardToOopClosure* dcto_cl,
38 MemRegionClosure* cl,
39 bool clear,
40 int n_threads) {
41 if (n_threads > 0) {
42 assert((n_threads == 1 && ParallelGCThreads == 0) ||
43 n_threads <= (int)ParallelGCThreads,
44 "# worker threads != # requested!");
45 // Make sure the LNC array is valid for the space.
46 jbyte** lowest_non_clean;
47 uintptr_t lowest_non_clean_base_chunk_index;
48 size_t lowest_non_clean_chunk_size;
49 get_LNC_array_for_space(sp, lowest_non_clean,
50 lowest_non_clean_base_chunk_index,
51 lowest_non_clean_chunk_size);
53 int n_strides = n_threads * StridesPerThread;
54 SequentialSubTasksDone* pst = sp->par_seq_tasks();
55 pst->set_n_threads(n_threads);
56 pst->set_n_tasks(n_strides);
58 int stride = 0;
59 while (!pst->is_task_claimed(/* reference */ stride)) {
60 process_stride(sp, mr, stride, n_strides, dcto_cl, cl, clear,
61 lowest_non_clean,
62 lowest_non_clean_base_chunk_index,
63 lowest_non_clean_chunk_size);
64 }
65 if (pst->all_tasks_completed()) {
66 // Clear lowest_non_clean array for next time.
67 intptr_t first_chunk_index = addr_to_chunk_index(mr.start());
68 uintptr_t last_chunk_index = addr_to_chunk_index(mr.last());
69 for (uintptr_t ch = first_chunk_index; ch <= last_chunk_index; ch++) {
70 intptr_t ind = ch - lowest_non_clean_base_chunk_index;
71 assert(0 <= ind && ind < (intptr_t)lowest_non_clean_chunk_size,
72 "Bounds error");
73 lowest_non_clean[ind] = NULL;
74 }
75 }
76 }
77 }
79 void
80 CardTableModRefBS::
81 process_stride(Space* sp,
82 MemRegion used,
83 jint stride, int n_strides,
84 DirtyCardToOopClosure* dcto_cl,
85 MemRegionClosure* cl,
86 bool clear,
87 jbyte** lowest_non_clean,
88 uintptr_t lowest_non_clean_base_chunk_index,
89 size_t lowest_non_clean_chunk_size) {
90 // We don't have to go downwards here; it wouldn't help anyway,
91 // because of parallelism.
93 // Find the first card address of the first chunk in the stride that is
94 // at least "bottom" of the used region.
95 jbyte* start_card = byte_for(used.start());
96 jbyte* end_card = byte_after(used.last());
97 uintptr_t start_chunk = addr_to_chunk_index(used.start());
98 uintptr_t start_chunk_stride_num = start_chunk % n_strides;
99 jbyte* chunk_card_start;
101 if ((uintptr_t)stride >= start_chunk_stride_num) {
102 chunk_card_start = (jbyte*)(start_card +
103 (stride - start_chunk_stride_num) *
104 CardsPerStrideChunk);
105 } else {
106 // Go ahead to the next chunk group boundary, then to the requested stride.
107 chunk_card_start = (jbyte*)(start_card +
108 (n_strides - start_chunk_stride_num + stride) *
109 CardsPerStrideChunk);
110 }
112 while (chunk_card_start < end_card) {
113 // We don't have to go downwards here; it wouldn't help anyway,
114 // because of parallelism. (We take care with "min_done"; see below.)
115 // Invariant: chunk_mr should be fully contained within the "used" region.
116 jbyte* chunk_card_end = chunk_card_start + CardsPerStrideChunk;
117 MemRegion chunk_mr = MemRegion(addr_for(chunk_card_start),
118 chunk_card_end >= end_card ?
119 used.end() : addr_for(chunk_card_end));
120 assert(chunk_mr.word_size() > 0, "[chunk_card_start > used_end)");
121 assert(used.contains(chunk_mr), "chunk_mr should be subset of used");
123 // Process the chunk.
124 process_chunk_boundaries(sp,
125 dcto_cl,
126 chunk_mr,
127 used,
128 lowest_non_clean,
129 lowest_non_clean_base_chunk_index,
130 lowest_non_clean_chunk_size);
132 non_clean_card_iterate_work(chunk_mr, cl, clear);
134 // Find the next chunk of the stride.
135 chunk_card_start += CardsPerStrideChunk * n_strides;
136 }
137 }
139 void
140 CardTableModRefBS::
141 process_chunk_boundaries(Space* sp,
142 DirtyCardToOopClosure* dcto_cl,
143 MemRegion chunk_mr,
144 MemRegion used,
145 jbyte** lowest_non_clean,
146 uintptr_t lowest_non_clean_base_chunk_index,
147 size_t lowest_non_clean_chunk_size)
148 {
149 // We must worry about the chunk boundaries.
151 // First, set our max_to_do:
152 HeapWord* max_to_do = NULL;
153 uintptr_t cur_chunk_index = addr_to_chunk_index(chunk_mr.start());
154 cur_chunk_index = cur_chunk_index - lowest_non_clean_base_chunk_index;
156 if (chunk_mr.end() < used.end()) {
157 // This is not the last chunk in the used region. What is the last
158 // object?
159 HeapWord* last_block = sp->block_start(chunk_mr.end());
160 assert(last_block <= chunk_mr.end(), "In case this property changes.");
161 if (last_block == chunk_mr.end()
162 || !sp->block_is_obj(last_block)) {
163 max_to_do = chunk_mr.end();
165 } else {
166 // It is an object and starts before the end of the current chunk.
167 // last_obj_card is the card corresponding to the start of the last object
168 // in the chunk. Note that the last object may not start in
169 // the chunk.
170 jbyte* last_obj_card = byte_for(last_block);
171 if (!card_may_have_been_dirty(*last_obj_card)) {
172 // The card containing the head is not dirty. Any marks in
173 // subsequent cards still in this chunk must have been made
174 // precisely; we can cap processing at the end.
175 max_to_do = chunk_mr.end();
176 } else {
177 // The last object must be considered dirty, and extends onto the
178 // following chunk. Look for a dirty card in that chunk that will
179 // bound our processing.
180 jbyte* limit_card = NULL;
181 size_t last_block_size = sp->block_size(last_block);
182 jbyte* last_card_of_last_obj =
183 byte_for(last_block + last_block_size - 1);
184 jbyte* first_card_of_next_chunk = byte_for(chunk_mr.end());
185 // This search potentially goes a long distance looking
186 // for the next card that will be scanned. For example,
187 // an object that is an array of primitives will not
188 // have any cards covering regions interior to the array
189 // that will need to be scanned. The scan can be terminated
190 // at the last card of the next chunk. That would leave
191 // limit_card as NULL and would result in "max_to_do"
192 // being set with the LNC value or with the end
193 // of the last block.
194 jbyte* last_card_of_next_chunk = first_card_of_next_chunk +
195 CardsPerStrideChunk;
196 assert(byte_for(chunk_mr.end()) - byte_for(chunk_mr.start())
197 == CardsPerStrideChunk, "last card of next chunk may be wrong");
198 jbyte* last_card_to_check = (jbyte*) MIN2(last_card_of_last_obj,
199 last_card_of_next_chunk);
200 for (jbyte* cur = first_card_of_next_chunk;
201 cur <= last_card_to_check; cur++) {
202 if (card_will_be_scanned(*cur)) {
203 limit_card = cur; break;
204 }
205 }
206 assert(0 <= cur_chunk_index+1 &&
207 cur_chunk_index+1 < lowest_non_clean_chunk_size,
208 "Bounds error.");
209 // LNC for the next chunk
210 jbyte* lnc_card = lowest_non_clean[cur_chunk_index+1];
211 if (limit_card == NULL) {
212 limit_card = lnc_card;
213 }
214 if (limit_card != NULL) {
215 if (lnc_card != NULL) {
216 limit_card = (jbyte*)MIN2((intptr_t)limit_card,
217 (intptr_t)lnc_card);
218 }
219 max_to_do = addr_for(limit_card);
220 } else {
221 max_to_do = last_block + last_block_size;
222 }
223 }
224 }
225 assert(max_to_do != NULL, "OOPS!");
226 } else {
227 max_to_do = used.end();
228 }
229 // Now we can set the closure we're using so it doesn't to beyond
230 // max_to_do.
231 dcto_cl->set_min_done(max_to_do);
232 #ifndef PRODUCT
233 dcto_cl->set_last_bottom(max_to_do);
234 #endif
236 // Now we set *our" lowest_non_clean entry.
237 // Find the object that spans our boundary, if one exists.
238 // Nothing to do on the first chunk.
239 if (chunk_mr.start() > used.start()) {
240 // first_block is the block possibly spanning the chunk start
241 HeapWord* first_block = sp->block_start(chunk_mr.start());
242 // Does the block span the start of the chunk and is it
243 // an object?
244 if (first_block < chunk_mr.start() &&
245 sp->block_is_obj(first_block)) {
246 jbyte* first_dirty_card = NULL;
247 jbyte* last_card_of_first_obj =
248 byte_for(first_block + sp->block_size(first_block) - 1);
249 jbyte* first_card_of_cur_chunk = byte_for(chunk_mr.start());
250 jbyte* last_card_of_cur_chunk = byte_for(chunk_mr.last());
251 jbyte* last_card_to_check =
252 (jbyte*) MIN2((intptr_t) last_card_of_cur_chunk,
253 (intptr_t) last_card_of_first_obj);
254 for (jbyte* cur = first_card_of_cur_chunk;
255 cur <= last_card_to_check; cur++) {
256 if (card_will_be_scanned(*cur)) {
257 first_dirty_card = cur; break;
258 }
259 }
260 if (first_dirty_card != NULL) {
261 assert(0 <= cur_chunk_index &&
262 cur_chunk_index < lowest_non_clean_chunk_size,
263 "Bounds error.");
264 lowest_non_clean[cur_chunk_index] = first_dirty_card;
265 }
266 }
267 }
268 }
270 void
271 CardTableModRefBS::
272 get_LNC_array_for_space(Space* sp,
273 jbyte**& lowest_non_clean,
274 uintptr_t& lowest_non_clean_base_chunk_index,
275 size_t& lowest_non_clean_chunk_size) {
277 int i = find_covering_region_containing(sp->bottom());
278 MemRegion covered = _covered[i];
279 size_t n_chunks = chunks_to_cover(covered);
281 // Only the first thread to obtain the lock will resize the
282 // LNC array for the covered region. Any later expansion can't affect
283 // the used_at_save_marks region.
284 // (I observed a bug in which the first thread to execute this would
285 // resize, and then it would cause "expand_and_allocates" that would
286 // Increase the number of chunks in the covered region. Then a second
287 // thread would come and execute this, see that the size didn't match,
288 // and free and allocate again. So the first thread would be using a
289 // freed "_lowest_non_clean" array.)
291 // Do a dirty read here. If we pass the conditional then take the rare
292 // event lock and do the read again in case some other thread had already
293 // succeeded and done the resize.
294 int cur_collection = Universe::heap()->total_collections();
295 if (_last_LNC_resizing_collection[i] != cur_collection) {
296 MutexLocker x(ParGCRareEvent_lock);
297 if (_last_LNC_resizing_collection[i] != cur_collection) {
298 if (_lowest_non_clean[i] == NULL ||
299 n_chunks != _lowest_non_clean_chunk_size[i]) {
301 // Should we delete the old?
302 if (_lowest_non_clean[i] != NULL) {
303 assert(n_chunks != _lowest_non_clean_chunk_size[i],
304 "logical consequence");
305 FREE_C_HEAP_ARRAY(CardPtr, _lowest_non_clean[i]);
306 _lowest_non_clean[i] = NULL;
307 }
308 // Now allocate a new one if necessary.
309 if (_lowest_non_clean[i] == NULL) {
310 _lowest_non_clean[i] = NEW_C_HEAP_ARRAY(CardPtr, n_chunks);
311 _lowest_non_clean_chunk_size[i] = n_chunks;
312 _lowest_non_clean_base_chunk_index[i] = addr_to_chunk_index(covered.start());
313 for (int j = 0; j < (int)n_chunks; j++)
314 _lowest_non_clean[i][j] = NULL;
315 }
316 }
317 _last_LNC_resizing_collection[i] = cur_collection;
318 }
319 }
320 // In any case, now do the initialization.
321 lowest_non_clean = _lowest_non_clean[i];
322 lowest_non_clean_base_chunk_index = _lowest_non_clean_base_chunk_index[i];
323 lowest_non_clean_chunk_size = _lowest_non_clean_chunk_size[i];
324 }