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 }
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();
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) {
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);
|
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/g1ParScanThreadState.hpp"
30 #include "gc/g1/g1Policy.hpp"
31 #include "gc/g1/heapRegion.inline.hpp"
32 #include "gc/g1/heapRegionRemSet.hpp"
33 #include "gc/g1/heapRegionSet.hpp"
34 #include "logging/logStream.hpp"
35 #include "utilities/debug.hpp"
36 #include "utilities/globalDefinitions.hpp"
37 #include "utilities/quickSort.hpp"
38
39 G1CollectorState* G1CollectionSet::collector_state() {
40 return _g1h->collector_state();
41 }
42
43 G1GCPhaseTimes* G1CollectionSet::phase_times() {
44 return _policy->phase_times();
45 }
46
47 CollectionSetChooser* G1CollectionSet::cset_chooser() {
48 return _cset_chooser;
49 }
88 assert_at_safepoint_on_vm_thread();
89
90 _eden_region_length = eden_cset_region_length;
91 _survivor_region_length = survivor_cset_region_length;
92
93 assert((size_t) young_region_length() == _collection_set_cur_length,
94 "Young region length %u should match collection set length " SIZE_FORMAT, young_region_length(), _collection_set_cur_length);
95
96 _old_region_length = 0;
97 _optional_region_length = 0;
98 }
99
100 void G1CollectionSet::initialize(uint max_region_length) {
101 guarantee(_collection_set_regions == NULL, "Must only initialize once.");
102 _collection_set_max_length = max_region_length;
103 _collection_set_regions = NEW_C_HEAP_ARRAY(uint, max_region_length, mtGC);
104 }
105
106 void G1CollectionSet::initialize_optional(uint max_length) {
107 assert(_optional_regions == NULL, "Already initialized");
108 assert(_optional_region_length == 0, "Already initialized");
109 assert(_optional_region_max_length == 0, "Already initialized");
110 _optional_region_max_length = max_length;
111 _optional_regions = NEW_C_HEAP_ARRAY(HeapRegion*, _optional_region_max_length, mtGC);
112 }
113
114 void G1CollectionSet::free_optional_regions() {
115 _optional_region_length = 0;
116 _optional_region_max_length = 0;
117 if (_optional_regions != NULL) {
118 FREE_C_HEAP_ARRAY(HeapRegion*, _optional_regions);
119 _optional_regions = NULL;
120 }
121 }
122
123 void G1CollectionSet::set_recorded_rs_lengths(size_t rs_lengths) {
124 _recorded_rs_lengths = rs_lengths;
125 }
126
127 // Add the heap region at the head of the non-incremental collection set
128 void G1CollectionSet::add_old_region(HeapRegion* hr) {
129 assert_at_safepoint_on_vm_thread();
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 void G1CollectionSet::add_as_old(HeapRegion* hr) {
442 cset_chooser()->pop(); // already have region via peek()
443 _g1h->old_set_remove(hr);
444 add_old_region(hr);
445 }
446
447 void G1CollectionSet::add_as_optional(HeapRegion* hr) {
448 assert(_optional_regions != NULL, "Must not be called before array is allocated");
449 cset_chooser()->pop(); // already have region via peek()
450 _g1h->old_set_remove(hr);
451 add_optional_region(hr);
452 }
453
454 bool G1CollectionSet::optional_is_full() {
455 assert(_optional_region_length <= _optional_region_max_length, "Invariant");
456 return _optional_region_length == _optional_region_max_length;
457 }
458
459 void G1CollectionSet::clear_optional_region(const HeapRegion* hr) {
460 assert(_optional_regions != NULL, "Must not be called before array is allocated");
461 uint index = hr->index_in_opt_cset();
462 _optional_regions[index] = NULL;
463 }
464
465 static int compare_region_idx(const uint a, const uint b) {
466 if (a > b) {
467 return 1;
468 } else if (a == b) {
469 return 0;
470 } else {
471 return -1;
472 }
473 }
474
475 void G1CollectionSet::finalize_old_part(double time_remaining_ms) {
617 HeapRegion* hr = region_at(i);
618 _cset->clear_optional_region(hr);
619 if (hr->evacuation_failed()){
620 _evacuation_failed = true;
621 }
622 }
623 _current_index = _current_limit;
624 }
625
626 bool G1OptionalCSet::evacuation_failed() {
627 return _evacuation_failed;
628 }
629
630 G1OptionalCSet::~G1OptionalCSet() {
631 G1CollectedHeap* g1h = G1CollectedHeap::heap();
632 while (!is_empty()) {
633 // We want to return regions not evacuated to the
634 // chooser in reverse order to maintain the old order.
635 HeapRegion* hr = _cset->remove_last_optional_region();
636 assert(hr != NULL, "Should be valid region left");
637 _pset->free_unused_optional_region(hr);
638 g1h->old_set_add(hr);
639 g1h->clear_in_cset(hr);
640 hr->set_index_in_opt_cset(InvalidCSetIndex);
641 _cset->cset_chooser()->push(hr);
642 }
643 _cset->free_optional_regions();
644 }
645
646 uint G1OptionalCSet::size() {
647 return _cset->optional_region_length() - _current_index;
648 }
649
650 bool G1OptionalCSet::is_empty() {
651 return size() == 0;
652 }
653
654 void G1OptionalCSet::prepare_to_evacuate_optional_region(HeapRegion* hr) {
655 log_trace(gc, cset)("Adding region %u for optional evacuation", hr->hrm_index());
656 G1CollectedHeap::heap()->clear_in_cset(hr);
657 _cset->add_old_region(hr);
|