src/hotspot/share/gc/g1/heapRegionSet.cpp
changeset 47216 71c04702a3d5
parent 42030 f7c0010a447e
child 49632 64f9ebc85e67
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 2011, 2016, 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(hr->is_humongous() == regions_humongous(), "Wrong humongous state for region %u and set %s", hr->hrm_index(), name());
       
    37   assert(hr->is_free() == regions_free(), "Wrong free state for region %u and set %s", hr->hrm_index(), 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
       
    47   // appropriate locks and the set changes underneath our feet
       
    48   // verification might fail and send us on a wild goose chase.
       
    49   check_mt_safety();
       
    50 
       
    51   guarantee_heap_region_set(( is_empty() && length() == 0) ||
       
    52                             (!is_empty() && length() > 0),
       
    53                             "invariant");
       
    54 }
       
    55 
       
    56 void HeapRegionSetBase::verify_start() {
       
    57   // See comment in verify() about MT safety and verification.
       
    58   check_mt_safety();
       
    59   assert_heap_region_set(!_verify_in_progress, "verification should not be in progress");
       
    60 
       
    61   // Do the basic verification first before we do the checks over the regions.
       
    62   HeapRegionSetBase::verify();
       
    63 
       
    64   _verify_in_progress = true;
       
    65 }
       
    66 
       
    67 void HeapRegionSetBase::verify_end() {
       
    68   // See comment in verify() about MT safety and verification.
       
    69   check_mt_safety();
       
    70   assert_heap_region_set(_verify_in_progress, "verification should be in progress");
       
    71 
       
    72   _verify_in_progress = false;
       
    73 }
       
    74 
       
    75 void HeapRegionSetBase::print_on(outputStream* out, bool print_contents) {
       
    76   out->cr();
       
    77   out->print_cr("Set: %s (" PTR_FORMAT ")", name(), p2i(this));
       
    78   out->print_cr("  Region Assumptions");
       
    79   out->print_cr("    humongous         : %s", BOOL_TO_STR(regions_humongous()));
       
    80   out->print_cr("    free              : %s", BOOL_TO_STR(regions_free()));
       
    81   out->print_cr("  Attributes");
       
    82   out->print_cr("    length            : %14u", length());
       
    83 }
       
    84 
       
    85 HeapRegionSetBase::HeapRegionSetBase(const char* name, bool humongous, bool free, HRSMtSafeChecker* mt_safety_checker)
       
    86   : _name(name), _verify_in_progress(false),
       
    87     _is_humongous(humongous), _is_free(free), _mt_safety_checker(mt_safety_checker),
       
    88     _length(0)
       
    89 { }
       
    90 
       
    91 void FreeRegionList::set_unrealistically_long_length(uint len) {
       
    92   guarantee(_unrealistically_long_length == 0, "should only be set once");
       
    93   _unrealistically_long_length = len;
       
    94 }
       
    95 
       
    96 void FreeRegionList::remove_all() {
       
    97   check_mt_safety();
       
    98   verify_optional();
       
    99 
       
   100   HeapRegion* curr = _head;
       
   101   while (curr != NULL) {
       
   102     verify_region(curr);
       
   103 
       
   104     HeapRegion* next = curr->next();
       
   105     curr->set_next(NULL);
       
   106     curr->set_prev(NULL);
       
   107     curr->set_containing_set(NULL);
       
   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   #ifdef ASSERT
       
   127   FreeRegionListIterator iter(from_list);
       
   128   while (iter.more_available()) {
       
   129     HeapRegion* hr = iter.get_next();
       
   130     // In set_containing_set() we check that we either set the value
       
   131     // from NULL to non-NULL or vice versa to catch bugs. So, we have
       
   132     // to NULL it first before setting it to the value.
       
   133     hr->set_containing_set(NULL);
       
   134     hr->set_containing_set(this);
       
   135   }
       
   136   #endif // ASSERT
       
   137 
       
   138   if (is_empty()) {
       
   139     assert_free_region_list(length() == 0 && _tail == NULL, "invariant");
       
   140     _head = from_list->_head;
       
   141     _tail = from_list->_tail;
       
   142   } else {
       
   143     HeapRegion* curr_to = _head;
       
   144     HeapRegion* curr_from = from_list->_head;
       
   145 
       
   146     while (curr_from != NULL) {
       
   147       while (curr_to != NULL && curr_to->hrm_index() < curr_from->hrm_index()) {
       
   148         curr_to = curr_to->next();
       
   149       }
       
   150 
       
   151       if (curr_to == NULL) {
       
   152         // The rest of the from list should be added as tail
       
   153         _tail->set_next(curr_from);
       
   154         curr_from->set_prev(_tail);
       
   155         curr_from = NULL;
       
   156       } else {
       
   157         HeapRegion* next_from = curr_from->next();
       
   158 
       
   159         curr_from->set_next(curr_to);
       
   160         curr_from->set_prev(curr_to->prev());
       
   161         if (curr_to->prev() == NULL) {
       
   162           _head = curr_from;
       
   163         } else {
       
   164           curr_to->prev()->set_next(curr_from);
       
   165         }
       
   166         curr_to->set_prev(curr_from);
       
   167 
       
   168         curr_from = next_from;
       
   169       }
       
   170     }
       
   171 
       
   172     if (_tail->hrm_index() < from_list->_tail->hrm_index()) {
       
   173       _tail = from_list->_tail;
       
   174     }
       
   175   }
       
   176 
       
   177   _length += from_list->length();
       
   178   from_list->clear();
       
   179 
       
   180   verify_optional();
       
   181   from_list->verify_optional();
       
   182 }
       
   183 
       
   184 void FreeRegionList::remove_starting_at(HeapRegion* first, uint num_regions) {
       
   185   check_mt_safety();
       
   186   assert_free_region_list(num_regions >= 1, "pre-condition");
       
   187   assert_free_region_list(!is_empty(), "pre-condition");
       
   188 
       
   189   verify_optional();
       
   190   DEBUG_ONLY(uint old_length = length();)
       
   191 
       
   192   HeapRegion* curr = first;
       
   193   uint count = 0;
       
   194   while (count < num_regions) {
       
   195     verify_region(curr);
       
   196     HeapRegion* next = curr->next();
       
   197     HeapRegion* prev = curr->prev();
       
   198 
       
   199     assert(count < num_regions,
       
   200            "[%s] should not come across more regions "
       
   201            "pending for removal than num_regions: %u",
       
   202            name(), num_regions);
       
   203 
       
   204     if (prev == NULL) {
       
   205       assert_free_region_list(_head == curr, "invariant");
       
   206       _head = next;
       
   207     } else {
       
   208       assert_free_region_list(_head != curr, "invariant");
       
   209       prev->set_next(next);
       
   210     }
       
   211     if (next == NULL) {
       
   212       assert_free_region_list(_tail == curr, "invariant");
       
   213       _tail = prev;
       
   214     } else {
       
   215       assert_free_region_list(_tail != curr, "invariant");
       
   216       next->set_prev(prev);
       
   217     }
       
   218     if (_last == curr) {
       
   219       _last = NULL;
       
   220     }
       
   221 
       
   222     curr->set_next(NULL);
       
   223     curr->set_prev(NULL);
       
   224     remove(curr);
       
   225 
       
   226     count++;
       
   227     curr = next;
       
   228   }
       
   229 
       
   230   assert(count == num_regions,
       
   231          "[%s] count: %u should be == num_regions: %u",
       
   232          name(), count, num_regions);
       
   233   assert(length() + num_regions == old_length,
       
   234          "[%s] new length should be consistent "
       
   235          "new length: %u old length: %u num_regions: %u",
       
   236          name(), length(), old_length, num_regions);
       
   237 
       
   238   verify_optional();
       
   239 }
       
   240 
       
   241 void FreeRegionList::verify() {
       
   242   // See comment in HeapRegionSetBase::verify() about MT safety and
       
   243   // verification.
       
   244   check_mt_safety();
       
   245 
       
   246   // This will also do the basic verification too.
       
   247   verify_start();
       
   248 
       
   249   verify_list();
       
   250 
       
   251   verify_end();
       
   252 }
       
   253 
       
   254 void FreeRegionList::clear() {
       
   255   _length = 0;
       
   256   _head = NULL;
       
   257   _tail = NULL;
       
   258   _last = NULL;
       
   259 }
       
   260 
       
   261 void FreeRegionList::verify_list() {
       
   262   HeapRegion* curr = _head;
       
   263   HeapRegion* prev1 = NULL;
       
   264   HeapRegion* prev0 = NULL;
       
   265   uint count = 0;
       
   266   size_t capacity = 0;
       
   267   uint last_index = 0;
       
   268 
       
   269   guarantee(_head == NULL || _head->prev() == NULL, "_head should not have a prev");
       
   270   while (curr != NULL) {
       
   271     verify_region(curr);
       
   272 
       
   273     count++;
       
   274     guarantee(count < _unrealistically_long_length,
       
   275               "[%s] the calculated length: %u seems very long, is there maybe a cycle? curr: " PTR_FORMAT " prev0: " PTR_FORMAT " " "prev1: " PTR_FORMAT " length: %u",
       
   276               name(), count, p2i(curr), p2i(prev0), p2i(prev1), length());
       
   277 
       
   278     if (curr->next() != NULL) {
       
   279       guarantee(curr->next()->prev() == curr, "Next or prev pointers messed up");
       
   280     }
       
   281     guarantee(curr->hrm_index() == 0 || curr->hrm_index() > last_index, "List should be sorted");
       
   282     last_index = curr->hrm_index();
       
   283 
       
   284     capacity += curr->capacity();
       
   285 
       
   286     prev1 = prev0;
       
   287     prev0 = curr;
       
   288     curr = curr->next();
       
   289   }
       
   290 
       
   291   guarantee(_tail == prev0, "Expected %s to end with %u but it ended with %u.", name(), _tail->hrm_index(), prev0->hrm_index());
       
   292   guarantee(_tail == NULL || _tail->next() == NULL, "_tail should not have a next");
       
   293   guarantee(length() == count, "%s count mismatch. Expected %u, actual %u.", name(), length(), count);
       
   294 }
       
   295 
       
   296 // Note on the check_mt_safety() methods below:
       
   297 //
       
   298 // Verification of the "master" heap region sets / lists that are
       
   299 // maintained by G1CollectedHeap is always done during a STW pause and
       
   300 // by the VM thread at the start / end of the pause. The standard
       
   301 // verification methods all assert check_mt_safety(). This is
       
   302 // important as it ensures that verification is done without
       
   303 // concurrent updates taking place at the same time. It follows, that,
       
   304 // for the "master" heap region sets / lists, the check_mt_safety()
       
   305 // method should include the VM thread / STW case.
       
   306 
       
   307 void MasterFreeRegionListMtSafeChecker::check() {
       
   308   // Master Free List MT safety protocol:
       
   309   // (a) If we're at a safepoint, operations on the master free list
       
   310   // should be invoked by either the VM thread (which will serialize
       
   311   // them) or by the GC workers while holding the
       
   312   // FreeList_lock.
       
   313   // (b) If we're not at a safepoint, operations on the master free
       
   314   // list should be invoked while holding the Heap_lock.
       
   315 
       
   316   if (SafepointSynchronize::is_at_safepoint()) {
       
   317     guarantee(Thread::current()->is_VM_thread() ||
       
   318               FreeList_lock->owned_by_self(), "master free list MT safety protocol at a safepoint");
       
   319   } else {
       
   320     guarantee(Heap_lock->owned_by_self(), "master free list MT safety protocol outside a safepoint");
       
   321   }
       
   322 }
       
   323 
       
   324 void SecondaryFreeRegionListMtSafeChecker::check() {
       
   325   // Secondary Free List MT safety protocol:
       
   326   // Operations on the secondary free list should always be invoked
       
   327   // while holding the SecondaryFreeList_lock.
       
   328 
       
   329   guarantee(SecondaryFreeList_lock->owned_by_self(), "secondary free list MT safety protocol");
       
   330 }
       
   331 
       
   332 void OldRegionSetMtSafeChecker::check() {
       
   333   // Master Old Set MT safety protocol:
       
   334   // (a) If we're at a safepoint, operations on the master old set
       
   335   // should be invoked:
       
   336   // - by the VM thread (which will serialize them), or
       
   337   // - by the GC workers while holding the FreeList_lock, if we're
       
   338   //   at a safepoint for an evacuation pause (this lock is taken
       
   339   //   anyway when an GC alloc region is retired so that a new one
       
   340   //   is allocated from the free list), or
       
   341   // - by the GC workers while holding the OldSets_lock, if we're at a
       
   342   //   safepoint for a cleanup pause.
       
   343   // (b) If we're not at a safepoint, operations on the master old set
       
   344   // should be invoked while holding the Heap_lock.
       
   345 
       
   346   if (SafepointSynchronize::is_at_safepoint()) {
       
   347     guarantee(Thread::current()->is_VM_thread()
       
   348         || FreeList_lock->owned_by_self() || OldSets_lock->owned_by_self(),
       
   349         "master old set MT safety protocol at a safepoint");
       
   350   } else {
       
   351     guarantee(Heap_lock->owned_by_self(), "master old set MT safety protocol outside a safepoint");
       
   352   }
       
   353 }
       
   354 
       
   355 void HumongousRegionSetMtSafeChecker::check() {
       
   356   // Humongous Set MT safety protocol:
       
   357   // (a) If we're at a safepoint, operations on the master humongous
       
   358   // set should be invoked by either the VM thread (which will
       
   359   // serialize them) or by the GC workers while holding the
       
   360   // OldSets_lock.
       
   361   // (b) If we're not at a safepoint, operations on the master
       
   362   // humongous set should be invoked while holding the Heap_lock.
       
   363 
       
   364   if (SafepointSynchronize::is_at_safepoint()) {
       
   365     guarantee(Thread::current()->is_VM_thread() ||
       
   366               OldSets_lock->owned_by_self(),
       
   367               "master humongous set MT safety protocol at a safepoint");
       
   368   } else {
       
   369     guarantee(Heap_lock->owned_by_self(),
       
   370               "master humongous set MT safety protocol outside a safepoint");
       
   371   }
       
   372 }