< prev index next >

src/hotspot/share/gc/g1/heapRegionSet.cpp

Print this page
rev 56461 : imported patch 8220312.stat.2
rev 56463 : [mq]: 8220312.stat.4
   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   clear();
 327 }
 328 
 329 FreeRegionList::~FreeRegionList() {
 330   if (_node_info != NULL) {
 331     delete _node_info;
 332   }
 333 }
 334 
 335 NodeInfo::NodeInfo() : _numa(G1NUMA::numa()), _length_of_node(NULL),
 336                        _num_nodes(_numa->num_active_nodes()) {
 337   assert(UseNUMA, "Invariant");
 338 
 339   _length_of_node = NEW_C_HEAP_ARRAY(uint, _num_nodes, mtGC);
 340 }
 341 
 342 NodeInfo::~NodeInfo() {
 343   FREE_C_HEAP_ARRAY(uint, _length_of_node);
 344 }
 345 
 346 void NodeInfo::clear() {
 347   for (uint i = 0; i < _num_nodes; ++i) {
 348     _length_of_node[i] = 0;
 349   }
 350 }
 351 
 352 void NodeInfo::add(NodeInfo* info) {
 353   for (uint i = 0; i < _num_nodes; ++i) {
 354     _length_of_node[i] += info->_length_of_node[i];
 355   }
 356 }
 357 
< prev index next >