annotate src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp @ 1951:899bbbdcb6ea

6997298: fatal error: must own lock CMS_markBitMap_lock during heap dump Summary: Since we are at a stop-world pause, the existing CMS-phase checks are sufficient for safety, and the locking check can be safely elided. Elaborated documentation comment to the case where class unloading and verification are disabled, and the query happens when we aren't in the sweeping phase, where the answer "false" would be (almost everywhere) too pessimistic. Reviewed-by: jmasa, johnc, tonyp
author ysr
date Fri, 05 Nov 2010 13:20:37 -0700
parents 8b10f48633dc
children f95d63e2154a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
2 * Copyright (c) 2007, 2010 Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 845
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 845
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 845
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_parCardTableModRefBS.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 void CardTableModRefBS::par_non_clean_card_iterate_work(Space* sp, MemRegion mr,
a61af66fc99e Initial load
duke
parents:
diff changeset
29 DirtyCardToOopClosure* dcto_cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
30 MemRegionClosure* cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
31 bool clear,
a61af66fc99e Initial load
duke
parents:
diff changeset
32 int n_threads) {
a61af66fc99e Initial load
duke
parents:
diff changeset
33 if (n_threads > 0) {
845
df6caf649ff7 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 0
diff changeset
34 assert((n_threads == 1 && ParallelGCThreads == 0) ||
df6caf649ff7 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 0
diff changeset
35 n_threads <= (int)ParallelGCThreads,
df6caf649ff7 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 0
diff changeset
36 "# worker threads != # requested!");
df6caf649ff7 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 0
diff changeset
37 // Make sure the LNC array is valid for the space.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
38 jbyte** lowest_non_clean;
a61af66fc99e Initial load
duke
parents:
diff changeset
39 uintptr_t lowest_non_clean_base_chunk_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 size_t lowest_non_clean_chunk_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 get_LNC_array_for_space(sp, lowest_non_clean,
a61af66fc99e Initial load
duke
parents:
diff changeset
42 lowest_non_clean_base_chunk_index,
a61af66fc99e Initial load
duke
parents:
diff changeset
43 lowest_non_clean_chunk_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45 int n_strides = n_threads * StridesPerThread;
a61af66fc99e Initial load
duke
parents:
diff changeset
46 SequentialSubTasksDone* pst = sp->par_seq_tasks();
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1552
diff changeset
47 pst->set_n_threads(n_threads);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
48 pst->set_n_tasks(n_strides);
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 int stride = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
51 while (!pst->is_task_claimed(/* reference */ stride)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
52 process_stride(sp, mr, stride, n_strides, dcto_cl, cl, clear,
a61af66fc99e Initial load
duke
parents:
diff changeset
53 lowest_non_clean,
a61af66fc99e Initial load
duke
parents:
diff changeset
54 lowest_non_clean_base_chunk_index,
a61af66fc99e Initial load
duke
parents:
diff changeset
55 lowest_non_clean_chunk_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
56 }
a61af66fc99e Initial load
duke
parents:
diff changeset
57 if (pst->all_tasks_completed()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // Clear lowest_non_clean array for next time.
a61af66fc99e Initial load
duke
parents:
diff changeset
59 intptr_t first_chunk_index = addr_to_chunk_index(mr.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
60 uintptr_t last_chunk_index = addr_to_chunk_index(mr.last());
a61af66fc99e Initial load
duke
parents:
diff changeset
61 for (uintptr_t ch = first_chunk_index; ch <= last_chunk_index; ch++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
62 intptr_t ind = ch - lowest_non_clean_base_chunk_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
63 assert(0 <= ind && ind < (intptr_t)lowest_non_clean_chunk_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
64 "Bounds error");
a61af66fc99e Initial load
duke
parents:
diff changeset
65 lowest_non_clean[ind] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 }
a61af66fc99e Initial load
duke
parents:
diff changeset
67 }
a61af66fc99e Initial load
duke
parents:
diff changeset
68 }
a61af66fc99e Initial load
duke
parents:
diff changeset
69 }
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 void
a61af66fc99e Initial load
duke
parents:
diff changeset
72 CardTableModRefBS::
a61af66fc99e Initial load
duke
parents:
diff changeset
73 process_stride(Space* sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
74 MemRegion used,
a61af66fc99e Initial load
duke
parents:
diff changeset
75 jint stride, int n_strides,
a61af66fc99e Initial load
duke
parents:
diff changeset
76 DirtyCardToOopClosure* dcto_cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
77 MemRegionClosure* cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
78 bool clear,
a61af66fc99e Initial load
duke
parents:
diff changeset
79 jbyte** lowest_non_clean,
a61af66fc99e Initial load
duke
parents:
diff changeset
80 uintptr_t lowest_non_clean_base_chunk_index,
a61af66fc99e Initial load
duke
parents:
diff changeset
81 size_t lowest_non_clean_chunk_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // We don't have to go downwards here; it wouldn't help anyway,
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // because of parallelism.
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // Find the first card address of the first chunk in the stride that is
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // at least "bottom" of the used region.
a61af66fc99e Initial load
duke
parents:
diff changeset
87 jbyte* start_card = byte_for(used.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
88 jbyte* end_card = byte_after(used.last());
a61af66fc99e Initial load
duke
parents:
diff changeset
89 uintptr_t start_chunk = addr_to_chunk_index(used.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
90 uintptr_t start_chunk_stride_num = start_chunk % n_strides;
a61af66fc99e Initial load
duke
parents:
diff changeset
91 jbyte* chunk_card_start;
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 if ((uintptr_t)stride >= start_chunk_stride_num) {
a61af66fc99e Initial load
duke
parents:
diff changeset
94 chunk_card_start = (jbyte*)(start_card +
a61af66fc99e Initial load
duke
parents:
diff changeset
95 (stride - start_chunk_stride_num) *
a61af66fc99e Initial load
duke
parents:
diff changeset
96 CardsPerStrideChunk);
a61af66fc99e Initial load
duke
parents:
diff changeset
97 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 // Go ahead to the next chunk group boundary, then to the requested stride.
a61af66fc99e Initial load
duke
parents:
diff changeset
99 chunk_card_start = (jbyte*)(start_card +
a61af66fc99e Initial load
duke
parents:
diff changeset
100 (n_strides - start_chunk_stride_num + stride) *
a61af66fc99e Initial load
duke
parents:
diff changeset
101 CardsPerStrideChunk);
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104 while (chunk_card_start < end_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // We don't have to go downwards here; it wouldn't help anyway,
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // because of parallelism. (We take care with "min_done"; see below.)
a61af66fc99e Initial load
duke
parents:
diff changeset
107 // Invariant: chunk_mr should be fully contained within the "used" region.
a61af66fc99e Initial load
duke
parents:
diff changeset
108 jbyte* chunk_card_end = chunk_card_start + CardsPerStrideChunk;
a61af66fc99e Initial load
duke
parents:
diff changeset
109 MemRegion chunk_mr = MemRegion(addr_for(chunk_card_start),
a61af66fc99e Initial load
duke
parents:
diff changeset
110 chunk_card_end >= end_card ?
a61af66fc99e Initial load
duke
parents:
diff changeset
111 used.end() : addr_for(chunk_card_end));
a61af66fc99e Initial load
duke
parents:
diff changeset
112 assert(chunk_mr.word_size() > 0, "[chunk_card_start > used_end)");
a61af66fc99e Initial load
duke
parents:
diff changeset
113 assert(used.contains(chunk_mr), "chunk_mr should be subset of used");
a61af66fc99e Initial load
duke
parents:
diff changeset
114
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // Process the chunk.
a61af66fc99e Initial load
duke
parents:
diff changeset
116 process_chunk_boundaries(sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
117 dcto_cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
118 chunk_mr,
a61af66fc99e Initial load
duke
parents:
diff changeset
119 used,
a61af66fc99e Initial load
duke
parents:
diff changeset
120 lowest_non_clean,
a61af66fc99e Initial load
duke
parents:
diff changeset
121 lowest_non_clean_base_chunk_index,
a61af66fc99e Initial load
duke
parents:
diff changeset
122 lowest_non_clean_chunk_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
123
a61af66fc99e Initial load
duke
parents:
diff changeset
124 non_clean_card_iterate_work(chunk_mr, cl, clear);
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // Find the next chunk of the stride.
a61af66fc99e Initial load
duke
parents:
diff changeset
127 chunk_card_start += CardsPerStrideChunk * n_strides;
a61af66fc99e Initial load
duke
parents:
diff changeset
128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 void
a61af66fc99e Initial load
duke
parents:
diff changeset
132 CardTableModRefBS::
a61af66fc99e Initial load
duke
parents:
diff changeset
133 process_chunk_boundaries(Space* sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
134 DirtyCardToOopClosure* dcto_cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
135 MemRegion chunk_mr,
a61af66fc99e Initial load
duke
parents:
diff changeset
136 MemRegion used,
a61af66fc99e Initial load
duke
parents:
diff changeset
137 jbyte** lowest_non_clean,
a61af66fc99e Initial load
duke
parents:
diff changeset
138 uintptr_t lowest_non_clean_base_chunk_index,
a61af66fc99e Initial load
duke
parents:
diff changeset
139 size_t lowest_non_clean_chunk_size)
a61af66fc99e Initial load
duke
parents:
diff changeset
140 {
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // We must worry about the chunk boundaries.
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // First, set our max_to_do:
a61af66fc99e Initial load
duke
parents:
diff changeset
144 HeapWord* max_to_do = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
145 uintptr_t cur_chunk_index = addr_to_chunk_index(chunk_mr.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
146 cur_chunk_index = cur_chunk_index - lowest_non_clean_base_chunk_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
147
a61af66fc99e Initial load
duke
parents:
diff changeset
148 if (chunk_mr.end() < used.end()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // This is not the last chunk in the used region. What is the last
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // object?
a61af66fc99e Initial load
duke
parents:
diff changeset
151 HeapWord* last_block = sp->block_start(chunk_mr.end());
a61af66fc99e Initial load
duke
parents:
diff changeset
152 assert(last_block <= chunk_mr.end(), "In case this property changes.");
a61af66fc99e Initial load
duke
parents:
diff changeset
153 if (last_block == chunk_mr.end()
a61af66fc99e Initial load
duke
parents:
diff changeset
154 || !sp->block_is_obj(last_block)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
155 max_to_do = chunk_mr.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // It is an object and starts before the end of the current chunk.
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // last_obj_card is the card corresponding to the start of the last object
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // in the chunk. Note that the last object may not start in
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // the chunk.
a61af66fc99e Initial load
duke
parents:
diff changeset
162 jbyte* last_obj_card = byte_for(last_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
163 if (!card_may_have_been_dirty(*last_obj_card)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // The card containing the head is not dirty. Any marks in
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // subsequent cards still in this chunk must have been made
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // precisely; we can cap processing at the end.
a61af66fc99e Initial load
duke
parents:
diff changeset
167 max_to_do = chunk_mr.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
168 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // The last object must be considered dirty, and extends onto the
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // following chunk. Look for a dirty card in that chunk that will
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // bound our processing.
a61af66fc99e Initial load
duke
parents:
diff changeset
172 jbyte* limit_card = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
173 size_t last_block_size = sp->block_size(last_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
174 jbyte* last_card_of_last_obj =
a61af66fc99e Initial load
duke
parents:
diff changeset
175 byte_for(last_block + last_block_size - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 jbyte* first_card_of_next_chunk = byte_for(chunk_mr.end());
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // This search potentially goes a long distance looking
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // for the next card that will be scanned. For example,
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // an object that is an array of primitives will not
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // have any cards covering regions interior to the array
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // that will need to be scanned. The scan can be terminated
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // at the last card of the next chunk. That would leave
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // limit_card as NULL and would result in "max_to_do"
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // being set with the LNC value or with the end
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // of the last block.
a61af66fc99e Initial load
duke
parents:
diff changeset
186 jbyte* last_card_of_next_chunk = first_card_of_next_chunk +
a61af66fc99e Initial load
duke
parents:
diff changeset
187 CardsPerStrideChunk;
a61af66fc99e Initial load
duke
parents:
diff changeset
188 assert(byte_for(chunk_mr.end()) - byte_for(chunk_mr.start())
a61af66fc99e Initial load
duke
parents:
diff changeset
189 == CardsPerStrideChunk, "last card of next chunk may be wrong");
a61af66fc99e Initial load
duke
parents:
diff changeset
190 jbyte* last_card_to_check = (jbyte*) MIN2(last_card_of_last_obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
191 last_card_of_next_chunk);
a61af66fc99e Initial load
duke
parents:
diff changeset
192 for (jbyte* cur = first_card_of_next_chunk;
a61af66fc99e Initial load
duke
parents:
diff changeset
193 cur <= last_card_to_check; cur++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
194 if (card_will_be_scanned(*cur)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 limit_card = cur; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
198 assert(0 <= cur_chunk_index+1 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
199 cur_chunk_index+1 < lowest_non_clean_chunk_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
200 "Bounds error.");
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // LNC for the next chunk
a61af66fc99e Initial load
duke
parents:
diff changeset
202 jbyte* lnc_card = lowest_non_clean[cur_chunk_index+1];
a61af66fc99e Initial load
duke
parents:
diff changeset
203 if (limit_card == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 limit_card = lnc_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
206 if (limit_card != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
207 if (lnc_card != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
208 limit_card = (jbyte*)MIN2((intptr_t)limit_card,
a61af66fc99e Initial load
duke
parents:
diff changeset
209 (intptr_t)lnc_card);
a61af66fc99e Initial load
duke
parents:
diff changeset
210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
211 max_to_do = addr_for(limit_card);
a61af66fc99e Initial load
duke
parents:
diff changeset
212 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 max_to_do = last_block + last_block_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
217 assert(max_to_do != NULL, "OOPS!");
a61af66fc99e Initial load
duke
parents:
diff changeset
218 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
219 max_to_do = used.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221 // Now we can set the closure we're using so it doesn't to beyond
a61af66fc99e Initial load
duke
parents:
diff changeset
222 // max_to_do.
a61af66fc99e Initial load
duke
parents:
diff changeset
223 dcto_cl->set_min_done(max_to_do);
a61af66fc99e Initial load
duke
parents:
diff changeset
224 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
225 dcto_cl->set_last_bottom(max_to_do);
a61af66fc99e Initial load
duke
parents:
diff changeset
226 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228 // Now we set *our" lowest_non_clean entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
229 // Find the object that spans our boundary, if one exists.
a61af66fc99e Initial load
duke
parents:
diff changeset
230 // Nothing to do on the first chunk.
a61af66fc99e Initial load
duke
parents:
diff changeset
231 if (chunk_mr.start() > used.start()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
232 // first_block is the block possibly spanning the chunk start
a61af66fc99e Initial load
duke
parents:
diff changeset
233 HeapWord* first_block = sp->block_start(chunk_mr.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // Does the block span the start of the chunk and is it
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // an object?
a61af66fc99e Initial load
duke
parents:
diff changeset
236 if (first_block < chunk_mr.start() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
237 sp->block_is_obj(first_block)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
238 jbyte* first_dirty_card = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
239 jbyte* last_card_of_first_obj =
a61af66fc99e Initial load
duke
parents:
diff changeset
240 byte_for(first_block + sp->block_size(first_block) - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
241 jbyte* first_card_of_cur_chunk = byte_for(chunk_mr.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
242 jbyte* last_card_of_cur_chunk = byte_for(chunk_mr.last());
a61af66fc99e Initial load
duke
parents:
diff changeset
243 jbyte* last_card_to_check =
a61af66fc99e Initial load
duke
parents:
diff changeset
244 (jbyte*) MIN2((intptr_t) last_card_of_cur_chunk,
a61af66fc99e Initial load
duke
parents:
diff changeset
245 (intptr_t) last_card_of_first_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
246 for (jbyte* cur = first_card_of_cur_chunk;
a61af66fc99e Initial load
duke
parents:
diff changeset
247 cur <= last_card_to_check; cur++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
248 if (card_will_be_scanned(*cur)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 first_dirty_card = cur; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252 if (first_dirty_card != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
253 assert(0 <= cur_chunk_index &&
a61af66fc99e Initial load
duke
parents:
diff changeset
254 cur_chunk_index < lowest_non_clean_chunk_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
255 "Bounds error.");
a61af66fc99e Initial load
duke
parents:
diff changeset
256 lowest_non_clean[cur_chunk_index] = first_dirty_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
261
a61af66fc99e Initial load
duke
parents:
diff changeset
262 void
a61af66fc99e Initial load
duke
parents:
diff changeset
263 CardTableModRefBS::
a61af66fc99e Initial load
duke
parents:
diff changeset
264 get_LNC_array_for_space(Space* sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
265 jbyte**& lowest_non_clean,
a61af66fc99e Initial load
duke
parents:
diff changeset
266 uintptr_t& lowest_non_clean_base_chunk_index,
a61af66fc99e Initial load
duke
parents:
diff changeset
267 size_t& lowest_non_clean_chunk_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
268
a61af66fc99e Initial load
duke
parents:
diff changeset
269 int i = find_covering_region_containing(sp->bottom());
a61af66fc99e Initial load
duke
parents:
diff changeset
270 MemRegion covered = _covered[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
271 size_t n_chunks = chunks_to_cover(covered);
a61af66fc99e Initial load
duke
parents:
diff changeset
272
a61af66fc99e Initial load
duke
parents:
diff changeset
273 // Only the first thread to obtain the lock will resize the
a61af66fc99e Initial load
duke
parents:
diff changeset
274 // LNC array for the covered region. Any later expansion can't affect
a61af66fc99e Initial load
duke
parents:
diff changeset
275 // the used_at_save_marks region.
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // (I observed a bug in which the first thread to execute this would
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // resize, and then it would cause "expand_and_allocates" that would
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // Increase the number of chunks in the covered region. Then a second
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // thread would come and execute this, see that the size didn't match,
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // and free and allocate again. So the first thread would be using a
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // freed "_lowest_non_clean" array.)
a61af66fc99e Initial load
duke
parents:
diff changeset
282
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // Do a dirty read here. If we pass the conditional then take the rare
a61af66fc99e Initial load
duke
parents:
diff changeset
284 // event lock and do the read again in case some other thread had already
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // succeeded and done the resize.
a61af66fc99e Initial load
duke
parents:
diff changeset
286 int cur_collection = Universe::heap()->total_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
287 if (_last_LNC_resizing_collection[i] != cur_collection) {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 MutexLocker x(ParGCRareEvent_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
289 if (_last_LNC_resizing_collection[i] != cur_collection) {
a61af66fc99e Initial load
duke
parents:
diff changeset
290 if (_lowest_non_clean[i] == NULL ||
a61af66fc99e Initial load
duke
parents:
diff changeset
291 n_chunks != _lowest_non_clean_chunk_size[i]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // Should we delete the old?
a61af66fc99e Initial load
duke
parents:
diff changeset
294 if (_lowest_non_clean[i] != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
295 assert(n_chunks != _lowest_non_clean_chunk_size[i],
a61af66fc99e Initial load
duke
parents:
diff changeset
296 "logical consequence");
a61af66fc99e Initial load
duke
parents:
diff changeset
297 FREE_C_HEAP_ARRAY(CardPtr, _lowest_non_clean[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
298 _lowest_non_clean[i] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // Now allocate a new one if necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
301 if (_lowest_non_clean[i] == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
302 _lowest_non_clean[i] = NEW_C_HEAP_ARRAY(CardPtr, n_chunks);
a61af66fc99e Initial load
duke
parents:
diff changeset
303 _lowest_non_clean_chunk_size[i] = n_chunks;
a61af66fc99e Initial load
duke
parents:
diff changeset
304 _lowest_non_clean_base_chunk_index[i] = addr_to_chunk_index(covered.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
305 for (int j = 0; j < (int)n_chunks; j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
306 _lowest_non_clean[i][j] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
309 _last_LNC_resizing_collection[i] = cur_collection;
a61af66fc99e Initial load
duke
parents:
diff changeset
310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // In any case, now do the initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
313 lowest_non_clean = _lowest_non_clean[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
314 lowest_non_clean_base_chunk_index = _lowest_non_clean_base_chunk_index[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
315 lowest_non_clean_chunk_size = _lowest_non_clean_chunk_size[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }