42 }
43
44 G1GCPhaseTimes* G1CollectionSet::phase_times() {
45 return _policy->phase_times();
46 }
47
48 double G1CollectionSet::predict_region_elapsed_time_ms(HeapRegion* hr) {
49 return _policy->predict_region_elapsed_time_ms(hr, collector_state()->in_young_only_phase());
50 }
51
52 G1CollectionSet::G1CollectionSet(G1CollectedHeap* g1h, G1Policy* policy) :
53 _g1h(g1h),
54 _policy(policy),
55 _candidates(NULL),
56 _eden_region_length(0),
57 _survivor_region_length(0),
58 _old_region_length(0),
59 _collection_set_regions(NULL),
60 _collection_set_cur_length(0),
61 _collection_set_max_length(0),
62 _optional_regions(NULL),
63 _optional_region_length(0),
64 _optional_region_max_length(0),
65 _bytes_used_before(0),
66 _recorded_rs_lengths(0),
67 _inc_build_state(Inactive),
68 _inc_bytes_used_before(0),
69 _inc_recorded_rs_lengths(0),
70 _inc_recorded_rs_lengths_diffs(0),
71 _inc_predicted_elapsed_time_ms(0.0),
72 _inc_predicted_elapsed_time_ms_diffs(0.0) {
73 }
74
75 G1CollectionSet::~G1CollectionSet() {
76 if (_collection_set_regions != NULL) {
77 FREE_C_HEAP_ARRAY(uint, _collection_set_regions);
78 }
79 free_optional_regions();
80 clear_candidates();
81 }
82
83 void G1CollectionSet::init_region_lengths(uint eden_cset_region_length,
84 uint survivor_cset_region_length) {
85 assert_at_safepoint_on_vm_thread();
86
87 _eden_region_length = eden_cset_region_length;
88 _survivor_region_length = survivor_cset_region_length;
89
90 assert((size_t) young_region_length() == _collection_set_cur_length,
91 "Young region length %u should match collection set length " SIZE_FORMAT, young_region_length(), _collection_set_cur_length);
92
93 _old_region_length = 0;
94 _optional_region_length = 0;
95 }
96
97 void G1CollectionSet::initialize(uint max_region_length) {
98 guarantee(_collection_set_regions == NULL, "Must only initialize once.");
99 _collection_set_max_length = max_region_length;
100 _collection_set_regions = NEW_C_HEAP_ARRAY(uint, max_region_length, mtGC);
101 }
102
103 void G1CollectionSet::initialize_optional(uint max_length) {
104 assert(_optional_regions == NULL, "Already initialized");
105 assert(_optional_region_length == 0, "Already initialized");
106 assert(_optional_region_max_length == 0, "Already initialized");
107 _optional_region_max_length = max_length;
108 _optional_regions = NEW_C_HEAP_ARRAY(HeapRegion*, _optional_region_max_length, mtGC);
109 }
110
111 void G1CollectionSet::free_optional_regions() {
112 _optional_region_length = 0;
113 _optional_region_max_length = 0;
114 if (_optional_regions != NULL) {
115 FREE_C_HEAP_ARRAY(HeapRegion*, _optional_regions);
116 _optional_regions = NULL;
117 }
118 }
119
120 void G1CollectionSet::clear_candidates() {
121 delete _candidates;
122 _candidates = NULL;
123 }
124
125 void G1CollectionSet::set_recorded_rs_lengths(size_t rs_lengths) {
126 _recorded_rs_lengths = rs_lengths;
127 }
128
129 // Add the heap region at the head of the non-incremental collection set
130 void G1CollectionSet::add_old_region(HeapRegion* hr) {
131 assert_at_safepoint_on_vm_thread();
132
133 assert(_inc_build_state == Active || hr->index_in_opt_cset() != G1OptionalCSet::InvalidCSetIndex,
134 "Precondition, actively building cset or adding optional later on");
135 assert(hr->is_old(), "the region should be old");
136
137 assert(!hr->in_collection_set(), "should not already be in the CSet");
138 _g1h->register_old_region_with_cset(hr);
139
140 _collection_set_regions[_collection_set_cur_length++] = hr->hrm_index();
141 assert(_collection_set_cur_length <= _collection_set_max_length, "Collection set now larger than maximum size.");
142
143 _bytes_used_before += hr->used();
144 size_t rs_length = hr->rem_set()->occupied();
145 _recorded_rs_lengths += rs_length;
146 _old_region_length += 1;
147
148 log_trace(gc, cset)("Added old region %d to collection set", hr->hrm_index());
149 }
150
151 void G1CollectionSet::add_optional_region(HeapRegion* hr) {
152 assert(!optional_is_full(), "Precondition, must have room left for this region");
153 assert(hr->is_old(), "the region should be old");
154 assert(!hr->in_collection_set(), "should not already be in the CSet");
155
156 _g1h->register_optional_region_with_cset(hr);
157
158 _optional_regions[_optional_region_length] = hr;
159 uint index = _optional_region_length++;
160 hr->set_index_in_opt_cset(index);
161
162 log_trace(gc, cset)("Added region %d to optional collection set (%u)", hr->hrm_index(), _optional_region_length);
163 }
164
165 // Initialize the per-collection-set information
166 void G1CollectionSet::start_incremental_building() {
167 assert(_collection_set_cur_length == 0, "Collection set must be empty before starting a new collection set.");
168 assert(_inc_build_state == Inactive, "Precondition");
169
170 _inc_bytes_used_before = 0;
171
172 _inc_recorded_rs_lengths = 0;
173 _inc_recorded_rs_lengths_diffs = 0;
174 _inc_predicted_elapsed_time_ms = 0.0;
175 _inc_predicted_elapsed_time_ms_diffs = 0.0;
176 _inc_build_state = Active;
177 }
178
179 void G1CollectionSet::finalize_incremental_building() {
180 assert(_inc_build_state == Active, "Precondition");
181 assert(SafepointSynchronize::is_at_safepoint(), "should be at a safepoint");
182
183 // The two "main" fields, _inc_recorded_rs_lengths and
184 // _inc_predicted_elapsed_time_ms, are updated by the thread
185 // that adds a new region to the CSet. Further updates by the
186 // concurrent refinement thread that samples the young RSet lengths
187 // are accumulated in the *_diffs fields. Here we add the diffs to
188 // the "main" fields.
189
190 if (_inc_recorded_rs_lengths_diffs >= 0) {
191 _inc_recorded_rs_lengths += _inc_recorded_rs_lengths_diffs;
192 } else {
193 // This is defensive. The diff should in theory be always positive
194 // as RSets can only grow between GCs. However, given that we
195 // sample their size concurrently with other threads updating them
196 // it's possible that we might get the wrong size back, which
197 // could make the calculations somewhat inaccurate.
198 size_t diffs = (size_t) (-_inc_recorded_rs_lengths_diffs);
199 if (_inc_recorded_rs_lengths >= diffs) {
200 _inc_recorded_rs_lengths -= diffs;
201 } else {
202 _inc_recorded_rs_lengths = 0;
203 }
204 }
205 _inc_predicted_elapsed_time_ms += _inc_predicted_elapsed_time_ms_diffs;
206
207 _inc_recorded_rs_lengths_diffs = 0;
208 _inc_predicted_elapsed_time_ms_diffs = 0.0;
209 }
210
211 void G1CollectionSet::clear() {
212 assert_at_safepoint_on_vm_thread();
213 _collection_set_cur_length = 0;
214 _optional_region_length = 0;
215 }
216
217 void G1CollectionSet::iterate(HeapRegionClosure* cl) const {
218 iterate_from(cl, 0, 1);
219 }
220
221 void G1CollectionSet::iterate_from(HeapRegionClosure* cl, uint worker_id, uint total_workers) const {
222 size_t len = _collection_set_cur_length;
223 OrderAccess::loadload();
224 if (len == 0) {
225 return;
226 }
227 size_t start_pos = (worker_id * len) / total_workers;
228 size_t cur_pos = start_pos;
229
230 do {
231 HeapRegion* r = _g1h->region_at(_collection_set_regions[cur_pos]);
232 bool result = cl->do_heap_region(r);
233 if (result) {
234 cl->set_incomplete();
235 return;
236 }
237 cur_pos++;
238 if (cur_pos == len) {
239 cur_pos = 0;
240 }
241 } while (cur_pos != start_pos);
242 }
243
244 void G1CollectionSet::update_young_region_prediction(HeapRegion* hr,
245 size_t new_rs_length) {
246 // Update the CSet information that is dependent on the new RS length
247 assert(hr->is_young(), "Precondition");
248 assert(!SafepointSynchronize::is_at_safepoint(), "should not be at a safepoint");
249
250 // We could have updated _inc_recorded_rs_lengths and
251 // _inc_predicted_elapsed_time_ms directly but we'd need to do
252 // that atomically, as this code is executed by a concurrent
253 // refinement thread, potentially concurrently with a mutator thread
254 // allocating a new region and also updating the same fields. To
255 // avoid the atomic operations we accumulate these updates on two
256 // separate fields (*_diffs) and we'll just add them to the "main"
382 _st->print_cr(" " HR_FORMAT ", P: " PTR_FORMAT "N: " PTR_FORMAT ", age: %4d",
383 HR_FORMAT_PARAMS(r),
384 p2i(r->prev_top_at_mark_start()),
385 p2i(r->next_top_at_mark_start()),
386 r->age_in_surv_rate_group_cond());
387 return false;
388 }
389 };
390
391 void G1CollectionSet::print(outputStream* st) {
392 st->print_cr("\nCollection_set:");
393
394 G1PrintCollectionSetDetailClosure cl(st);
395 iterate(&cl);
396 }
397 #endif // !PRODUCT
398
399 double G1CollectionSet::finalize_young_part(double target_pause_time_ms, G1SurvivorRegions* survivors) {
400 double young_start_time_sec = os::elapsedTime();
401
402 finalize_incremental_building();
403
404 guarantee(target_pause_time_ms > 0.0,
405 "target_pause_time_ms = %1.6lf should be positive", target_pause_time_ms);
406
407 size_t pending_cards = _policy->pending_cards();
408 double base_time_ms = _policy->predict_base_elapsed_time_ms(pending_cards);
409 double time_remaining_ms = MAX2(target_pause_time_ms - base_time_ms, 0.0);
410
411 log_trace(gc, ergo, cset)("Start choosing CSet. pending cards: " SIZE_FORMAT " predicted base time: %1.2fms remaining time: %1.2fms target pause time: %1.2fms",
412 pending_cards, base_time_ms, time_remaining_ms, target_pause_time_ms);
413
414 // The young list is laid with the survivor regions from the previous
415 // pause are appended to the RHS of the young list, i.e.
416 // [Newly Young Regions ++ Survivors from last pause].
417
418 uint survivor_region_length = survivors->length();
419 uint eden_region_length = _g1h->eden_regions_count();
420 init_region_lengths(eden_region_length, survivor_region_length);
421
422 verify_young_cset_indices();
423
424 // Clear the fields that point to the survivor list - they are all young now.
425 survivors->convert_to_eden();
426
427 _bytes_used_before = _inc_bytes_used_before;
428 time_remaining_ms = MAX2(time_remaining_ms - _inc_predicted_elapsed_time_ms, 0.0);
429
430 log_trace(gc, ergo, cset)("Add young regions to CSet. eden: %u regions, survivors: %u regions, predicted young region time: %1.2fms, target pause time: %1.2fms",
431 eden_region_length, survivor_region_length, _inc_predicted_elapsed_time_ms, target_pause_time_ms);
432
433 // The number of recorded young regions is the incremental
434 // collection set's current size
435 set_recorded_rs_lengths(_inc_recorded_rs_lengths);
436
437 double young_end_time_sec = os::elapsedTime();
438 phase_times()->record_young_cset_choice_time_ms((young_end_time_sec - young_start_time_sec) * 1000.0);
439
440 return time_remaining_ms;
441 }
442
443 void G1CollectionSet::add_as_old(HeapRegion* hr) {
444 candidates()->pop_front(); // already have region via peek()
445 _g1h->old_set_remove(hr);
446 add_old_region(hr);
447 }
448
449 void G1CollectionSet::add_as_optional(HeapRegion* hr) {
450 assert(_optional_regions != NULL, "Must not be called before array is allocated");
451 candidates()->pop_front(); // already have region via peek()
452 _g1h->old_set_remove(hr);
453 add_optional_region(hr);
454 }
455
456 bool G1CollectionSet::optional_is_full() {
457 assert(_optional_region_length <= _optional_region_max_length, "Invariant");
458 return _optional_region_length == _optional_region_max_length;
459 }
460
461 void G1CollectionSet::clear_optional_region(const HeapRegion* hr) {
462 assert(_optional_regions != NULL, "Must not be called before array is allocated");
463 uint index = hr->index_in_opt_cset();
464 _optional_regions[index] = NULL;
465 }
466
467 static int compare_region_idx(const uint a, const uint b) {
468 if (a > b) {
469 return 1;
470 } else if (a == b) {
471 return 0;
472 } else {
473 return -1;
474 }
475 }
476
477 void G1CollectionSet::finalize_old_part(double time_remaining_ms) {
478 double non_young_start_time_sec = os::elapsedTime();
479 double predicted_old_time_ms = 0.0;
480 double predicted_optional_time_ms = 0.0;
481 double optional_threshold_ms = time_remaining_ms * _policy->optional_prediction_fraction();
482 uint expensive_region_num = 0;
483
484 if (collector_state()->in_mixed_phase()) {
485 candidates()->verify();
486 const uint min_old_cset_length = _policy->calc_min_old_cset_length();
487 const uint max_old_cset_length = MAX2(min_old_cset_length, _policy->calc_max_old_cset_length());
488 bool check_time_remaining = _policy->adaptive_young_list_length();
489
490 initialize_optional(max_old_cset_length - min_old_cset_length);
491 log_debug(gc, ergo, cset)("Start adding old regions for mixed gc. min %u regions, max %u regions, "
492 "time remaining %1.2fms, optional threshold %1.2fms",
493 min_old_cset_length, max_old_cset_length, time_remaining_ms, optional_threshold_ms);
494
495 HeapRegion* hr = candidates()->peek_front();
496 while (hr != NULL) {
497 if (old_region_length() + optional_region_length() >= max_old_cset_length) {
498 // Added maximum number of old regions to the CSet.
499 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (old CSet region num reached max). "
500 "old %u regions, optional %u regions",
501 old_region_length(), optional_region_length());
502 break;
503 }
504
505 // Stop adding regions if the remaining reclaimable space is
506 // not above G1HeapWastePercent.
507 size_t reclaimable_bytes = candidates()->remaining_reclaimable_bytes();
508 double reclaimable_percent = _policy->reclaimable_bytes_percent(reclaimable_bytes);
509 double threshold = (double) G1HeapWastePercent;
510 if (reclaimable_percent <= threshold) {
511 // We've added enough old regions that the amount of uncollected
512 // reclaimable space is at or below the waste threshold. Stop
513 // adding old regions to the CSet.
514 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (reclaimable percentage not over threshold). "
515 "reclaimable: " SIZE_FORMAT "%s (%1.2f%%) threshold: " UINTX_FORMAT "%%",
516 byte_size_in_proper_unit(reclaimable_bytes), proper_unit_for_byte_size(reclaimable_bytes),
517 reclaimable_percent, G1HeapWastePercent);
518 break;
519 }
520
521 double predicted_time_ms = predict_region_elapsed_time_ms(hr);
522 time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0);
523 // Add regions to old set until we reach minimum amount
524 if (old_region_length() < min_old_cset_length) {
525 predicted_old_time_ms += predicted_time_ms;
526 add_as_old(hr);
527 // Record the number of regions added when no time remaining
528 if (time_remaining_ms == 0.0) {
529 expensive_region_num++;
530 }
531 } else {
532 // In the non-auto-tuning case, we'll finish adding regions
533 // to the CSet if we reach the minimum.
534 if (!check_time_remaining) {
535 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (old CSet region num reached min).");
536 break;
537 }
538 // Keep adding regions to old set until we reach optional threshold
539 if (time_remaining_ms > optional_threshold_ms) {
540 predicted_old_time_ms += predicted_time_ms;
541 add_as_old(hr);
542 } else if (time_remaining_ms > 0) {
543 // Keep adding optional regions until time is up
544 if (!optional_is_full()) {
545 predicted_optional_time_ms += predicted_time_ms;
546 add_as_optional(hr);
547 } else {
548 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (optional set full).");
549 break;
550 }
551 } else {
552 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (predicted time is too high).");
553 break;
554 }
555 }
556 hr = candidates()->peek_front();
557 }
558 if (hr == NULL) {
559 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (candidate old regions not available)");
560 }
561
562 candidates()->verify();
563 }
564
565 stop_incremental_building();
566
567 log_debug(gc, ergo, cset)("Finish choosing CSet regions old: %u, optional: %u, "
568 "predicted old time: %1.2fms, predicted optional time: %1.2fms, time remaining: %1.2f",
569 old_region_length(), optional_region_length(),
570 predicted_old_time_ms, predicted_optional_time_ms, time_remaining_ms);
571 if (expensive_region_num > 0) {
572 log_debug(gc, ergo, cset)("CSet contains %u old regions that were added although the predicted time was too high.",
573 expensive_region_num);
574 }
575
576 double non_young_end_time_sec = os::elapsedTime();
577 phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
578
579 QuickSort::sort(_collection_set_regions, _collection_set_cur_length, compare_region_idx, true);
580 }
581
582 HeapRegion* G1OptionalCSet::region_at(uint index) {
583 return _cset->optional_region_at(index);
584 }
585
586 void G1OptionalCSet::prepare_evacuation(double time_limit) {
587 assert(_current_index == _current_limit, "Before prepare no regions should be ready for evac");
588
589 uint prepared_regions = 0;
590 double prediction_ms = 0;
591
592 _prepare_failed = true;
593 for (uint i = _current_index; i < _cset->optional_region_length(); i++) {
594 HeapRegion* hr = region_at(i);
595 prediction_ms += _cset->predict_region_elapsed_time_ms(hr);
596 if (prediction_ms > time_limit) {
597 log_debug(gc, cset)("Prepared %u regions for optional evacuation. Predicted time: %.3fms", prepared_regions, prediction_ms);
598 return;
599 }
600
601 // This region will be included in the next optional evacuation.
602 prepare_to_evacuate_optional_region(hr);
603 prepared_regions++;
604 _current_limit++;
605 _prepare_failed = false;
606 }
607
608 log_debug(gc, cset)("Prepared all %u regions for optional evacuation. Predicted time: %.3fms",
609 prepared_regions, prediction_ms);
610 }
611
612 bool G1OptionalCSet::prepare_failed() {
613 return _prepare_failed;
614 }
615
616 void G1OptionalCSet::complete_evacuation() {
617 _evacuation_failed = false;
618 for (uint i = _current_index; i < _current_limit; i++) {
619 HeapRegion* hr = region_at(i);
620 _cset->clear_optional_region(hr);
621 if (hr->evacuation_failed()){
622 _evacuation_failed = true;
623 }
624 }
625 _current_index = _current_limit;
626 }
627
628 bool G1OptionalCSet::evacuation_failed() {
629 return _evacuation_failed;
630 }
631
632 G1OptionalCSet::~G1OptionalCSet() {
633 G1CollectedHeap* g1h = G1CollectedHeap::heap();
634 while (!is_empty()) {
635 // We want to return regions not evacuated to the collection set candidates
636 // in reverse order to maintain the old order.
637 HeapRegion* hr = _cset->remove_last_optional_region();
638 assert(hr != NULL, "Should be valid region left");
639 _pset->record_unused_optional_region(hr);
640 g1h->old_set_add(hr);
641 g1h->clear_in_cset(hr);
642 hr->set_index_in_opt_cset(InvalidCSetIndex);
643 _cset->candidates()->push_front(hr);
644 }
645 _cset->free_optional_regions();
646 }
647
648 uint G1OptionalCSet::size() {
649 return _cset->optional_region_length() - _current_index;
650 }
651
652 bool G1OptionalCSet::is_empty() {
653 return size() == 0;
654 }
655
656 void G1OptionalCSet::prepare_to_evacuate_optional_region(HeapRegion* hr) {
657 log_trace(gc, cset)("Adding region %u for optional evacuation", hr->hrm_index());
658 G1CollectedHeap::heap()->clear_in_cset(hr);
659 _cset->add_old_region(hr);
660 }
661
662 #ifdef ASSERT
663 class G1VerifyYoungCSetIndicesClosure : public HeapRegionClosure {
664 private:
665 size_t _young_length;
666 int* _heap_region_indices;
667 public:
668 G1VerifyYoungCSetIndicesClosure(size_t young_length) : HeapRegionClosure(), _young_length(young_length) {
669 _heap_region_indices = NEW_C_HEAP_ARRAY(int, young_length, mtGC);
670 for (size_t i = 0; i < young_length; i++) {
671 _heap_region_indices[i] = -1;
672 }
673 }
674 ~G1VerifyYoungCSetIndicesClosure() {
675 FREE_C_HEAP_ARRAY(int, _heap_region_indices);
676 }
677
678 virtual bool do_heap_region(HeapRegion* r) {
679 const int idx = r->young_index_in_cset();
|
42 }
43
44 G1GCPhaseTimes* G1CollectionSet::phase_times() {
45 return _policy->phase_times();
46 }
47
48 double G1CollectionSet::predict_region_elapsed_time_ms(HeapRegion* hr) {
49 return _policy->predict_region_elapsed_time_ms(hr, collector_state()->in_young_only_phase());
50 }
51
52 G1CollectionSet::G1CollectionSet(G1CollectedHeap* g1h, G1Policy* policy) :
53 _g1h(g1h),
54 _policy(policy),
55 _candidates(NULL),
56 _eden_region_length(0),
57 _survivor_region_length(0),
58 _old_region_length(0),
59 _collection_set_regions(NULL),
60 _collection_set_cur_length(0),
61 _collection_set_max_length(0),
62 _num_optional_regions(0),
63 _bytes_used_before(0),
64 _recorded_rs_lengths(0),
65 _inc_build_state(Inactive),
66 _inc_bytes_used_before(0),
67 _inc_recorded_rs_lengths(0),
68 _inc_recorded_rs_lengths_diffs(0),
69 _inc_predicted_elapsed_time_ms(0.0),
70 _inc_predicted_elapsed_time_ms_diffs(0.0) {
71 }
72
73 G1CollectionSet::~G1CollectionSet() {
74 if (_collection_set_regions != NULL) {
75 FREE_C_HEAP_ARRAY(uint, _collection_set_regions);
76 }
77 free_optional_regions();
78 clear_candidates();
79 }
80
81 void G1CollectionSet::init_region_lengths(uint eden_cset_region_length,
82 uint survivor_cset_region_length) {
83 assert_at_safepoint_on_vm_thread();
84
85 _eden_region_length = eden_cset_region_length;
86 _survivor_region_length = survivor_cset_region_length;
87
88 assert((size_t) young_region_length() == _collection_set_cur_length,
89 "Young region length %u should match collection set length " SIZE_FORMAT, young_region_length(), _collection_set_cur_length);
90
91 _old_region_length = 0;
92 _num_optional_regions = 0;
93 }
94
95 void G1CollectionSet::initialize(uint max_region_length) {
96 guarantee(_collection_set_regions == NULL, "Must only initialize once.");
97 _collection_set_max_length = max_region_length;
98 _collection_set_regions = NEW_C_HEAP_ARRAY(uint, max_region_length, mtGC);
99 }
100
101 void G1CollectionSet::free_optional_regions() {
102 _num_optional_regions = 0;
103 }
104
105 void G1CollectionSet::clear_candidates() {
106 delete _candidates;
107 _candidates = NULL;
108 }
109
110 void G1CollectionSet::set_recorded_rs_lengths(size_t rs_lengths) {
111 _recorded_rs_lengths = rs_lengths;
112 }
113
114 // Add the heap region at the head of the non-incremental collection set
115 void G1CollectionSet::add_old_region(HeapRegion* hr) {
116 assert_at_safepoint_on_vm_thread();
117
118 assert(_inc_build_state == Active,
119 "Precondition, actively building cset or adding optional later on");
120 assert(hr->is_old(), "the region should be old");
121
122 assert(!hr->in_collection_set(), "should not already be in the collection set");
123 _g1h->register_old_region_with_cset(hr);
124
125 _collection_set_regions[_collection_set_cur_length++] = hr->hrm_index();
126 assert(_collection_set_cur_length <= _collection_set_max_length, "Collection set now larger than maximum size.");
127
128 _bytes_used_before += hr->used();
129 _recorded_rs_lengths += hr->rem_set()->occupied();
130 _old_region_length++;
131
132 _g1h->old_set_remove(hr);
133 }
134
135 void G1CollectionSet::add_optional_region(HeapRegion* hr) {
136 assert(hr->is_old(), "the region should be old");
137 assert(!hr->in_collection_set(), "should not already be in the CSet");
138
139 _g1h->register_optional_region_with_cset(hr);
140
141 hr->set_index_in_opt_cset(_num_optional_regions++);
142 }
143
144 void G1CollectionSet::start_incremental_building() {
145 assert(_collection_set_cur_length == 0, "Collection set must be empty before starting a new collection set.");
146 assert(_inc_build_state == Inactive, "Precondition");
147
148 _inc_bytes_used_before = 0;
149
150 _inc_recorded_rs_lengths = 0;
151 _inc_recorded_rs_lengths_diffs = 0;
152 _inc_predicted_elapsed_time_ms = 0.0;
153 _inc_predicted_elapsed_time_ms_diffs = 0.0;
154
155 update_incremental_marker();
156 }
157
158 void G1CollectionSet::finalize_young_increment() {
159 assert(_inc_build_state == Active, "Precondition");
160 assert(SafepointSynchronize::is_at_safepoint(), "should be at a safepoint");
161
162 // The two "main" fields, _inc_recorded_rs_lengths and
163 // _inc_predicted_elapsed_time_ms, are updated by the thread
164 // that adds a new region to the CSet. Further updates by the
165 // concurrent refinement thread that samples the young RSet lengths
166 // are accumulated in the *_diffs fields. Here we add the diffs to
167 // the "main" fields.
168
169 if (_inc_recorded_rs_lengths_diffs >= 0) {
170 _inc_recorded_rs_lengths += _inc_recorded_rs_lengths_diffs;
171 } else {
172 // This is defensive. The diff should in theory be always positive
173 // as RSets can only grow between GCs. However, given that we
174 // sample their size concurrently with other threads updating them
175 // it's possible that we might get the wrong size back, which
176 // could make the calculations somewhat inaccurate.
177 size_t diffs = (size_t) (-_inc_recorded_rs_lengths_diffs);
178 if (_inc_recorded_rs_lengths >= diffs) {
179 _inc_recorded_rs_lengths -= diffs;
180 } else {
181 _inc_recorded_rs_lengths = 0;
182 }
183 }
184 _inc_predicted_elapsed_time_ms += _inc_predicted_elapsed_time_ms_diffs;
185
186 _inc_recorded_rs_lengths_diffs = 0;
187 _inc_predicted_elapsed_time_ms_diffs = 0.0;
188 }
189
190 void G1CollectionSet::clear() {
191 assert_at_safepoint_on_vm_thread();
192 _collection_set_cur_length = 0;
193 }
194
195 void G1CollectionSet::iterate(HeapRegionClosure* cl) const {
196 size_t len = _collection_set_cur_length;
197 OrderAccess::loadload();
198
199 for (uint i = 0; i < len; i++) {
200 HeapRegion* r = _g1h->region_at(_collection_set_regions[i]);
201 bool result = cl->do_heap_region(r);
202 if (result) {
203 cl->set_incomplete();
204 return;
205 }
206 }
207 }
208
209 void G1CollectionSet::iterate_optional(HeapRegionClosure* cl) const {
210 assert_at_safepoint();
211
212 for (uint i = 0; i < _num_optional_regions; i++) {
213 HeapRegion* r = _candidates->at(i);
214 bool result = cl->do_heap_region(r);
215 guarantee(!result, "Must not cancel iteration");
216 }
217 }
218
219 void G1CollectionSet::iterate_incremental_part_from(HeapRegionClosure* cl, uint worker_id, uint total_workers) const {
220 assert_at_safepoint();
221
222 size_t len = _collection_set_cur_length - _inc_part_start;
223 if (len == 0) {
224 return;
225 }
226
227 size_t start_pos = (worker_id * len) / total_workers;
228 size_t cur_pos = start_pos;
229
230 do {
231 HeapRegion* r = _g1h->region_at(_collection_set_regions[cur_pos + _inc_part_start]);
232 bool result = cl->do_heap_region(r);
233 guarantee(!result, "Must not cancel iteration");
234
235 cur_pos++;
236 if (cur_pos == len) {
237 cur_pos = 0;
238 }
239 } while (cur_pos != start_pos);
240 }
241
242 void G1CollectionSet::update_young_region_prediction(HeapRegion* hr,
243 size_t new_rs_length) {
244 // Update the CSet information that is dependent on the new RS length
245 assert(hr->is_young(), "Precondition");
246 assert(!SafepointSynchronize::is_at_safepoint(), "should not be at a safepoint");
247
248 // We could have updated _inc_recorded_rs_lengths and
249 // _inc_predicted_elapsed_time_ms directly but we'd need to do
250 // that atomically, as this code is executed by a concurrent
251 // refinement thread, potentially concurrently with a mutator thread
252 // allocating a new region and also updating the same fields. To
253 // avoid the atomic operations we accumulate these updates on two
254 // separate fields (*_diffs) and we'll just add them to the "main"
380 _st->print_cr(" " HR_FORMAT ", P: " PTR_FORMAT "N: " PTR_FORMAT ", age: %4d",
381 HR_FORMAT_PARAMS(r),
382 p2i(r->prev_top_at_mark_start()),
383 p2i(r->next_top_at_mark_start()),
384 r->age_in_surv_rate_group_cond());
385 return false;
386 }
387 };
388
389 void G1CollectionSet::print(outputStream* st) {
390 st->print_cr("\nCollection_set:");
391
392 G1PrintCollectionSetDetailClosure cl(st);
393 iterate(&cl);
394 }
395 #endif // !PRODUCT
396
397 double G1CollectionSet::finalize_young_part(double target_pause_time_ms, G1SurvivorRegions* survivors) {
398 double young_start_time_sec = os::elapsedTime();
399
400 finalize_young_increment();
401
402 guarantee(target_pause_time_ms > 0.0,
403 "target_pause_time_ms = %1.6lf should be positive", target_pause_time_ms);
404
405 size_t pending_cards = _policy->pending_cards();
406 double base_time_ms = _policy->predict_base_elapsed_time_ms(pending_cards);
407 double time_remaining_ms = MAX2(target_pause_time_ms - base_time_ms, 0.0);
408
409 log_trace(gc, ergo, cset)("Start choosing CSet. pending cards: " SIZE_FORMAT " predicted base time: %1.2fms remaining time: %1.2fms target pause time: %1.2fms",
410 pending_cards, base_time_ms, time_remaining_ms, target_pause_time_ms);
411
412 // The young list is laid with the survivor regions from the previous
413 // pause are appended to the RHS of the young list, i.e.
414 // [Newly Young Regions ++ Survivors from last pause].
415
416 uint survivor_region_length = survivors->length();
417 uint eden_region_length = _g1h->eden_regions_count();
418 init_region_lengths(eden_region_length, survivor_region_length);
419
420 verify_young_cset_indices();
421
422 // Clear the fields that point to the survivor list - they are all young now.
423 survivors->convert_to_eden();
424
425 _bytes_used_before = _inc_bytes_used_before;
426 time_remaining_ms = MAX2(time_remaining_ms - _inc_predicted_elapsed_time_ms, 0.0);
427
428 log_trace(gc, ergo, cset)("Add young regions to CSet. eden: %u regions, survivors: %u regions, predicted young region time: %1.2fms, target pause time: %1.2fms",
429 eden_region_length, survivor_region_length, _inc_predicted_elapsed_time_ms, target_pause_time_ms);
430
431 // The number of recorded young regions is the incremental
432 // collection set's current size
433 set_recorded_rs_lengths(_inc_recorded_rs_lengths);
434
435 double young_end_time_sec = os::elapsedTime();
436 phase_times()->record_young_cset_choice_time_ms((young_end_time_sec - young_start_time_sec) * 1000.0);
437
438 return time_remaining_ms;
439 }
440
441 static int compare_region_idx(const uint a, const uint b) {
442 if (a > b) {
443 return 1;
444 } else if (a == b) {
445 return 0;
446 } else {
447 return -1;
448 }
449 }
450
451 void G1CollectionSet::finalize_old_part(double time_remaining_ms) {
452 double non_young_start_time_sec = os::elapsedTime();
453
454 uint num_expensive_regions = 0;
455
456 if (collector_state()->in_mixed_phase()) {
457 candidates()->verify();
458
459 uint num_initial_regions;
460 uint num_optional_regions;
461
462 _policy->select_old_collection_set_regions(candidates(),
463 time_remaining_ms,
464 num_expensive_regions,
465 num_initial_regions,
466 num_optional_regions);
467
468 // Prepare initial old regions.
469 move_candidates_to_collection_set(num_initial_regions);
470
471 // Prepare optional regions for evacuation.
472 uint candidate_idx = candidates()->cur_idx();
473 for (uint i = 0; i < num_optional_regions; i++) {
474 add_optional_region(candidates()->at(candidate_idx + i));
475 }
476
477 candidates()->verify();
478 }
479
480 stop_incremental_building();
481
482 double non_young_end_time_sec = os::elapsedTime();
483 phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
484
485 QuickSort::sort(_collection_set_regions, _collection_set_cur_length, compare_region_idx, true);
486 }
487
488 void G1CollectionSet::move_candidates_to_collection_set(uint num_old_candidate_regions) {
489 if (num_old_candidate_regions == 0) {
490 return;
491 }
492 uint candidate_idx = candidates()->cur_idx();
493 for (uint i = 0; i < num_old_candidate_regions; i++) {
494 HeapRegion* r = candidates()->at(candidate_idx + i);
495 // This potentially optional candidate region is going to be an actual collection
496 // set region. Clear cset marker.
497 _g1h->clear_in_cset(r);
498 add_old_region(r);
499 }
500 candidates()->remove(num_old_candidate_regions);
501
502 candidates()->verify();
503 }
504
505 void G1CollectionSet::finalize_initial_collection_set(double target_pause_time_ms, G1SurvivorRegions* survivor) {
506 double time_remaining_ms = finalize_young_part(target_pause_time_ms, survivor);
507 finalize_old_part(time_remaining_ms);
508 }
509
510 bool G1CollectionSet::finalize_optional_for_evacuation(double remaining_pause_time) {
511 update_incremental_marker();
512
513 uint num_selected_regions;
514 _policy->select_optional_collection_set_regions(candidates(),
515 _num_optional_regions,
516 remaining_pause_time,
517 num_selected_regions);
518
519 move_candidates_to_collection_set(num_selected_regions);
520
521 _num_optional_regions -= num_selected_regions;
522
523 stop_incremental_building();
524 return num_selected_regions > 0;
525 }
526
527 void G1CollectionSet::abandon_optional_collection_set(G1ParScanThreadStateSet* pss) {
528 for (uint i = 0; i < _num_optional_regions; i++) {
529 HeapRegion* r = candidates()->at(candidates()->cur_idx() + i);
530 pss->record_unused_optional_region(r);
531 _g1h->clear_in_cset(r);
532 r->clear_index_in_opt_cset();
533 }
534 _num_optional_regions = 0;
535 }
536
537 #ifdef ASSERT
538 class G1VerifyYoungCSetIndicesClosure : public HeapRegionClosure {
539 private:
540 size_t _young_length;
541 int* _heap_region_indices;
542 public:
543 G1VerifyYoungCSetIndicesClosure(size_t young_length) : HeapRegionClosure(), _young_length(young_length) {
544 _heap_region_indices = NEW_C_HEAP_ARRAY(int, young_length, mtGC);
545 for (size_t i = 0; i < young_length; i++) {
546 _heap_region_indices[i] = -1;
547 }
548 }
549 ~G1VerifyYoungCSetIndicesClosure() {
550 FREE_C_HEAP_ARRAY(int, _heap_region_indices);
551 }
552
553 virtual bool do_heap_region(HeapRegion* r) {
554 const int idx = r->young_index_in_cset();
|