169 void G1CollectionSet::clear() {
170 assert_at_safepoint(true);
171 _collection_set_cur_length = 0;
172 }
173
174 void G1CollectionSet::iterate(HeapRegionClosure* cl) const {
175 iterate_from(cl, 0, 1);
176 }
177
178 void G1CollectionSet::iterate_from(HeapRegionClosure* cl, uint worker_id, uint total_workers) const {
179 size_t len = _collection_set_cur_length;
180 OrderAccess::loadload();
181 if (len == 0) {
182 return;
183 }
184 size_t start_pos = (worker_id * len) / total_workers;
185 size_t cur_pos = start_pos;
186
187 do {
188 HeapRegion* r = G1CollectedHeap::heap()->region_at(_collection_set_regions[cur_pos]);
189 bool result = cl->doHeapRegion(r);
190 if (result) {
191 cl->incomplete();
192 return;
193 }
194 cur_pos++;
195 if (cur_pos == len) {
196 cur_pos = 0;
197 }
198 } while (cur_pos != start_pos);
199 }
200
201 void G1CollectionSet::update_young_region_prediction(HeapRegion* hr,
202 size_t new_rs_length) {
203 // Update the CSet information that is dependent on the new RS length
204 assert(hr->is_young(), "Precondition");
205 assert(!SafepointSynchronize::is_at_safepoint(), "should not be at a safepoint");
206
207 // We could have updated _inc_recorded_rs_lengths and
208 // _inc_predicted_elapsed_time_ms directly but we'd need to do
209 // that atomically, as this code is executed by a concurrent
210 // refinement thread, potentially concurrently with a mutator thread
211 // allocating a new region and also updating the same fields. To
275 _g1->register_young_region_with_cset(hr);
276 }
277
278 void G1CollectionSet::add_survivor_regions(HeapRegion* hr) {
279 assert(hr->is_survivor(), "Must only add survivor regions, but is %s", hr->get_type_str());
280 add_young_region_common(hr);
281 }
282
283 void G1CollectionSet::add_eden_region(HeapRegion* hr) {
284 assert(hr->is_eden(), "Must only add eden regions, but is %s", hr->get_type_str());
285 add_young_region_common(hr);
286 }
287
288 #ifndef PRODUCT
289 class G1VerifyYoungAgesClosure : public HeapRegionClosure {
290 public:
291 bool _valid;
292 public:
293 G1VerifyYoungAgesClosure() : HeapRegionClosure(), _valid(true) { }
294
295 virtual bool doHeapRegion(HeapRegion* r) {
296 guarantee(r->is_young(), "Region must be young but is %s", r->get_type_str());
297
298 SurvRateGroup* group = r->surv_rate_group();
299
300 if (group == NULL) {
301 log_error(gc, verify)("## encountered NULL surv_rate_group in young region");
302 _valid = false;
303 }
304
305 if (r->age_in_surv_rate_group() < 0) {
306 log_error(gc, verify)("## encountered negative age in young region");
307 _valid = false;
308 }
309
310 return false;
311 }
312
313 bool valid() const { return _valid; }
314 };
315
316 bool G1CollectionSet::verify_young_ages() {
317 assert_at_safepoint(true);
318
319 G1VerifyYoungAgesClosure cl;
320 iterate(&cl);
321
322 if (!cl.valid()) {
323 LogStreamHandle(Error, gc, verify) log;
324 print(&log);
325 }
326
327 return cl.valid();
328 }
329
330 class G1PrintCollectionSetClosure : public HeapRegionClosure {
331 outputStream* _st;
332 public:
333 G1PrintCollectionSetClosure(outputStream* st) : HeapRegionClosure(), _st(st) { }
334
335 virtual bool doHeapRegion(HeapRegion* r) {
336 assert(r->in_collection_set(), "Region %u should be in collection set", r->hrm_index());
337 _st->print_cr(" " HR_FORMAT ", P: " PTR_FORMAT "N: " PTR_FORMAT ", age: %4d",
338 HR_FORMAT_PARAMS(r),
339 p2i(r->prev_top_at_mark_start()),
340 p2i(r->next_top_at_mark_start()),
341 r->age_in_surv_rate_group_cond());
342 return false;
343 }
344 };
345
346 void G1CollectionSet::print(outputStream* st) {
347 st->print_cr("\nCollection_set:");
348
349 G1PrintCollectionSetClosure cl(st);
350 iterate(&cl);
351 }
352 #endif // !PRODUCT
353
354 double G1CollectionSet::finalize_young_part(double target_pause_time_ms, G1SurvivorRegions* survivors) {
355 double young_start_time_sec = os::elapsedTime();
507
508 QuickSort::sort(_collection_set_regions, _collection_set_cur_length, compare_region_idx, true);
509 }
510
511 #ifdef ASSERT
512 class G1VerifyYoungCSetIndicesClosure : public HeapRegionClosure {
513 private:
514 size_t _young_length;
515 int* _heap_region_indices;
516 public:
517 G1VerifyYoungCSetIndicesClosure(size_t young_length) : HeapRegionClosure(), _young_length(young_length) {
518 _heap_region_indices = NEW_C_HEAP_ARRAY(int, young_length, mtGC);
519 for (size_t i = 0; i < young_length; i++) {
520 _heap_region_indices[i] = -1;
521 }
522 }
523 ~G1VerifyYoungCSetIndicesClosure() {
524 FREE_C_HEAP_ARRAY(int, _heap_region_indices);
525 }
526
527 virtual bool doHeapRegion(HeapRegion* r) {
528 const int idx = r->young_index_in_cset();
529
530 assert(idx > -1, "Young index must be set for all regions in the incremental collection set but is not for region %u.", r->hrm_index());
531 assert((size_t)idx < _young_length, "Young cset index too large for region %u", r->hrm_index());
532
533 assert(_heap_region_indices[idx] == -1,
534 "Index %d used by multiple regions, first use by region %u, second by region %u",
535 idx, _heap_region_indices[idx], r->hrm_index());
536
537 _heap_region_indices[idx] = r->hrm_index();
538
539 return false;
540 }
541 };
542
543 void G1CollectionSet::verify_young_cset_indices() const {
544 assert_at_safepoint(true);
545
546 G1VerifyYoungCSetIndicesClosure cl(_collection_set_cur_length);
547 iterate(&cl);
|
169 void G1CollectionSet::clear() {
170 assert_at_safepoint(true);
171 _collection_set_cur_length = 0;
172 }
173
174 void G1CollectionSet::iterate(HeapRegionClosure* cl) const {
175 iterate_from(cl, 0, 1);
176 }
177
178 void G1CollectionSet::iterate_from(HeapRegionClosure* cl, uint worker_id, uint total_workers) const {
179 size_t len = _collection_set_cur_length;
180 OrderAccess::loadload();
181 if (len == 0) {
182 return;
183 }
184 size_t start_pos = (worker_id * len) / total_workers;
185 size_t cur_pos = start_pos;
186
187 do {
188 HeapRegion* r = G1CollectedHeap::heap()->region_at(_collection_set_regions[cur_pos]);
189 bool result = cl->do_heap_region(r);
190 if (result) {
191 cl->set_incomplete();
192 return;
193 }
194 cur_pos++;
195 if (cur_pos == len) {
196 cur_pos = 0;
197 }
198 } while (cur_pos != start_pos);
199 }
200
201 void G1CollectionSet::update_young_region_prediction(HeapRegion* hr,
202 size_t new_rs_length) {
203 // Update the CSet information that is dependent on the new RS length
204 assert(hr->is_young(), "Precondition");
205 assert(!SafepointSynchronize::is_at_safepoint(), "should not be at a safepoint");
206
207 // We could have updated _inc_recorded_rs_lengths and
208 // _inc_predicted_elapsed_time_ms directly but we'd need to do
209 // that atomically, as this code is executed by a concurrent
210 // refinement thread, potentially concurrently with a mutator thread
211 // allocating a new region and also updating the same fields. To
275 _g1->register_young_region_with_cset(hr);
276 }
277
278 void G1CollectionSet::add_survivor_regions(HeapRegion* hr) {
279 assert(hr->is_survivor(), "Must only add survivor regions, but is %s", hr->get_type_str());
280 add_young_region_common(hr);
281 }
282
283 void G1CollectionSet::add_eden_region(HeapRegion* hr) {
284 assert(hr->is_eden(), "Must only add eden regions, but is %s", hr->get_type_str());
285 add_young_region_common(hr);
286 }
287
288 #ifndef PRODUCT
289 class G1VerifyYoungAgesClosure : public HeapRegionClosure {
290 public:
291 bool _valid;
292 public:
293 G1VerifyYoungAgesClosure() : HeapRegionClosure(), _valid(true) { }
294
295 virtual bool do_heap_region(HeapRegion* r) {
296 guarantee(r->is_young(), "Region must be young but is %s", r->get_type_str());
297
298 SurvRateGroup* group = r->surv_rate_group();
299
300 if (group == NULL) {
301 log_error(gc, verify)("## encountered NULL surv_rate_group in young region");
302 _valid = false;
303 }
304
305 if (r->age_in_surv_rate_group() < 0) {
306 log_error(gc, verify)("## encountered negative age in young region");
307 _valid = false;
308 }
309
310 return false;
311 }
312
313 bool valid() const { return _valid; }
314 };
315
316 bool G1CollectionSet::verify_young_ages() {
317 assert_at_safepoint(true);
318
319 G1VerifyYoungAgesClosure cl;
320 iterate(&cl);
321
322 if (!cl.valid()) {
323 LogStreamHandle(Error, gc, verify) log;
324 print(&log);
325 }
326
327 return cl.valid();
328 }
329
330 class G1PrintCollectionSetClosure : public HeapRegionClosure {
331 outputStream* _st;
332 public:
333 G1PrintCollectionSetClosure(outputStream* st) : HeapRegionClosure(), _st(st) { }
334
335 virtual bool do_heap_region(HeapRegion* r) {
336 assert(r->in_collection_set(), "Region %u should be in collection set", r->hrm_index());
337 _st->print_cr(" " HR_FORMAT ", P: " PTR_FORMAT "N: " PTR_FORMAT ", age: %4d",
338 HR_FORMAT_PARAMS(r),
339 p2i(r->prev_top_at_mark_start()),
340 p2i(r->next_top_at_mark_start()),
341 r->age_in_surv_rate_group_cond());
342 return false;
343 }
344 };
345
346 void G1CollectionSet::print(outputStream* st) {
347 st->print_cr("\nCollection_set:");
348
349 G1PrintCollectionSetClosure cl(st);
350 iterate(&cl);
351 }
352 #endif // !PRODUCT
353
354 double G1CollectionSet::finalize_young_part(double target_pause_time_ms, G1SurvivorRegions* survivors) {
355 double young_start_time_sec = os::elapsedTime();
507
508 QuickSort::sort(_collection_set_regions, _collection_set_cur_length, compare_region_idx, true);
509 }
510
511 #ifdef ASSERT
512 class G1VerifyYoungCSetIndicesClosure : public HeapRegionClosure {
513 private:
514 size_t _young_length;
515 int* _heap_region_indices;
516 public:
517 G1VerifyYoungCSetIndicesClosure(size_t young_length) : HeapRegionClosure(), _young_length(young_length) {
518 _heap_region_indices = NEW_C_HEAP_ARRAY(int, young_length, mtGC);
519 for (size_t i = 0; i < young_length; i++) {
520 _heap_region_indices[i] = -1;
521 }
522 }
523 ~G1VerifyYoungCSetIndicesClosure() {
524 FREE_C_HEAP_ARRAY(int, _heap_region_indices);
525 }
526
527 virtual bool do_heap_region(HeapRegion* r) {
528 const int idx = r->young_index_in_cset();
529
530 assert(idx > -1, "Young index must be set for all regions in the incremental collection set but is not for region %u.", r->hrm_index());
531 assert((size_t)idx < _young_length, "Young cset index too large for region %u", r->hrm_index());
532
533 assert(_heap_region_indices[idx] == -1,
534 "Index %d used by multiple regions, first use by region %u, second by region %u",
535 idx, _heap_region_indices[idx], r->hrm_index());
536
537 _heap_region_indices[idx] = r->hrm_index();
538
539 return false;
540 }
541 };
542
543 void G1CollectionSet::verify_young_cset_indices() const {
544 assert_at_safepoint(true);
545
546 G1VerifyYoungCSetIndicesClosure cl(_collection_set_cur_length);
547 iterate(&cl);
|