6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/g1/g1CollectedHeap.hpp"
27 #include "gc/g1/g1CollectionSet.hpp"
28 #include "gc/g1/g1CollectorState.hpp"
29 #include "gc/g1/g1Policy.hpp"
30 #include "gc/g1/heapRegion.inline.hpp"
31 #include "gc/g1/heapRegionRemSet.hpp"
32 #include "gc/g1/heapRegionSet.hpp"
33 #include "logging/logStream.hpp"
34 #include "utilities/debug.hpp"
35 #include "utilities/quickSort.hpp"
36
37 G1CollectorState* G1CollectionSet::collector_state() {
38 return _g1h->collector_state();
39 }
40
41 G1GCPhaseTimes* G1CollectionSet::phase_times() {
42 return _policy->phase_times();
43 }
44
45 CollectionSetChooser* G1CollectionSet::cset_chooser() {
46 return _cset_chooser;
47 }
48
49 double G1CollectionSet::predict_region_elapsed_time_ms(HeapRegion* hr) {
50 return _policy->predict_region_elapsed_time_ms(hr, collector_state()->in_young_only_phase());
51 }
52
53 G1CollectionSet::G1CollectionSet(G1CollectedHeap* g1h, G1Policy* policy) :
54 _g1h(g1h),
55 _policy(policy),
56 _cset_chooser(new CollectionSetChooser()),
57 _eden_region_length(0),
58 _survivor_region_length(0),
59 _old_region_length(0),
60 _collection_set_regions(NULL),
61 _collection_set_cur_length(0),
62 _collection_set_max_length(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 delete _cset_chooser;
78 }
79
80 void G1CollectionSet::init_region_lengths(uint eden_cset_region_length,
81 uint survivor_cset_region_length) {
82 assert_at_safepoint_on_vm_thread();
83
84 _eden_region_length = eden_cset_region_length;
85 _survivor_region_length = survivor_cset_region_length;
86
87 assert((size_t) young_region_length() == _collection_set_cur_length,
88 "Young region length %u should match collection set length " SIZE_FORMAT, young_region_length(), _collection_set_cur_length);
89
90 _old_region_length = 0;
91 }
92
93 void G1CollectionSet::initialize(uint max_region_length) {
94 guarantee(_collection_set_regions == NULL, "Must only initialize once.");
95 _collection_set_max_length = max_region_length;
96 _collection_set_regions = NEW_C_HEAP_ARRAY(uint, max_region_length, mtGC);
97 }
98
99 void G1CollectionSet::set_recorded_rs_lengths(size_t rs_lengths) {
100 _recorded_rs_lengths = rs_lengths;
101 }
102
103 // Add the heap region at the head of the non-incremental collection set
104 void G1CollectionSet::add_old_region(HeapRegion* hr) {
105 assert_at_safepoint_on_vm_thread();
106
107 assert(_inc_build_state == Active, "Precondition");
108 assert(hr->is_old(), "the region should be old");
109
110 assert(!hr->in_collection_set(), "should not already be in the CSet");
111 _g1h->register_old_region_with_cset(hr);
112
113 _collection_set_regions[_collection_set_cur_length++] = hr->hrm_index();
114 assert(_collection_set_cur_length <= _collection_set_max_length, "Collection set now larger than maximum size.");
115
116 _bytes_used_before += hr->used();
117 size_t rs_length = hr->rem_set()->occupied();
118 _recorded_rs_lengths += rs_length;
119 _old_region_length += 1;
120 }
121
122 // Initialize the per-collection-set information
123 void G1CollectionSet::start_incremental_building() {
124 assert(_collection_set_cur_length == 0, "Collection set must be empty before starting a new collection set.");
125 assert(_inc_build_state == Inactive, "Precondition");
126
127 _inc_bytes_used_before = 0;
128
129 _inc_recorded_rs_lengths = 0;
130 _inc_recorded_rs_lengths_diffs = 0;
131 _inc_predicted_elapsed_time_ms = 0.0;
132 _inc_predicted_elapsed_time_ms_diffs = 0.0;
133 _inc_build_state = Active;
134 }
135
136 void G1CollectionSet::finalize_incremental_building() {
137 assert(_inc_build_state == Active, "Precondition");
138 assert(SafepointSynchronize::is_at_safepoint(), "should be at a safepoint");
139
151 // as RSets can only grow between GCs. However, given that we
152 // sample their size concurrently with other threads updating them
153 // it's possible that we might get the wrong size back, which
154 // could make the calculations somewhat inaccurate.
155 size_t diffs = (size_t) (-_inc_recorded_rs_lengths_diffs);
156 if (_inc_recorded_rs_lengths >= diffs) {
157 _inc_recorded_rs_lengths -= diffs;
158 } else {
159 _inc_recorded_rs_lengths = 0;
160 }
161 }
162 _inc_predicted_elapsed_time_ms += _inc_predicted_elapsed_time_ms_diffs;
163
164 _inc_recorded_rs_lengths_diffs = 0;
165 _inc_predicted_elapsed_time_ms_diffs = 0.0;
166 }
167
168 void G1CollectionSet::clear() {
169 assert_at_safepoint_on_vm_thread();
170 _collection_set_cur_length = 0;
171 }
172
173 void G1CollectionSet::iterate(HeapRegionClosure* cl) const {
174 iterate_from(cl, 0, 1);
175 }
176
177 void G1CollectionSet::iterate_from(HeapRegionClosure* cl, uint worker_id, uint total_workers) const {
178 size_t len = _collection_set_cur_length;
179 OrderAccess::loadload();
180 if (len == 0) {
181 return;
182 }
183 size_t start_pos = (worker_id * len) / total_workers;
184 size_t cur_pos = start_pos;
185
186 do {
187 HeapRegion* r = _g1h->region_at(_collection_set_regions[cur_pos]);
188 bool result = cl->do_heap_region(r);
189 if (result) {
190 cl->set_incomplete();
379
380 // Clear the fields that point to the survivor list - they are all young now.
381 survivors->convert_to_eden();
382
383 _bytes_used_before = _inc_bytes_used_before;
384 time_remaining_ms = MAX2(time_remaining_ms - _inc_predicted_elapsed_time_ms, 0.0);
385
386 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",
387 eden_region_length, survivor_region_length, _inc_predicted_elapsed_time_ms, target_pause_time_ms);
388
389 // The number of recorded young regions is the incremental
390 // collection set's current size
391 set_recorded_rs_lengths(_inc_recorded_rs_lengths);
392
393 double young_end_time_sec = os::elapsedTime();
394 phase_times()->record_young_cset_choice_time_ms((young_end_time_sec - young_start_time_sec) * 1000.0);
395
396 return time_remaining_ms;
397 }
398
399 static int compare_region_idx(const uint a, const uint b) {
400 if (a > b) {
401 return 1;
402 } else if (a == b) {
403 return 0;
404 } else {
405 return -1;
406 }
407 }
408
409 void G1CollectionSet::finalize_old_part(double time_remaining_ms) {
410 double non_young_start_time_sec = os::elapsedTime();
411 double predicted_old_time_ms = 0.0;
412
413 if (collector_state()->in_mixed_phase()) {
414 cset_chooser()->verify();
415 const uint min_old_cset_length = _policy->calc_min_old_cset_length();
416 const uint max_old_cset_length = _policy->calc_max_old_cset_length();
417
418 uint expensive_region_num = 0;
419 bool check_time_remaining = _policy->adaptive_young_list_length();
420
421 HeapRegion* hr = cset_chooser()->peek();
422 while (hr != NULL) {
423 if (old_region_length() >= max_old_cset_length) {
424 // Added maximum number of old regions to the CSet.
425 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (old CSet region num reached max). old %u regions, max %u regions",
426 old_region_length(), max_old_cset_length);
427 break;
428 }
429
430 // Stop adding regions if the remaining reclaimable space is
431 // not above G1HeapWastePercent.
432 size_t reclaimable_bytes = cset_chooser()->remaining_reclaimable_bytes();
433 double reclaimable_percent = _policy->reclaimable_bytes_percent(reclaimable_bytes);
434 double threshold = (double) G1HeapWastePercent;
435 if (reclaimable_percent <= threshold) {
436 // We've added enough old regions that the amount of uncollected
437 // reclaimable space is at or below the waste threshold. Stop
438 // adding old regions to the CSet.
439 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (reclaimable percentage not over threshold). "
440 "old %u regions, max %u regions, reclaimable: " SIZE_FORMAT "B (%1.2f%%) threshold: " UINTX_FORMAT "%%",
441 old_region_length(), max_old_cset_length, reclaimable_bytes, reclaimable_percent, G1HeapWastePercent);
442 break;
443 }
444
445 double predicted_time_ms = predict_region_elapsed_time_ms(hr);
446 if (check_time_remaining) {
447 if (predicted_time_ms > time_remaining_ms) {
448 // Too expensive for the current CSet.
449
450 if (old_region_length() >= min_old_cset_length) {
451 // We have added the minimum number of old regions to the CSet,
452 // we are done with this CSet.
453 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (predicted time is too high). "
454 "predicted time: %1.2fms, remaining time: %1.2fms old %u regions, min %u regions",
455 predicted_time_ms, time_remaining_ms, old_region_length(), min_old_cset_length);
456 break;
457 }
458
459 // We'll add it anyway given that we haven't reached the
460 // minimum number of old regions.
461 expensive_region_num += 1;
462 }
463 } else {
464 if (old_region_length() >= min_old_cset_length) {
465 // In the non-auto-tuning case, we'll finish adding regions
466 // to the CSet if we reach the minimum.
467
468 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (old CSet region num reached min). old %u regions, min %u regions",
469 old_region_length(), min_old_cset_length);
470 break;
471 }
472 }
473
474 // We will add this region to the CSet.
475 time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0);
476 predicted_old_time_ms += predicted_time_ms;
477 cset_chooser()->pop(); // already have region via peek()
478 _g1h->old_set_remove(hr);
479 add_old_region(hr);
480
481 hr = cset_chooser()->peek();
482 }
483 if (hr == NULL) {
484 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (candidate old regions not available)");
485 }
486
487 if (expensive_region_num > 0) {
488 // We print the information once here at the end, predicated on
489 // whether we added any apparently expensive regions or not, to
490 // avoid generating output per region.
491 log_debug(gc, ergo, cset)("Added expensive regions to CSet (old CSet region num not reached min)."
492 "old: %u regions, expensive: %u regions, min: %u regions, remaining time: %1.2fms",
493 old_region_length(), expensive_region_num, min_old_cset_length, time_remaining_ms);
494 }
495
496 cset_chooser()->verify();
497 }
498
499 stop_incremental_building();
500
501 log_debug(gc, ergo, cset)("Finish choosing CSet. old: %u regions, predicted old region time: %1.2fms, time remaining: %1.2f",
502 old_region_length(), predicted_old_time_ms, time_remaining_ms);
503
504 double non_young_end_time_sec = os::elapsedTime();
505 phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
506
507 QuickSort::sort(_collection_set_regions, _collection_set_cur_length, compare_region_idx, true);
508 }
509
510 #ifdef ASSERT
511 class G1VerifyYoungCSetIndicesClosure : public HeapRegionClosure {
512 private:
513 size_t _young_length;
514 int* _heap_region_indices;
515 public:
516 G1VerifyYoungCSetIndicesClosure(size_t young_length) : HeapRegionClosure(), _young_length(young_length) {
517 _heap_region_indices = NEW_C_HEAP_ARRAY(int, young_length, mtGC);
518 for (size_t i = 0; i < young_length; i++) {
519 _heap_region_indices[i] = -1;
520 }
521 }
522 ~G1VerifyYoungCSetIndicesClosure() {
523 FREE_C_HEAP_ARRAY(int, _heap_region_indices);
524 }
525
526 virtual bool do_heap_region(HeapRegion* r) {
527 const int idx = r->young_index_in_cset();
|
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/g1/g1CollectedHeap.inline.hpp"
27 #include "gc/g1/g1CollectionSet.hpp"
28 #include "gc/g1/g1CollectorState.hpp"
29 #include "gc/g1/g1Policy.hpp"
30 #include "gc/g1/heapRegion.inline.hpp"
31 #include "gc/g1/heapRegionRemSet.hpp"
32 #include "gc/g1/heapRegionSet.hpp"
33 #include "logging/logStream.hpp"
34 #include "utilities/debug.hpp"
35 #include "utilities/globalDefinitions.hpp"
36 #include "utilities/quickSort.hpp"
37
38 G1CollectorState* G1CollectionSet::collector_state() {
39 return _g1h->collector_state();
40 }
41
42 G1GCPhaseTimes* G1CollectionSet::phase_times() {
43 return _policy->phase_times();
44 }
45
46 CollectionSetChooser* G1CollectionSet::cset_chooser() {
47 return _cset_chooser;
48 }
49
50 double G1CollectionSet::predict_region_elapsed_time_ms(HeapRegion* hr) {
51 return _policy->predict_region_elapsed_time_ms(hr, collector_state()->in_young_only_phase());
52 }
53
54 G1CollectionSet::G1CollectionSet(G1CollectedHeap* g1h, G1Policy* policy) :
55 _g1h(g1h),
56 _policy(policy),
57 _cset_chooser(new CollectionSetChooser()),
58 _eden_region_length(0),
59 _survivor_region_length(0),
60 _old_region_length(0),
61 _collection_set_regions(NULL),
62 _collection_set_cur_length(0),
63 _collection_set_max_length(0),
64 _optional_regions(NULL),
65 _optional_region_length(0),
66 _optional_region_max_length(0),
67 _bytes_used_before(0),
68 _recorded_rs_lengths(0),
69 _inc_build_state(Inactive),
70 _inc_bytes_used_before(0),
71 _inc_recorded_rs_lengths(0),
72 _inc_recorded_rs_lengths_diffs(0),
73 _inc_predicted_elapsed_time_ms(0.0),
74 _inc_predicted_elapsed_time_ms_diffs(0.0) {
75 }
76
77 G1CollectionSet::~G1CollectionSet() {
78 if (_collection_set_regions != NULL) {
79 FREE_C_HEAP_ARRAY(uint, _collection_set_regions);
80 }
81 free_optional_regions();
82 delete _cset_chooser;
83 }
84
85 void G1CollectionSet::init_region_lengths(uint eden_cset_region_length,
86 uint survivor_cset_region_length) {
87 assert_at_safepoint_on_vm_thread();
88
89 _eden_region_length = eden_cset_region_length;
90 _survivor_region_length = survivor_cset_region_length;
91
92 assert((size_t) young_region_length() == _collection_set_cur_length,
93 "Young region length %u should match collection set length " SIZE_FORMAT, young_region_length(), _collection_set_cur_length);
94
95 _old_region_length = 0;
96 _optional_region_length = 0;
97 }
98
99 void G1CollectionSet::initialize(uint max_region_length) {
100 guarantee(_collection_set_regions == NULL, "Must only initialize once.");
101 _collection_set_max_length = max_region_length;
102 _collection_set_regions = NEW_C_HEAP_ARRAY(uint, max_region_length, mtGC);
103 }
104
105 void G1CollectionSet::initialize_optional(uint max_length) {
106 assert(_optional_regions == NULL, "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::set_recorded_rs_lengths(size_t rs_lengths) {
121 _recorded_rs_lengths = rs_lengths;
122 }
123
124 // Add the heap region at the head of the non-incremental collection set
125 void G1CollectionSet::add_old_region(HeapRegion* hr) {
126 assert_at_safepoint_on_vm_thread();
127
128 assert(_inc_build_state == Active || hr->index_in_opt_cset() != G1OptionalCSet::InvalidCSetIndex,
129 "Precondition, actively building cset or adding optional later on");
130 assert(hr->is_old(), "the region should be old");
131
132 assert(!hr->in_collection_set(), "should not already be in the CSet");
133 _g1h->register_old_region_with_cset(hr);
134
135 _collection_set_regions[_collection_set_cur_length++] = hr->hrm_index();
136 assert(_collection_set_cur_length <= _collection_set_max_length, "Collection set now larger than maximum size.");
137
138 _bytes_used_before += hr->used();
139 size_t rs_length = hr->rem_set()->occupied();
140 _recorded_rs_lengths += rs_length;
141 _old_region_length += 1;
142
143 log_trace(gc, cset)("Added old region %d to collection set", hr->hrm_index());
144 }
145
146 void G1CollectionSet::add_optional_region(HeapRegion* hr) {
147 assert(!optional_is_full(), "Precondition, must have room left for this region");
148 assert(hr->is_old(), "the region should be old");
149 assert(!hr->in_collection_set(), "should not already be in the CSet");
150
151 _g1h->register_optional_region_with_cset(hr);
152
153 _optional_regions[_optional_region_length] = hr;
154 uint index = _optional_region_length++;
155 hr->set_index_in_opt_cset(index);
156
157 log_trace(gc, cset)("Added region %d to optional collection set (%u)", hr->hrm_index(), _optional_region_length);
158 }
159
160 // Initialize the per-collection-set information
161 void G1CollectionSet::start_incremental_building() {
162 assert(_collection_set_cur_length == 0, "Collection set must be empty before starting a new collection set.");
163 assert(_inc_build_state == Inactive, "Precondition");
164
165 _inc_bytes_used_before = 0;
166
167 _inc_recorded_rs_lengths = 0;
168 _inc_recorded_rs_lengths_diffs = 0;
169 _inc_predicted_elapsed_time_ms = 0.0;
170 _inc_predicted_elapsed_time_ms_diffs = 0.0;
171 _inc_build_state = Active;
172 }
173
174 void G1CollectionSet::finalize_incremental_building() {
175 assert(_inc_build_state == Active, "Precondition");
176 assert(SafepointSynchronize::is_at_safepoint(), "should be at a safepoint");
177
189 // as RSets can only grow between GCs. However, given that we
190 // sample their size concurrently with other threads updating them
191 // it's possible that we might get the wrong size back, which
192 // could make the calculations somewhat inaccurate.
193 size_t diffs = (size_t) (-_inc_recorded_rs_lengths_diffs);
194 if (_inc_recorded_rs_lengths >= diffs) {
195 _inc_recorded_rs_lengths -= diffs;
196 } else {
197 _inc_recorded_rs_lengths = 0;
198 }
199 }
200 _inc_predicted_elapsed_time_ms += _inc_predicted_elapsed_time_ms_diffs;
201
202 _inc_recorded_rs_lengths_diffs = 0;
203 _inc_predicted_elapsed_time_ms_diffs = 0.0;
204 }
205
206 void G1CollectionSet::clear() {
207 assert_at_safepoint_on_vm_thread();
208 _collection_set_cur_length = 0;
209 _optional_region_length = 0;
210 }
211
212 void G1CollectionSet::iterate(HeapRegionClosure* cl) const {
213 iterate_from(cl, 0, 1);
214 }
215
216 void G1CollectionSet::iterate_from(HeapRegionClosure* cl, uint worker_id, uint total_workers) const {
217 size_t len = _collection_set_cur_length;
218 OrderAccess::loadload();
219 if (len == 0) {
220 return;
221 }
222 size_t start_pos = (worker_id * len) / total_workers;
223 size_t cur_pos = start_pos;
224
225 do {
226 HeapRegion* r = _g1h->region_at(_collection_set_regions[cur_pos]);
227 bool result = cl->do_heap_region(r);
228 if (result) {
229 cl->set_incomplete();
418
419 // Clear the fields that point to the survivor list - they are all young now.
420 survivors->convert_to_eden();
421
422 _bytes_used_before = _inc_bytes_used_before;
423 time_remaining_ms = MAX2(time_remaining_ms - _inc_predicted_elapsed_time_ms, 0.0);
424
425 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",
426 eden_region_length, survivor_region_length, _inc_predicted_elapsed_time_ms, target_pause_time_ms);
427
428 // The number of recorded young regions is the incremental
429 // collection set's current size
430 set_recorded_rs_lengths(_inc_recorded_rs_lengths);
431
432 double young_end_time_sec = os::elapsedTime();
433 phase_times()->record_young_cset_choice_time_ms((young_end_time_sec - young_start_time_sec) * 1000.0);
434
435 return time_remaining_ms;
436 }
437
438 void G1CollectionSet::add_as_old(HeapRegion* hr) {
439 cset_chooser()->pop(); // already have region via peek()
440 _g1h->old_set_remove(hr);
441 add_old_region(hr);
442 }
443
444 void G1CollectionSet::add_as_optional(HeapRegion* hr) {
445 assert(_optional_regions != NULL, "Must not be called before array is allocated");
446 cset_chooser()->pop(); // already have region via peek()
447 _g1h->old_set_remove(hr);
448 add_optional_region(hr);
449 }
450
451 bool G1CollectionSet::optional_is_full() {
452 return _optional_region_length == _optional_region_max_length;
453 }
454
455 void G1CollectionSet::clear_optional_region(const HeapRegion* hr) {
456 assert(_optional_regions != NULL, "Must not be called before array is allocated");
457 uint index = hr->index_in_opt_cset();
458 _optional_regions[index] = NULL;
459 }
460
461 static int compare_region_idx(const uint a, const uint b) {
462 if (a > b) {
463 return 1;
464 } else if (a == b) {
465 return 0;
466 } else {
467 return -1;
468 }
469 }
470
471 void G1CollectionSet::finalize_old_part(double time_remaining_ms) {
472 double non_young_start_time_sec = os::elapsedTime();
473 double predicted_old_time_ms = 0.0;
474 double predicted_optional_time_ms = 0.0;
475 double optional_threshold_ms = time_remaining_ms * _policy->optional_prediction_fraction();
476 uint expensive_region_num = 0;
477
478 if (collector_state()->in_mixed_phase()) {
479 cset_chooser()->verify();
480 const uint min_old_cset_length = _policy->calc_min_old_cset_length();
481 const uint max_old_cset_length = MAX2(min_old_cset_length, _policy->calc_max_old_cset_length());
482 bool check_time_remaining = _policy->adaptive_young_list_length();
483
484 initialize_optional(max_old_cset_length - min_old_cset_length);
485 log_debug(gc, ergo, cset)("Start adding old regions for mixed gc. min %u regions, max %u regions, "
486 "time remaining %1.2fms, optional threshold %1.2fms",
487 min_old_cset_length, max_old_cset_length, time_remaining_ms, optional_threshold_ms);
488
489 HeapRegion* hr = cset_chooser()->peek();
490 while (hr != NULL) {
491 if (old_region_length() + optional_region_length() >= max_old_cset_length) {
492 // Added maximum number of old regions to the CSet.
493 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (old CSet region num reached max). "
494 "old %u regions, optional %u regions",
495 old_region_length(), optional_region_length());
496 break;
497 }
498
499 // Stop adding regions if the remaining reclaimable space is
500 // not above G1HeapWastePercent.
501 size_t reclaimable_bytes = cset_chooser()->remaining_reclaimable_bytes();
502 double reclaimable_percent = _policy->reclaimable_bytes_percent(reclaimable_bytes);
503 double threshold = (double) G1HeapWastePercent;
504 if (reclaimable_percent <= threshold) {
505 // We've added enough old regions that the amount of uncollected
506 // reclaimable space is at or below the waste threshold. Stop
507 // adding old regions to the CSet.
508 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (reclaimable percentage not over threshold). "
509 "reclaimable: " SIZE_FORMAT "%s (%1.2f%%) threshold: " UINTX_FORMAT "%%",
510 byte_size_in_proper_unit(reclaimable_bytes), proper_unit_for_byte_size(reclaimable_bytes),
511 reclaimable_percent, G1HeapWastePercent);
512 break;
513 }
514
515 double predicted_time_ms = predict_region_elapsed_time_ms(hr);
516 time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0);
517 // Add regions to old set until we reach minimum amount
518 if (old_region_length() < min_old_cset_length) {
519 predicted_old_time_ms += predicted_time_ms;
520 add_as_old(hr);
521 // Record the number of regions added when no time remaining
522 if (time_remaining_ms == 0.0) {
523 expensive_region_num++;
524 }
525 } else {
526 // In the non-auto-tuning case, we'll finish adding regions
527 // to the CSet if we reach the minimum.
528 if (!check_time_remaining) {
529 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (old CSet region num reached min).");
530 break;
531 }
532 // Keep adding regions to old set until we reach optional threshold
533 if (time_remaining_ms > optional_threshold_ms) {
534 predicted_old_time_ms += predicted_time_ms;
535 add_as_old(hr);
536 } else if (time_remaining_ms > 0) {
537 // Keep adding optional regions until time is up
538 if (!optional_is_full()) {
539 predicted_optional_time_ms += predicted_time_ms;
540 add_as_optional(hr);
541 } else {
542 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (optional set full).");
543 break;
544 }
545 } else {
546 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (predicted time is too high).");
547 break;
548 }
549 }
550 hr = cset_chooser()->peek();
551 }
552 if (hr == NULL) {
553 log_debug(gc, ergo, cset)("Finish adding old regions to CSet (candidate old regions not available)");
554 }
555
556 cset_chooser()->verify();
557 }
558
559 stop_incremental_building();
560
561 log_debug(gc, ergo, cset)("Finish choosing CSet regions old: %u, optional: %u, "
562 "predicted old time: %1.2fms, predicted optional time: %1.2fms, time remaining: %1.2f",
563 old_region_length(), optional_region_length(),
564 predicted_old_time_ms, predicted_optional_time_ms, time_remaining_ms);
565 if (expensive_region_num > 0) {
566 log_debug(gc, ergo, cset)("CSet contains %u old regions that were added although the predicted time was too high.",
567 expensive_region_num);
568 }
569
570 double non_young_end_time_sec = os::elapsedTime();
571 phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
572
573 QuickSort::sort(_collection_set_regions, _collection_set_cur_length, compare_region_idx, true);
574 }
575
576 HeapRegion* G1OptionalCSet::region_at(uint index) {
577 return _cset->optional_region_at(index);
578 }
579
580 void G1OptionalCSet::prepare_evacuation(double time_limit) {
581 assert(_current_index == _current_limit, "Before prepare no regions should be ready for evac");
582
583 uint prepared_regions = 0;
584 double prediction_ms = 0;
585
586 _prepare_failed = true;
587 for (uint i = _current_index; i < _cset->optional_region_length(); i++) {
588 HeapRegion* hr = region_at(i);
589 prediction_ms += _cset->predict_region_elapsed_time_ms(hr);
590 if (prediction_ms > time_limit) {
591 log_debug(gc, cset)("Prepared %u regions for optional evacuation. Predicted time: %.3fms", prepared_regions, prediction_ms);
592 return;
593 }
594
595 // This region will be included in the next optional evacuation.
596 prepare_to_evacuate_optional_region(hr);
597 prepared_regions++;
598 _current_limit++;
599 _prepare_failed = false;
600 }
601
602 log_debug(gc, cset)("Prepared all %u regions for optional evacuation. Predicted time: %.3fms",
603 prepared_regions, prediction_ms);
604 }
605
606 bool G1OptionalCSet::prepare_failed() {
607 return _prepare_failed;
608 }
609
610 void G1OptionalCSet::complete_evacuation() {
611 _evacuation_failed = false;
612 for (uint i = _current_index; i < _current_limit; i++) {
613 HeapRegion* hr = region_at(i);
614 _cset->clear_optional_region(hr);
615 if (hr->evacuation_failed()){
616 _evacuation_failed = true;
617 }
618 }
619 _current_index = _current_limit;
620 }
621
622 bool G1OptionalCSet::evacuation_failed() {
623 return _evacuation_failed;
624 }
625
626 G1OptionalCSet::~G1OptionalCSet() {
627 G1CollectedHeap* g1h = G1CollectedHeap::heap();
628 while (!is_empty()) {
629 // We want to return regions not evacuated to the
630 // chooser in reverse order to maintain the old order.
631 HeapRegion* hr = _cset->remove_last_optional_region();
632 assert(hr != NULL, "Should be valid region left");
633 g1h->old_set_add(hr);
634 g1h->clear_in_cset(hr);
635 hr->set_index_in_opt_cset(InvalidCSetIndex);
636 _cset->cset_chooser()->push(hr);
637 }
638 _cset->free_optional_regions();
639 }
640
641 uint G1OptionalCSet::size() {
642 return _cset->optional_region_length() - _current_index;
643 }
644
645 bool G1OptionalCSet::is_empty() {
646 return size() == 0;
647 }
648
649 void G1OptionalCSet::prepare_to_evacuate_optional_region(HeapRegion* hr) {
650 log_trace(gc, cset)("Adding region %u for optional evacuation", hr->hrm_index());
651 G1CollectedHeap::heap()->clear_in_cset(hr);
652 _cset->add_old_region(hr);
653 }
654
655 #ifdef ASSERT
656 class G1VerifyYoungCSetIndicesClosure : public HeapRegionClosure {
657 private:
658 size_t _young_length;
659 int* _heap_region_indices;
660 public:
661 G1VerifyYoungCSetIndicesClosure(size_t young_length) : HeapRegionClosure(), _young_length(young_length) {
662 _heap_region_indices = NEW_C_HEAP_ARRAY(int, young_length, mtGC);
663 for (size_t i = 0; i < young_length; i++) {
664 _heap_region_indices[i] = -1;
665 }
666 }
667 ~G1VerifyYoungCSetIndicesClosure() {
668 FREE_C_HEAP_ARRAY(int, _heap_region_indices);
669 }
670
671 virtual bool do_heap_region(HeapRegion* r) {
672 const int idx = r->young_index_in_cset();
|