Mercurial > hg > graal-jvmci-8
annotate src/share/vm/gc_implementation/g1/heapRegionSet.cpp @ 20417:d35872270666
8057658: Enable G1 FullGC extensions
Summary: Refactored the G1 FullGC code to enable it to be extended.
Reviewed-by: mgerdin, brutisso
author | sjohanss |
---|---|
date | Tue, 09 Sep 2014 00:05:25 +0200 |
parents | a8ea2f110d87 |
children | c02ec279b062 |
rev | line source |
---|---|
2152 | 1 /* |
17773
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
2 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. |
2152 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
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" | |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
26 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
27 #include "gc_implementation/g1/heapRegionRemSet.hpp" |
2152 | 28 #include "gc_implementation/g1/heapRegionSet.inline.hpp" |
29 | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17773
diff
changeset
|
30 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17773
diff
changeset
|
31 |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
32 uint FreeRegionList::_unrealistically_long_length = 0; |
2152 | 33 |
2361 | 34 void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) { |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
35 msg->append("[%s] %s ln: %u cy: "SIZE_FORMAT, |
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
36 name(), message, length(), total_capacity_bytes()); |
2152 | 37 fill_in_ext_msg_extra(msg); |
38 } | |
39 | |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
40 #ifndef PRODUCT |
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
41 void HeapRegionSetBase::verify_region(HeapRegion* hr) { |
20377
a8ea2f110d87
8054819: Rename HeapRegionSeq to HeapRegionManager
tschatzl
parents:
20337
diff
changeset
|
42 assert(hr->containing_set() == this, err_msg("Inconsistent containing set for %u", hr->hrm_index())); |
a8ea2f110d87
8054819: Rename HeapRegionSeq to HeapRegionManager
tschatzl
parents:
20337
diff
changeset
|
43 assert(!hr->is_young(), err_msg("Adding young region %u", hr->hrm_index())); // currently we don't use these sets for young regions |
a8ea2f110d87
8054819: Rename HeapRegionSeq to HeapRegionManager
tschatzl
parents:
20337
diff
changeset
|
44 assert(hr->isHumongous() == regions_humongous(), err_msg("Wrong humongous state for region %u and set %s", hr->hrm_index(), name())); |
a8ea2f110d87
8054819: Rename HeapRegionSeq to HeapRegionManager
tschatzl
parents:
20337
diff
changeset
|
45 assert(hr->is_empty() == regions_empty(), err_msg("Wrong empty state for region %u and set %s", hr->hrm_index(), name())); |
a8ea2f110d87
8054819: Rename HeapRegionSeq to HeapRegionManager
tschatzl
parents:
20337
diff
changeset
|
46 assert(hr->rem_set()->verify_ready_for_par_iteration(), err_msg("Wrong iteration state %u", hr->hrm_index())); |
2152 | 47 } |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
48 #endif |
2152 | 49 |
50 void HeapRegionSetBase::verify() { | |
51 // It's important that we also observe the MT safety protocol even | |
52 // for the verification calls. If we do verification without the | |
53 // appropriate locks and the set changes underneath our feet | |
54 // verification might fail and send us on a wild goose chase. | |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
55 check_mt_safety(); |
2152 | 56 |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
57 guarantee(( is_empty() && length() == 0 && total_capacity_bytes() == 0) || |
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
58 (!is_empty() && length() >= 0 && total_capacity_bytes() >= 0), |
2361 | 59 hrs_ext_msg(this, "invariant")); |
2152 | 60 } |
61 | |
62 void HeapRegionSetBase::verify_start() { | |
63 // See comment in verify() about MT safety and verification. | |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
64 check_mt_safety(); |
2152 | 65 assert(!_verify_in_progress, |
2361 | 66 hrs_ext_msg(this, "verification should not be in progress")); |
2152 | 67 |
68 // Do the basic verification first before we do the checks over the regions. | |
69 HeapRegionSetBase::verify(); | |
70 | |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
71 _verify_in_progress = true; |
2152 | 72 } |
73 | |
74 void HeapRegionSetBase::verify_end() { | |
75 // See comment in verify() about MT safety and verification. | |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
76 check_mt_safety(); |
2152 | 77 assert(_verify_in_progress, |
2361 | 78 hrs_ext_msg(this, "verification should be in progress")); |
2152 | 79 |
80 _verify_in_progress = false; | |
81 } | |
82 | |
83 void HeapRegionSetBase::print_on(outputStream* out, bool print_contents) { | |
84 out->cr(); | |
85 out->print_cr("Set: %s ("PTR_FORMAT")", name(), this); | |
86 out->print_cr(" Region Assumptions"); | |
87 out->print_cr(" humongous : %s", BOOL_TO_STR(regions_humongous())); | |
88 out->print_cr(" empty : %s", BOOL_TO_STR(regions_empty())); | |
89 out->print_cr(" Attributes"); | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
90 out->print_cr(" length : %14u", length()); |
2152 | 91 out->print_cr(" total capacity : "SIZE_FORMAT_W(14)" bytes", |
92 total_capacity_bytes()); | |
93 } | |
94 | |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
95 HeapRegionSetBase::HeapRegionSetBase(const char* name, bool humongous, bool empty, HRSMtSafeChecker* mt_safety_checker) |
2152 | 96 : _name(name), _verify_in_progress(false), |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
97 _is_humongous(humongous), _is_empty(empty), _mt_safety_checker(mt_safety_checker), |
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
98 _count() |
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
99 { } |
2152 | 100 |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
101 void FreeRegionList::set_unrealistically_long_length(uint len) { |
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
102 guarantee(_unrealistically_long_length == 0, "should only be set once"); |
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
103 _unrealistically_long_length = len; |
2152 | 104 } |
105 | |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
106 void FreeRegionList::fill_in_ext_msg_extra(hrs_ext_msg* msg) { |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
107 msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, _head, _tail); |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
108 } |
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
109 |
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
110 void FreeRegionList::remove_all() { |
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
111 check_mt_safety(); |
2152 | 112 verify_optional(); |
113 | |
114 HeapRegion* curr = _head; | |
115 while (curr != NULL) { | |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
116 verify_region(curr); |
2152 | 117 |
118 HeapRegion* next = curr->next(); | |
119 curr->set_next(NULL); | |
17773
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
120 curr->set_prev(NULL); |
2152 | 121 curr->set_containing_set(NULL); |
122 curr = next; | |
123 } | |
124 clear(); | |
125 | |
126 verify_optional(); | |
127 } | |
128 | |
17773
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
129 void FreeRegionList::add_ordered(FreeRegionList* from_list) { |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
130 check_mt_safety(); |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
131 from_list->check_mt_safety(); |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
132 |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
133 verify_optional(); |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
134 from_list->verify_optional(); |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
135 |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
136 if (from_list->is_empty()) { |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
137 return; |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
138 } |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
139 |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
140 #ifdef ASSERT |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
141 FreeRegionListIterator iter(from_list); |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
142 while (iter.more_available()) { |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
143 HeapRegion* hr = iter.get_next(); |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
144 // In set_containing_set() we check that we either set the value |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
145 // from NULL to non-NULL or vice versa to catch bugs. So, we have |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
146 // to NULL it first before setting it to the value. |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
147 hr->set_containing_set(NULL); |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
148 hr->set_containing_set(this); |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
149 } |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
150 #endif // ASSERT |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
151 |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
152 if (is_empty()) { |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
153 assert(length() == 0 && _tail == NULL, hrs_ext_msg(this, "invariant")); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
154 _head = from_list->_head; |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
155 _tail = from_list->_tail; |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
156 } else { |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
157 HeapRegion* curr_to = _head; |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
158 HeapRegion* curr_from = from_list->_head; |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
159 |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
160 while (curr_from != NULL) { |
20377
a8ea2f110d87
8054819: Rename HeapRegionSeq to HeapRegionManager
tschatzl
parents:
20337
diff
changeset
|
161 while (curr_to != NULL && curr_to->hrm_index() < curr_from->hrm_index()) { |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
162 curr_to = curr_to->next(); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
163 } |
17773
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
164 |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
165 if (curr_to == NULL) { |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
166 // The rest of the from list should be added as tail |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
167 _tail->set_next(curr_from); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
168 curr_from->set_prev(_tail); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
169 curr_from = NULL; |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
170 } else { |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
171 HeapRegion* next_from = curr_from->next(); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
172 |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
173 curr_from->set_next(curr_to); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
174 curr_from->set_prev(curr_to->prev()); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
175 if (curr_to->prev() == NULL) { |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
176 _head = curr_from; |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
177 } else { |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
178 curr_to->prev()->set_next(curr_from); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
179 } |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
180 curr_to->set_prev(curr_from); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
181 |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
182 curr_from = next_from; |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
183 } |
17773
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
184 } |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
185 |
20377
a8ea2f110d87
8054819: Rename HeapRegionSeq to HeapRegionManager
tschatzl
parents:
20337
diff
changeset
|
186 if (_tail->hrm_index() < from_list->_tail->hrm_index()) { |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
187 _tail = from_list->_tail; |
17773
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
188 } |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
189 } |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
190 |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
191 _count.increment(from_list->length(), from_list->total_capacity_bytes()); |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
192 from_list->clear(); |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
193 |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
194 verify_optional(); |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
195 from_list->verify_optional(); |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
196 } |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
197 |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
198 void FreeRegionList::remove_starting_at(HeapRegion* first, uint num_regions) { |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
199 check_mt_safety(); |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
200 assert(num_regions >= 1, hrs_ext_msg(this, "pre-condition")); |
2361 | 201 assert(!is_empty(), hrs_ext_msg(this, "pre-condition")); |
2152 | 202 |
203 verify_optional(); | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
204 DEBUG_ONLY(uint old_length = length();) |
2152 | 205 |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
206 HeapRegion* curr = first; |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
207 uint count = 0; |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
208 while (count < num_regions) { |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
209 verify_region(curr); |
2152 | 210 HeapRegion* next = curr->next(); |
17773
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
211 HeapRegion* prev = curr->prev(); |
2152 | 212 |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
213 assert(count < num_regions, |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
214 hrs_err_msg("[%s] should not come across more regions " |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
215 "pending for removal than num_regions: %u", |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
216 name(), num_regions)); |
2152 | 217 |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
218 if (prev == NULL) { |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
219 assert(_head == curr, hrs_ext_msg(this, "invariant")); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
220 _head = next; |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
221 } else { |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
222 assert(_head != curr, hrs_ext_msg(this, "invariant")); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
223 prev->set_next(next); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
224 } |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
225 if (next == NULL) { |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
226 assert(_tail == curr, hrs_ext_msg(this, "invariant")); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
227 _tail = prev; |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
228 } else { |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
229 assert(_tail != curr, hrs_ext_msg(this, "invariant")); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
230 next->set_prev(prev); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
231 } |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
232 if (_last = curr) { |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
233 _last = NULL; |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
234 } |
2152 | 235 |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
236 curr->set_next(NULL); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
237 curr->set_prev(NULL); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
238 remove(curr); |
2152 | 239 |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
240 count++; |
2152 | 241 curr = next; |
242 } | |
243 | |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
244 assert(count == num_regions, |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
245 hrs_err_msg("[%s] count: %u should be == num_regions: %u", |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
246 name(), count, num_regions)); |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
247 assert(length() + num_regions == old_length, |
2361 | 248 hrs_err_msg("[%s] new length should be consistent " |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
249 "new length: %u old length: %u num_regions: %u", |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
250 name(), length(), old_length, num_regions)); |
2152 | 251 |
252 verify_optional(); | |
253 } | |
254 | |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
255 void FreeRegionList::verify() { |
2152 | 256 // See comment in HeapRegionSetBase::verify() about MT safety and |
257 // verification. | |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
258 check_mt_safety(); |
2152 | 259 |
260 // This will also do the basic verification too. | |
261 verify_start(); | |
262 | |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
263 verify_list(); |
2152 | 264 |
265 verify_end(); | |
266 } | |
267 | |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
268 void FreeRegionList::clear() { |
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
269 _count = HeapRegionSetCount(); |
2152 | 270 _head = NULL; |
271 _tail = NULL; | |
17773
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
272 _last = NULL; |
2152 | 273 } |
274 | |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
275 void FreeRegionList::print_on(outputStream* out, bool print_contents) { |
2152 | 276 HeapRegionSetBase::print_on(out, print_contents); |
277 out->print_cr(" Linking"); | |
278 out->print_cr(" head : "PTR_FORMAT, _head); | |
279 out->print_cr(" tail : "PTR_FORMAT, _tail); | |
280 | |
281 if (print_contents) { | |
282 out->print_cr(" Contents"); | |
17736
58fc1b1523dc
8034079: G1: Refactor the HeapRegionSet hierarchy
brutisso
parents:
6254
diff
changeset
|
283 FreeRegionListIterator iter(this); |
2152 | 284 while (iter.more_available()) { |
285 HeapRegion* hr = iter.get_next(); | |
286 hr->print_on(out); | |
287 } | |
288 } | |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
289 |
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
290 out->cr(); |
2152 | 291 } |
17737 | 292 |
293 void FreeRegionList::verify_list() { | |
20336
6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
tschatzl
parents:
17937
diff
changeset
|
294 HeapRegion* curr = _head; |
17737 | 295 HeapRegion* prev1 = NULL; |
296 HeapRegion* prev0 = NULL; | |
297 uint count = 0; | |
298 size_t capacity = 0; | |
17773
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
299 uint last_index = 0; |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
300 |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
301 guarantee(_head == NULL || _head->prev() == NULL, "_head should not have a prev"); |
17737 | 302 while (curr != NULL) { |
303 verify_region(curr); | |
304 | |
305 count++; | |
306 guarantee(count < _unrealistically_long_length, | |
307 hrs_err_msg("[%s] the calculated length: %u seems very long, is there maybe a cycle? curr: "PTR_FORMAT" prev0: "PTR_FORMAT" " "prev1: "PTR_FORMAT" length: %u", name(), count, curr, prev0, prev1, length())); | |
308 | |
17773
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
309 if (curr->next() != NULL) { |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
310 guarantee(curr->next()->prev() == curr, "Next or prev pointers messed up"); |
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
311 } |
20377
a8ea2f110d87
8054819: Rename HeapRegionSeq to HeapRegionManager
tschatzl
parents:
20337
diff
changeset
|
312 guarantee(curr->hrm_index() == 0 || curr->hrm_index() > last_index, "List should be sorted"); |
a8ea2f110d87
8054819: Rename HeapRegionSeq to HeapRegionManager
tschatzl
parents:
20337
diff
changeset
|
313 last_index = curr->hrm_index(); |
17773
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
314 |
17737 | 315 capacity += curr->capacity(); |
316 | |
317 prev1 = prev0; | |
318 prev0 = curr; | |
319 curr = curr->next(); | |
320 } | |
321 | |
20377
a8ea2f110d87
8054819: Rename HeapRegionSeq to HeapRegionManager
tschatzl
parents:
20337
diff
changeset
|
322 guarantee(_tail == prev0, err_msg("Expected %s to end with %u but it ended with %u.", name(), _tail->hrm_index(), prev0->hrm_index())); |
17773
8ee855b4e667
8036025: Sort the freelist in order to shrink the heap
jwilhelm
parents:
17737
diff
changeset
|
323 guarantee(_tail == NULL || _tail->next() == NULL, "_tail should not have a next"); |
17737 | 324 guarantee(length() == count, err_msg("%s count mismatch. Expected %u, actual %u.", name(), length(), count)); |
325 guarantee(total_capacity_bytes() == capacity, err_msg("%s capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT, | |
326 name(), total_capacity_bytes(), capacity)); | |
327 } | |
328 | |
329 // Note on the check_mt_safety() methods below: | |
330 // | |
331 // Verification of the "master" heap region sets / lists that are | |
332 // maintained by G1CollectedHeap is always done during a STW pause and | |
333 // by the VM thread at the start / end of the pause. The standard | |
334 // verification methods all assert check_mt_safety(). This is | |
335 // important as it ensures that verification is done without | |
336 // concurrent updates taking place at the same time. It follows, that, | |
337 // for the "master" heap region sets / lists, the check_mt_safety() | |
338 // method should include the VM thread / STW case. | |
339 | |
340 void MasterFreeRegionListMtSafeChecker::check() { | |
341 // Master Free List MT safety protocol: | |
342 // (a) If we're at a safepoint, operations on the master free list | |
343 // should be invoked by either the VM thread (which will serialize | |
344 // them) or by the GC workers while holding the | |
345 // FreeList_lock. | |
346 // (b) If we're not at a safepoint, operations on the master free | |
347 // list should be invoked while holding the Heap_lock. | |
348 | |
349 if (SafepointSynchronize::is_at_safepoint()) { | |
350 guarantee(Thread::current()->is_VM_thread() || | |
351 FreeList_lock->owned_by_self(), "master free list MT safety protocol at a safepoint"); | |
352 } else { | |
353 guarantee(Heap_lock->owned_by_self(), "master free list MT safety protocol outside a safepoint"); | |
354 } | |
355 } | |
356 | |
357 void SecondaryFreeRegionListMtSafeChecker::check() { | |
358 // Secondary Free List MT safety protocol: | |
359 // Operations on the secondary free list should always be invoked | |
360 // while holding the SecondaryFreeList_lock. | |
361 | |
362 guarantee(SecondaryFreeList_lock->owned_by_self(), "secondary free list MT safety protocol"); | |
363 } | |
364 | |
365 void OldRegionSetMtSafeChecker::check() { | |
366 // Master Old Set MT safety protocol: | |
367 // (a) If we're at a safepoint, operations on the master old set | |
368 // should be invoked: | |
369 // - by the VM thread (which will serialize them), or | |
370 // - by the GC workers while holding the FreeList_lock, if we're | |
371 // at a safepoint for an evacuation pause (this lock is taken | |
372 // anyway when an GC alloc region is retired so that a new one | |
373 // is allocated from the free list), or | |
374 // - by the GC workers while holding the OldSets_lock, if we're at a | |
375 // safepoint for a cleanup pause. | |
376 // (b) If we're not at a safepoint, operations on the master old set | |
377 // should be invoked while holding the Heap_lock. | |
378 | |
379 if (SafepointSynchronize::is_at_safepoint()) { | |
380 guarantee(Thread::current()->is_VM_thread() | |
381 || FreeList_lock->owned_by_self() || OldSets_lock->owned_by_self(), | |
382 "master old set MT safety protocol at a safepoint"); | |
383 } else { | |
384 guarantee(Heap_lock->owned_by_self(), "master old set MT safety protocol outside a safepoint"); | |
385 } | |
386 } | |
387 | |
388 void HumongousRegionSetMtSafeChecker::check() { | |
389 // Humongous Set MT safety protocol: | |
390 // (a) If we're at a safepoint, operations on the master humongous | |
391 // set should be invoked by either the VM thread (which will | |
392 // serialize them) or by the GC workers while holding the | |
393 // OldSets_lock. | |
394 // (b) If we're not at a safepoint, operations on the master | |
395 // humongous set should be invoked while holding the Heap_lock. | |
396 | |
397 if (SafepointSynchronize::is_at_safepoint()) { | |
398 guarantee(Thread::current()->is_VM_thread() || | |
399 OldSets_lock->owned_by_self(), | |
400 "master humongous set MT safety protocol at a safepoint"); | |
401 } else { | |
402 guarantee(Heap_lock->owned_by_self(), | |
403 "master humongous set MT safety protocol outside a safepoint"); | |
404 } | |
405 } | |
20337 | 406 |
407 void FreeRegionList_test() { | |
408 FreeRegionList l("test"); | |
409 | |
410 const uint num_regions_in_test = 5; | |
411 // Create a fake heap. It does not need to be valid, as the HeapRegion constructor | |
412 // does not access it. | |
413 MemRegion heap(NULL, num_regions_in_test * HeapRegion::GrainWords); | |
414 // Allocate a fake BOT because the HeapRegion constructor initializes | |
415 // the BOT. | |
416 size_t bot_size = G1BlockOffsetSharedArray::compute_size(heap.word_size()); | |
417 HeapWord* bot_data = NEW_C_HEAP_ARRAY(HeapWord, bot_size, mtGC); | |
418 ReservedSpace bot_rs(G1BlockOffsetSharedArray::compute_size(heap.word_size())); | |
419 G1RegionToSpaceMapper* bot_storage = | |
420 G1RegionToSpaceMapper::create_mapper(bot_rs, | |
421 os::vm_page_size(), | |
422 HeapRegion::GrainBytes, | |
423 G1BlockOffsetSharedArray::N_bytes, | |
424 mtGC); | |
425 G1BlockOffsetSharedArray oa(heap, bot_storage); | |
426 bot_storage->commit_regions(0, num_regions_in_test); | |
427 HeapRegion hr0(0, &oa, heap); | |
428 HeapRegion hr1(1, &oa, heap); | |
429 HeapRegion hr2(2, &oa, heap); | |
430 HeapRegion hr3(3, &oa, heap); | |
431 HeapRegion hr4(4, &oa, heap); | |
432 l.add_ordered(&hr1); | |
433 l.add_ordered(&hr0); | |
434 l.add_ordered(&hr3); | |
435 l.add_ordered(&hr4); | |
436 l.add_ordered(&hr2); | |
437 assert(l.length() == num_regions_in_test, "wrong length"); | |
438 l.verify_list(); | |
439 | |
440 bot_storage->uncommit_regions(0, num_regions_in_test); | |
441 delete bot_storage; | |
442 FREE_C_HEAP_ARRAY(HeapWord, bot_data, mtGC); | |
443 } |