27 #include "gc/g1/heapRegionRemSet.hpp" |
27 #include "gc/g1/heapRegionRemSet.hpp" |
28 #include "gc/g1/heapRegionSet.inline.hpp" |
28 #include "gc/g1/heapRegionSet.inline.hpp" |
29 |
29 |
30 uint FreeRegionList::_unrealistically_long_length = 0; |
30 uint FreeRegionList::_unrealistically_long_length = 0; |
31 |
31 |
32 void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) { |
|
33 msg->append("[%s] %s ln: %u cy: " SIZE_FORMAT, |
|
34 name(), message, length(), total_capacity_bytes()); |
|
35 fill_in_ext_msg_extra(msg); |
|
36 } |
|
37 |
|
38 #ifndef PRODUCT |
32 #ifndef PRODUCT |
39 void HeapRegionSetBase::verify_region(HeapRegion* hr) { |
33 void HeapRegionSetBase::verify_region(HeapRegion* hr) { |
40 assert(hr->containing_set() == this, "Inconsistent containing set for %u", hr->hrm_index()); |
34 assert(hr->containing_set() == this, "Inconsistent containing set for %u", hr->hrm_index()); |
41 assert(!hr->is_young(), "Adding young region %u", hr->hrm_index()); // currently we don't use these sets for young regions |
35 assert(!hr->is_young(), "Adding young region %u", hr->hrm_index()); // currently we don't use these sets for young regions |
42 assert(hr->is_humongous() == regions_humongous(), "Wrong humongous state for region %u and set %s", hr->hrm_index(), name()); |
36 assert(hr->is_humongous() == regions_humongous(), "Wrong humongous state for region %u and set %s", hr->hrm_index(), name()); |
53 // for the verification calls. If we do verification without the |
47 // for the verification calls. If we do verification without the |
54 // appropriate locks and the set changes underneath our feet |
48 // appropriate locks and the set changes underneath our feet |
55 // verification might fail and send us on a wild goose chase. |
49 // verification might fail and send us on a wild goose chase. |
56 check_mt_safety(); |
50 check_mt_safety(); |
57 |
51 |
58 guarantee(( is_empty() && length() == 0 && total_capacity_bytes() == 0) || |
52 guarantee_heap_region_set(( is_empty() && length() == 0 && total_capacity_bytes() == 0) || |
59 (!is_empty() && length() > 0 && total_capacity_bytes() > 0) , |
53 (!is_empty() && length() > 0 && total_capacity_bytes() > 0) , |
60 "%s", hrs_ext_msg(this, "invariant").buffer()); |
54 "invariant"); |
61 } |
55 } |
62 |
56 |
63 void HeapRegionSetBase::verify_start() { |
57 void HeapRegionSetBase::verify_start() { |
64 // See comment in verify() about MT safety and verification. |
58 // See comment in verify() about MT safety and verification. |
65 check_mt_safety(); |
59 check_mt_safety(); |
66 assert(!_verify_in_progress, |
60 assert_heap_region_set(!_verify_in_progress, "verification should not be in progress"); |
67 "%s", hrs_ext_msg(this, "verification should not be in progress").buffer()); |
|
68 |
61 |
69 // Do the basic verification first before we do the checks over the regions. |
62 // Do the basic verification first before we do the checks over the regions. |
70 HeapRegionSetBase::verify(); |
63 HeapRegionSetBase::verify(); |
71 |
64 |
72 _verify_in_progress = true; |
65 _verify_in_progress = true; |
73 } |
66 } |
74 |
67 |
75 void HeapRegionSetBase::verify_end() { |
68 void HeapRegionSetBase::verify_end() { |
76 // See comment in verify() about MT safety and verification. |
69 // See comment in verify() about MT safety and verification. |
77 check_mt_safety(); |
70 check_mt_safety(); |
78 assert(_verify_in_progress, |
71 assert_heap_region_set(_verify_in_progress, "verification should be in progress"); |
79 "%s", hrs_ext_msg(this, "verification should be in progress").buffer()); |
|
80 |
72 |
81 _verify_in_progress = false; |
73 _verify_in_progress = false; |
82 } |
74 } |
83 |
75 |
84 void HeapRegionSetBase::print_on(outputStream* out, bool print_contents) { |
76 void HeapRegionSetBase::print_on(outputStream* out, bool print_contents) { |
102 void FreeRegionList::set_unrealistically_long_length(uint len) { |
94 void FreeRegionList::set_unrealistically_long_length(uint len) { |
103 guarantee(_unrealistically_long_length == 0, "should only be set once"); |
95 guarantee(_unrealistically_long_length == 0, "should only be set once"); |
104 _unrealistically_long_length = len; |
96 _unrealistically_long_length = len; |
105 } |
97 } |
106 |
98 |
107 void FreeRegionList::fill_in_ext_msg_extra(hrs_ext_msg* msg) { |
|
108 msg->append(" hd: " PTR_FORMAT " tl: " PTR_FORMAT, p2i(_head), p2i(_tail)); |
|
109 } |
|
110 |
|
111 void FreeRegionList::remove_all() { |
99 void FreeRegionList::remove_all() { |
112 check_mt_safety(); |
100 check_mt_safety(); |
113 verify_optional(); |
101 verify_optional(); |
114 |
102 |
115 HeapRegion* curr = _head; |
103 HeapRegion* curr = _head; |
149 hr->set_containing_set(this); |
137 hr->set_containing_set(this); |
150 } |
138 } |
151 #endif // ASSERT |
139 #endif // ASSERT |
152 |
140 |
153 if (is_empty()) { |
141 if (is_empty()) { |
154 assert(length() == 0 && _tail == NULL, "%s", hrs_ext_msg(this, "invariant").buffer()); |
142 assert_free_region_list(length() == 0 && _tail == NULL, "invariant"); |
155 _head = from_list->_head; |
143 _head = from_list->_head; |
156 _tail = from_list->_tail; |
144 _tail = from_list->_tail; |
157 } else { |
145 } else { |
158 HeapRegion* curr_to = _head; |
146 HeapRegion* curr_to = _head; |
159 HeapRegion* curr_from = from_list->_head; |
147 HeapRegion* curr_from = from_list->_head; |
196 from_list->verify_optional(); |
184 from_list->verify_optional(); |
197 } |
185 } |
198 |
186 |
199 void FreeRegionList::remove_starting_at(HeapRegion* first, uint num_regions) { |
187 void FreeRegionList::remove_starting_at(HeapRegion* first, uint num_regions) { |
200 check_mt_safety(); |
188 check_mt_safety(); |
201 assert(num_regions >= 1, "%s", hrs_ext_msg(this, "pre-condition").buffer()); |
189 assert_free_region_list(num_regions >= 1, "pre-condition"); |
202 assert(!is_empty(), "%s", hrs_ext_msg(this, "pre-condition").buffer()); |
190 assert_free_region_list(!is_empty(), "pre-condition"); |
203 |
191 |
204 verify_optional(); |
192 verify_optional(); |
205 DEBUG_ONLY(uint old_length = length();) |
193 DEBUG_ONLY(uint old_length = length();) |
206 |
194 |
207 HeapRegion* curr = first; |
195 HeapRegion* curr = first; |
210 verify_region(curr); |
198 verify_region(curr); |
211 HeapRegion* next = curr->next(); |
199 HeapRegion* next = curr->next(); |
212 HeapRegion* prev = curr->prev(); |
200 HeapRegion* prev = curr->prev(); |
213 |
201 |
214 assert(count < num_regions, |
202 assert(count < num_regions, |
215 "%s", hrs_err_msg("[%s] should not come across more regions " |
203 "[%s] should not come across more regions " |
216 "pending for removal than num_regions: %u", |
204 "pending for removal than num_regions: %u", |
217 name(), num_regions).buffer()); |
205 name(), num_regions); |
218 |
206 |
219 if (prev == NULL) { |
207 if (prev == NULL) { |
220 assert(_head == curr, "%s", hrs_ext_msg(this, "invariant").buffer()); |
208 assert_free_region_list(_head == curr, "invariant"); |
221 _head = next; |
209 _head = next; |
222 } else { |
210 } else { |
223 assert(_head != curr, "%s", hrs_ext_msg(this, "invariant").buffer()); |
211 assert_free_region_list(_head != curr, "invariant"); |
224 prev->set_next(next); |
212 prev->set_next(next); |
225 } |
213 } |
226 if (next == NULL) { |
214 if (next == NULL) { |
227 assert(_tail == curr, "%s", hrs_ext_msg(this, "invariant").buffer()); |
215 assert_free_region_list(_tail == curr, "invariant"); |
228 _tail = prev; |
216 _tail = prev; |
229 } else { |
217 } else { |
230 assert(_tail != curr, "%s", hrs_ext_msg(this, "invariant").buffer()); |
218 assert_free_region_list(_tail != curr, "invariant"); |
231 next->set_prev(prev); |
219 next->set_prev(prev); |
232 } |
220 } |
233 if (_last == curr) { |
221 if (_last == curr) { |
234 _last = NULL; |
222 _last = NULL; |
235 } |
223 } |
241 count++; |
229 count++; |
242 curr = next; |
230 curr = next; |
243 } |
231 } |
244 |
232 |
245 assert(count == num_regions, |
233 assert(count == num_regions, |
246 "%s", hrs_err_msg("[%s] count: %u should be == num_regions: %u", |
234 "[%s] count: %u should be == num_regions: %u", |
247 name(), count, num_regions).buffer()); |
235 name(), count, num_regions); |
248 assert(length() + num_regions == old_length, |
236 assert(length() + num_regions == old_length, |
249 "%s", hrs_err_msg("[%s] new length should be consistent " |
237 "[%s] new length should be consistent " |
250 "new length: %u old length: %u num_regions: %u", |
238 "new length: %u old length: %u num_regions: %u", |
251 name(), length(), old_length, num_regions).buffer()); |
239 name(), length(), old_length, num_regions); |
252 |
240 |
253 verify_optional(); |
241 verify_optional(); |
254 } |
242 } |
255 |
243 |
256 void FreeRegionList::verify() { |
244 void FreeRegionList::verify() { |
303 while (curr != NULL) { |
291 while (curr != NULL) { |
304 verify_region(curr); |
292 verify_region(curr); |
305 |
293 |
306 count++; |
294 count++; |
307 guarantee(count < _unrealistically_long_length, |
295 guarantee(count < _unrealistically_long_length, |
308 "%s", 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", |
296 "[%s] the calculated length: %u seems very long, is there maybe a cycle? curr: " PTR_FORMAT " prev0: " PTR_FORMAT " " "prev1: " PTR_FORMAT " length: %u", |
309 name(), count, p2i(curr), p2i(prev0), p2i(prev1), length()).buffer()); |
297 name(), count, p2i(curr), p2i(prev0), p2i(prev1), length()); |
310 |
298 |
311 if (curr->next() != NULL) { |
299 if (curr->next() != NULL) { |
312 guarantee(curr->next()->prev() == curr, "Next or prev pointers messed up"); |
300 guarantee(curr->next()->prev() == curr, "Next or prev pointers messed up"); |
313 } |
301 } |
314 guarantee(curr->hrm_index() == 0 || curr->hrm_index() > last_index, "List should be sorted"); |
302 guarantee(curr->hrm_index() == 0 || curr->hrm_index() > last_index, "List should be sorted"); |