comparison src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp @ 6817:f81a7c0c618d

7199349: NPG: PS: Crash seen in jprt Reviewed-by: johnc
author jmasa
date Wed, 03 Oct 2012 08:08:52 -0700
parents da91efe96a93
children 746b070f5022
comparison
equal deleted inserted replaced
6816:87ac5c0a404d 6817:f81a7c0c618d
119 virtual void do_oop(narrowOop* p) { CheckForPreciseMarks::do_oop_work(p); } 119 virtual void do_oop(narrowOop* p) { CheckForPreciseMarks::do_oop_work(p); }
120 }; 120 };
121 121
122 // We get passed the space_top value to prevent us from traversing into 122 // We get passed the space_top value to prevent us from traversing into
123 // the old_gen promotion labs, which cannot be safely parsed. 123 // the old_gen promotion labs, which cannot be safely parsed.
124 void CardTableExtension::scavenge_contents(ObjectStartArray* start_array, 124
125 MutableSpace* sp, 125 // Do not call this method if the space is empty.
126 HeapWord* space_top, 126 // It is a waste to start tasks and get here only to
127 PSPromotionManager* pm) 127 // do no work. If this method needs to be called
128 { 128 // when the space is empty, fix the calculation of
129 assert(start_array != NULL && sp != NULL && pm != NULL, "Sanity"); 129 // end_card to allow sp_top == sp->bottom().
130 assert(start_array->covered_region().contains(sp->used_region()),
131 "ObjectStartArray does not cover space");
132
133 if (sp->not_empty()) {
134 oop* sp_top = (oop*)space_top;
135 oop* prev_top = NULL;
136 jbyte* current_card = byte_for(sp->bottom());
137 jbyte* end_card = byte_for(sp_top - 1); // sp_top is exclusive
138 // scan card marking array
139 while (current_card <= end_card) {
140 jbyte value = *current_card;
141 // skip clean cards
142 if (card_is_clean(value)) {
143 current_card++;
144 } else {
145 // we found a non-clean card
146 jbyte* first_nonclean_card = current_card++;
147 oop* bottom = (oop*)addr_for(first_nonclean_card);
148 // find object starting on card
149 oop* bottom_obj = (oop*)start_array->object_start((HeapWord*)bottom);
150 // bottom_obj = (oop*)start_array->object_start((HeapWord*)bottom);
151 assert(bottom_obj <= bottom, "just checking");
152 // make sure we don't scan oops we already looked at
153 if (bottom < prev_top) bottom = prev_top;
154 // figure out when to stop scanning
155 jbyte* first_clean_card;
156 oop* top;
157 bool restart_scanning;
158 do {
159 restart_scanning = false;
160 // find a clean card
161 while (current_card <= end_card) {
162 value = *current_card;
163 if (card_is_clean(value)) break;
164 current_card++;
165 }
166 // check if we reached the end, if so we are done
167 if (current_card >= end_card) {
168 first_clean_card = end_card + 1;
169 current_card++;
170 top = sp_top;
171 } else {
172 // we have a clean card, find object starting on that card
173 first_clean_card = current_card++;
174 top = (oop*)addr_for(first_clean_card);
175 oop* top_obj = (oop*)start_array->object_start((HeapWord*)top);
176 // top_obj = (oop*)start_array->object_start((HeapWord*)top);
177 assert(top_obj <= top, "just checking");
178 if (oop(top_obj)->is_objArray() || oop(top_obj)->is_typeArray()) {
179 // an arrayOop is starting on the clean card - since we do exact store
180 // checks for objArrays we are done
181 } else {
182 // otherwise, it is possible that the object starting on the clean card
183 // spans the entire card, and that the store happened on a later card.
184 // figure out where the object ends
185 top = top_obj + oop(top_obj)->size();
186 jbyte* top_card = CardTableModRefBS::byte_for(top - 1); // top is exclusive
187 if (top_card > first_clean_card) {
188 // object ends a different card
189 current_card = top_card + 1;
190 if (card_is_clean(*top_card)) {
191 // the ending card is clean, we are done
192 first_clean_card = top_card;
193 } else {
194 // the ending card is not clean, continue scanning at start of do-while
195 restart_scanning = true;
196 }
197 } else {
198 // object ends on the clean card, we are done.
199 assert(first_clean_card == top_card, "just checking");
200 }
201 }
202 }
203 } while (restart_scanning);
204 // we know which cards to scan, now clear them
205 while (first_nonclean_card < first_clean_card) {
206 *first_nonclean_card++ = clean_card;
207 }
208 // scan oops in objects
209 do {
210 oop(bottom_obj)->push_contents(pm);
211 bottom_obj += oop(bottom_obj)->size();
212 assert(bottom_obj <= sp_top, "just checking");
213 } while (bottom_obj < top);
214 pm->drain_stacks_cond_depth();
215 // remember top oop* scanned
216 prev_top = top;
217 }
218 }
219 }
220 }
221 130
222 void CardTableExtension::scavenge_contents_parallel(ObjectStartArray* start_array, 131 void CardTableExtension::scavenge_contents_parallel(ObjectStartArray* start_array,
223 MutableSpace* sp, 132 MutableSpace* sp,
224 HeapWord* space_top, 133 HeapWord* space_top,
225 PSPromotionManager* pm, 134 PSPromotionManager* pm,
226 uint stripe_number, 135 uint stripe_number,
227 uint stripe_total) { 136 uint stripe_total) {
228 int ssize = 128; // Naked constant! Work unit = 64k. 137 int ssize = 128; // Naked constant! Work unit = 64k.
229 int dirty_card_count = 0; 138 int dirty_card_count = 0;
230 139
140 // It is a waste to get here if empty.
141 assert(sp->bottom() < sp->top(), "Should not be called if empty");
231 oop* sp_top = (oop*)space_top; 142 oop* sp_top = (oop*)space_top;
232 oop* sp_last = sp->bottom() == space_top ? sp_top : sp_top - 1;
233 jbyte* start_card = byte_for(sp->bottom()); 143 jbyte* start_card = byte_for(sp->bottom());
234 jbyte* end_card = byte_for(sp_last) + 1; 144 jbyte* end_card = byte_for(sp_top - 1) + 1;
235 oop* last_scanned = NULL; // Prevent scanning objects more than once 145 oop* last_scanned = NULL; // Prevent scanning objects more than once
236 // The width of the stripe ssize*stripe_total must be 146 // The width of the stripe ssize*stripe_total must be
237 // consistent with the number of stripes so that the complete slice 147 // consistent with the number of stripes so that the complete slice
238 // is covered. 148 // is covered.
239 size_t slice_width = ssize * stripe_total; 149 size_t slice_width = ssize * stripe_total;
252 // last object continues into the next 'slice'. 162 // last object continues into the next 'slice'.
253 // 163 //
254 // Note! ending cards are exclusive! 164 // Note! ending cards are exclusive!
255 HeapWord* slice_start = addr_for(worker_start_card); 165 HeapWord* slice_start = addr_for(worker_start_card);
256 HeapWord* slice_end = MIN2((HeapWord*) sp_top, addr_for(worker_end_card)); 166 HeapWord* slice_end = MIN2((HeapWord*) sp_top, addr_for(worker_end_card));
167
168 #ifdef ASSERT
169 if (GCWorkerDelayMillis > 0) {
170 // Delay 1 worker so that it proceeds after all the work
171 // has been completed.
172 if (stripe_number < 2) {
173 os::sleep(Thread::current(), GCWorkerDelayMillis, false);
174 }
175 }
176 #endif
257 177
258 // If there are not objects starting within the chunk, skip it. 178 // If there are not objects starting within the chunk, skip it.
259 if (!start_array->object_starts_in_range(slice_start, slice_end)) { 179 if (!start_array->object_starts_in_range(slice_start, slice_end)) {
260 continue; 180 continue;
261 } 181 }