1 /*
2 * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
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"
26 #include "gc/g1/g1CollectedHeap.inline.hpp"
27 #include "gc/g1/heapRegionRemSet.hpp"
28 #include "gc/g1/heapRegionSet.inline.hpp"
29
30 uint FreeRegionList::_unrealistically_long_length = 0;
31
32 #ifndef PRODUCT
33 void HeapRegionSetBase::verify_region(HeapRegion* hr) {
34 assert(hr->containing_set() == this, "Inconsistent containing set for %u", hr->hrm_index());
35 assert(!hr->is_young(), "Adding young region %u", hr->hrm_index()); // currently we don't use these sets for young regions
36 assert(_checker == NULL || _checker->is_correct_type(hr), "Wrong type of region %u (%s) and set %s",
37 hr->hrm_index(), hr->get_type_str(), name());
38 assert(!hr->is_free() || hr->is_empty(), "Free region %u is not empty for set %s", hr->hrm_index(), name());
39 assert(!hr->is_empty() || hr->is_free() || hr->is_archive(),
40 "Empty region %u is not free or archive for set %s", hr->hrm_index(), name());
41 }
42 #endif
43
44 void HeapRegionSetBase::verify() {
45 // It's important that we also observe the MT safety protocol even
46 // for the verification calls. If we do verification without the
84 {
85 }
86
87 void FreeRegionList::set_unrealistically_long_length(uint len) {
88 guarantee(_unrealistically_long_length == 0, "should only be set once");
89 _unrealistically_long_length = len;
90 }
91
92 void FreeRegionList::remove_all() {
93 check_mt_safety();
94 verify_optional();
95
96 HeapRegion* curr = _head;
97 while (curr != NULL) {
98 verify_region(curr);
99
100 HeapRegion* next = curr->next();
101 curr->set_next(NULL);
102 curr->set_prev(NULL);
103 curr->set_containing_set(NULL);
104 curr = next;
105 }
106 clear();
107
108 verify_optional();
109 }
110
111 void FreeRegionList::add_ordered(FreeRegionList* from_list) {
112 check_mt_safety();
113 from_list->check_mt_safety();
114
115 verify_optional();
116 from_list->verify_optional();
117
118 if (from_list->is_empty()) {
119 return;
120 }
121
122 #ifdef ASSERT
123 FreeRegionListIterator iter(from_list);
124 while (iter.more_available()) {
125 HeapRegion* hr = iter.get_next();
126 // In set_containing_set() we check that we either set the value
127 // from NULL to non-NULL or vice versa to catch bugs. So, we have
128 // to NULL it first before setting it to the value.
129 hr->set_containing_set(NULL);
130 hr->set_containing_set(this);
131 }
132 #endif // ASSERT
133
134 if (is_empty()) {
135 assert_free_region_list(length() == 0 && _tail == NULL, "invariant");
136 _head = from_list->_head;
137 _tail = from_list->_tail;
138 } else {
139 HeapRegion* curr_to = _head;
140 HeapRegion* curr_from = from_list->_head;
141
203 } else {
204 assert_free_region_list(_head != curr, "invariant");
205 prev->set_next(next);
206 }
207 if (next == NULL) {
208 assert_free_region_list(_tail == curr, "invariant");
209 _tail = prev;
210 } else {
211 assert_free_region_list(_tail != curr, "invariant");
212 next->set_prev(prev);
213 }
214 if (_last == curr) {
215 _last = NULL;
216 }
217
218 curr->set_next(NULL);
219 curr->set_prev(NULL);
220 remove(curr);
221
222 count++;
223 curr = next;
224 }
225
226 assert(count == num_regions,
227 "[%s] count: %u should be == num_regions: %u",
228 name(), count, num_regions);
229 assert(length() + num_regions == old_length,
230 "[%s] new length should be consistent "
231 "new length: %u old length: %u num_regions: %u",
232 name(), length(), old_length, num_regions);
233
234 verify_optional();
235 }
236
237 uint FreeRegionList::num_of_regions_in_range(uint start, uint end) const {
238 HeapRegion* cur = _head;
239 uint num = 0;
240 while (cur != NULL) {
241 uint index = cur->hrm_index();
242 if (index > end) {
250 }
251
252 void FreeRegionList::verify() {
253 // See comment in HeapRegionSetBase::verify() about MT safety and
254 // verification.
255 check_mt_safety();
256
257 // This will also do the basic verification too.
258 verify_start();
259
260 verify_list();
261
262 verify_end();
263 }
264
265 void FreeRegionList::clear() {
266 _length = 0;
267 _head = NULL;
268 _tail = NULL;
269 _last = NULL;
270 }
271
272 void FreeRegionList::verify_list() {
273 HeapRegion* curr = _head;
274 HeapRegion* prev1 = NULL;
275 HeapRegion* prev0 = NULL;
276 uint count = 0;
277 size_t capacity = 0;
278 uint last_index = 0;
279
280 guarantee(_head == NULL || _head->prev() == NULL, "_head should not have a prev");
281 while (curr != NULL) {
282 verify_region(curr);
283
284 count++;
285 guarantee(count < _unrealistically_long_length,
286 "[%s] the calculated length: %u seems very long, is there maybe a cycle? curr: " PTR_FORMAT " prev0: " PTR_FORMAT " " "prev1: " PTR_FORMAT " length: %u",
287 name(), count, p2i(curr), p2i(prev0), p2i(prev1), length());
288
289 if (curr->next() != NULL) {
290 guarantee(curr->next()->prev() == curr, "Next or prev pointers messed up");
291 }
292 guarantee(curr->hrm_index() == 0 || curr->hrm_index() > last_index, "List should be sorted");
293 last_index = curr->hrm_index();
294
295 capacity += curr->capacity();
296
297 prev1 = prev0;
298 prev0 = curr;
299 curr = curr->next();
300 }
301
302 guarantee(_tail == prev0, "Expected %s to end with %u but it ended with %u.", name(), _tail->hrm_index(), prev0->hrm_index());
303 guarantee(_tail == NULL || _tail->next() == NULL, "_tail should not have a next");
304 guarantee(length() == count, "%s count mismatch. Expected %u, actual %u.", name(), length(), count);
305 }
|
1 /*
2 * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
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"
26 #include "gc/g1/g1CollectedHeap.inline.hpp"
27 #include "gc/g1/g1NUMA.hpp"
28 #include "gc/g1/heapRegionRemSet.hpp"
29 #include "gc/g1/heapRegionSet.inline.hpp"
30
31 uint FreeRegionList::_unrealistically_long_length = 0;
32
33 #ifndef PRODUCT
34 void HeapRegionSetBase::verify_region(HeapRegion* hr) {
35 assert(hr->containing_set() == this, "Inconsistent containing set for %u", hr->hrm_index());
36 assert(!hr->is_young(), "Adding young region %u", hr->hrm_index()); // currently we don't use these sets for young regions
37 assert(_checker == NULL || _checker->is_correct_type(hr), "Wrong type of region %u (%s) and set %s",
38 hr->hrm_index(), hr->get_type_str(), name());
39 assert(!hr->is_free() || hr->is_empty(), "Free region %u is not empty for set %s", hr->hrm_index(), name());
40 assert(!hr->is_empty() || hr->is_free() || hr->is_archive(),
41 "Empty region %u is not free or archive for set %s", hr->hrm_index(), name());
42 }
43 #endif
44
45 void HeapRegionSetBase::verify() {
46 // It's important that we also observe the MT safety protocol even
47 // for the verification calls. If we do verification without the
85 {
86 }
87
88 void FreeRegionList::set_unrealistically_long_length(uint len) {
89 guarantee(_unrealistically_long_length == 0, "should only be set once");
90 _unrealistically_long_length = len;
91 }
92
93 void FreeRegionList::remove_all() {
94 check_mt_safety();
95 verify_optional();
96
97 HeapRegion* curr = _head;
98 while (curr != NULL) {
99 verify_region(curr);
100
101 HeapRegion* next = curr->next();
102 curr->set_next(NULL);
103 curr->set_prev(NULL);
104 curr->set_containing_set(NULL);
105
106 decrease_length(curr->node_index());
107
108 curr = next;
109 }
110 clear();
111
112 verify_optional();
113 }
114
115 void FreeRegionList::add_ordered(FreeRegionList* from_list) {
116 check_mt_safety();
117 from_list->check_mt_safety();
118
119 verify_optional();
120 from_list->verify_optional();
121
122 if (from_list->is_empty()) {
123 return;
124 }
125
126 if (_node_info != NULL && from_list->_node_info != NULL) {
127 _node_info->add(from_list->_node_info);
128 }
129
130 #ifdef ASSERT
131 FreeRegionListIterator iter(from_list);
132 while (iter.more_available()) {
133 HeapRegion* hr = iter.get_next();
134 // In set_containing_set() we check that we either set the value
135 // from NULL to non-NULL or vice versa to catch bugs. So, we have
136 // to NULL it first before setting it to the value.
137 hr->set_containing_set(NULL);
138 hr->set_containing_set(this);
139 }
140 #endif // ASSERT
141
142 if (is_empty()) {
143 assert_free_region_list(length() == 0 && _tail == NULL, "invariant");
144 _head = from_list->_head;
145 _tail = from_list->_tail;
146 } else {
147 HeapRegion* curr_to = _head;
148 HeapRegion* curr_from = from_list->_head;
149
211 } else {
212 assert_free_region_list(_head != curr, "invariant");
213 prev->set_next(next);
214 }
215 if (next == NULL) {
216 assert_free_region_list(_tail == curr, "invariant");
217 _tail = prev;
218 } else {
219 assert_free_region_list(_tail != curr, "invariant");
220 next->set_prev(prev);
221 }
222 if (_last == curr) {
223 _last = NULL;
224 }
225
226 curr->set_next(NULL);
227 curr->set_prev(NULL);
228 remove(curr);
229
230 count++;
231
232 decrease_length(curr->node_index());
233
234 curr = next;
235 }
236
237 assert(count == num_regions,
238 "[%s] count: %u should be == num_regions: %u",
239 name(), count, num_regions);
240 assert(length() + num_regions == old_length,
241 "[%s] new length should be consistent "
242 "new length: %u old length: %u num_regions: %u",
243 name(), length(), old_length, num_regions);
244
245 verify_optional();
246 }
247
248 uint FreeRegionList::num_of_regions_in_range(uint start, uint end) const {
249 HeapRegion* cur = _head;
250 uint num = 0;
251 while (cur != NULL) {
252 uint index = cur->hrm_index();
253 if (index > end) {
261 }
262
263 void FreeRegionList::verify() {
264 // See comment in HeapRegionSetBase::verify() about MT safety and
265 // verification.
266 check_mt_safety();
267
268 // This will also do the basic verification too.
269 verify_start();
270
271 verify_list();
272
273 verify_end();
274 }
275
276 void FreeRegionList::clear() {
277 _length = 0;
278 _head = NULL;
279 _tail = NULL;
280 _last = NULL;
281
282 if (_node_info!= NULL) {
283 _node_info->clear();
284 }
285 }
286
287 void FreeRegionList::verify_list() {
288 HeapRegion* curr = _head;
289 HeapRegion* prev1 = NULL;
290 HeapRegion* prev0 = NULL;
291 uint count = 0;
292 size_t capacity = 0;
293 uint last_index = 0;
294
295 guarantee(_head == NULL || _head->prev() == NULL, "_head should not have a prev");
296 while (curr != NULL) {
297 verify_region(curr);
298
299 count++;
300 guarantee(count < _unrealistically_long_length,
301 "[%s] the calculated length: %u seems very long, is there maybe a cycle? curr: " PTR_FORMAT " prev0: " PTR_FORMAT " " "prev1: " PTR_FORMAT " length: %u",
302 name(), count, p2i(curr), p2i(prev0), p2i(prev1), length());
303
304 if (curr->next() != NULL) {
305 guarantee(curr->next()->prev() == curr, "Next or prev pointers messed up");
306 }
307 guarantee(curr->hrm_index() == 0 || curr->hrm_index() > last_index, "List should be sorted");
308 last_index = curr->hrm_index();
309
310 capacity += curr->capacity();
311
312 prev1 = prev0;
313 prev0 = curr;
314 curr = curr->next();
315 }
316
317 guarantee(_tail == prev0, "Expected %s to end with %u but it ended with %u.", name(), _tail->hrm_index(), prev0->hrm_index());
318 guarantee(_tail == NULL || _tail->next() == NULL, "_tail should not have a next");
319 guarantee(length() == count, "%s count mismatch. Expected %u, actual %u.", name(), length(), count);
320 }
321
322
323 FreeRegionList::FreeRegionList(const char* name, HeapRegionSetChecker* checker):
324 HeapRegionSetBase(name, checker),
325 _node_info(G1NUMA::numa()->is_enabled() ? new NodeInfo() : NULL) {
326
327 clear();
328 }
329
330 FreeRegionList::~FreeRegionList() {
331 if (_node_info != NULL) {
332 delete _node_info;
333 }
334 }
335
336 FreeRegionList::NodeInfo::NodeInfo() : _numa(G1NUMA::numa()), _length_of_node(NULL),
337 _num_nodes(_numa->num_active_nodes()) {
338 assert(UseNUMA, "Invariant");
339
340 _length_of_node = NEW_C_HEAP_ARRAY(uint, _num_nodes, mtGC);
341 }
342
343 FreeRegionList::NodeInfo::~NodeInfo() {
344 FREE_C_HEAP_ARRAY(uint, _length_of_node);
345 }
346
347 void FreeRegionList::NodeInfo::clear() {
348 for (uint i = 0; i < _num_nodes; ++i) {
349 _length_of_node[i] = 0;
350 }
351 }
352
353 void FreeRegionList::NodeInfo::add(NodeInfo* info) {
354 for (uint i = 0; i < _num_nodes; ++i) {
355 _length_of_node[i] += info->_length_of_node[i];
356 }
357 }
358
|