Mercurial > hg > graal-jvmci-8
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 } |