src/share/vm/gc_implementation/g1/heapRegionSet.cpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/gc_implementation/g1/heapRegionSet.cpp	Wed Apr 27 01:25:04 2016 +0800
     1.3 @@ -0,0 +1,465 @@
     1.4 +/*
     1.5 + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 + * or visit www.oracle.com if you need additional information or have any
    1.24 + * questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +#include "precompiled.hpp"
    1.29 +#include "gc_implementation/g1/heapRegionRemSet.hpp"
    1.30 +#include "gc_implementation/g1/heapRegionSet.inline.hpp"
    1.31 +
    1.32 +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
    1.33 +
    1.34 +uint FreeRegionList::_unrealistically_long_length = 0;
    1.35 +
    1.36 +void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) {
    1.37 +  msg->append("[%s] %s ln: %u cy: "SIZE_FORMAT,
    1.38 +              name(), message, length(), total_capacity_bytes());
    1.39 +  fill_in_ext_msg_extra(msg);
    1.40 +}
    1.41 +
    1.42 +#ifndef PRODUCT
    1.43 +void HeapRegionSetBase::verify_region(HeapRegion* hr) {
    1.44 +  assert(hr->containing_set() == this, err_msg("Inconsistent containing set for %u", hr->hrs_index()));
    1.45 +  assert(!hr->is_young(), err_msg("Adding young region %u", hr->hrs_index())); // currently we don't use these sets for young regions
    1.46 +  assert(hr->isHumongous() == regions_humongous(), err_msg("Wrong humongous state for region %u and set %s", hr->hrs_index(), name()));
    1.47 +  assert(hr->is_empty() == regions_empty(), err_msg("Wrong empty state for region %u and set %s", hr->hrs_index(), name()));
    1.48 +  assert(hr->rem_set()->verify_ready_for_par_iteration(), err_msg("Wrong iteration state %u", hr->hrs_index()));
    1.49 +}
    1.50 +#endif
    1.51 +
    1.52 +void HeapRegionSetBase::verify() {
    1.53 +  // It's important that we also observe the MT safety protocol even
    1.54 +  // for the verification calls. If we do verification without the
    1.55 +  // appropriate locks and the set changes underneath our feet
    1.56 +  // verification might fail and send us on a wild goose chase.
    1.57 +  check_mt_safety();
    1.58 +
    1.59 +  guarantee(( is_empty() && length() == 0 && total_capacity_bytes() == 0) ||
    1.60 +            (!is_empty() && length() >= 0 && total_capacity_bytes() >= 0),
    1.61 +            hrs_ext_msg(this, "invariant"));
    1.62 +}
    1.63 +
    1.64 +void HeapRegionSetBase::verify_start() {
    1.65 +  // See comment in verify() about MT safety and verification.
    1.66 +  check_mt_safety();
    1.67 +  assert(!_verify_in_progress,
    1.68 +         hrs_ext_msg(this, "verification should not be in progress"));
    1.69 +
    1.70 +  // Do the basic verification first before we do the checks over the regions.
    1.71 +  HeapRegionSetBase::verify();
    1.72 +
    1.73 +  _verify_in_progress        = true;
    1.74 +}
    1.75 +
    1.76 +void HeapRegionSetBase::verify_end() {
    1.77 +  // See comment in verify() about MT safety and verification.
    1.78 +  check_mt_safety();
    1.79 +  assert(_verify_in_progress,
    1.80 +         hrs_ext_msg(this, "verification should be in progress"));
    1.81 +
    1.82 +  _verify_in_progress = false;
    1.83 +}
    1.84 +
    1.85 +void HeapRegionSetBase::print_on(outputStream* out, bool print_contents) {
    1.86 +  out->cr();
    1.87 +  out->print_cr("Set: %s ("PTR_FORMAT")", name(), this);
    1.88 +  out->print_cr("  Region Assumptions");
    1.89 +  out->print_cr("    humongous         : %s", BOOL_TO_STR(regions_humongous()));
    1.90 +  out->print_cr("    empty             : %s", BOOL_TO_STR(regions_empty()));
    1.91 +  out->print_cr("  Attributes");
    1.92 +  out->print_cr("    length            : %14u", length());
    1.93 +  out->print_cr("    total capacity    : "SIZE_FORMAT_W(14)" bytes",
    1.94 +                total_capacity_bytes());
    1.95 +}
    1.96 +
    1.97 +HeapRegionSetBase::HeapRegionSetBase(const char* name, bool humongous, bool empty, HRSMtSafeChecker* mt_safety_checker)
    1.98 +  : _name(name), _verify_in_progress(false),
    1.99 +    _is_humongous(humongous), _is_empty(empty), _mt_safety_checker(mt_safety_checker),
   1.100 +    _count()
   1.101 +{ }
   1.102 +
   1.103 +void FreeRegionList::set_unrealistically_long_length(uint len) {
   1.104 +  guarantee(_unrealistically_long_length == 0, "should only be set once");
   1.105 +  _unrealistically_long_length = len;
   1.106 +}
   1.107 +
   1.108 +void FreeRegionList::fill_in_ext_msg_extra(hrs_ext_msg* msg) {
   1.109 +  msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, head(), tail());
   1.110 +}
   1.111 +
   1.112 +void FreeRegionList::add_as_head_or_tail(FreeRegionList* from_list, bool as_head) {
   1.113 +  check_mt_safety();
   1.114 +  from_list->check_mt_safety();
   1.115 +
   1.116 +  verify_optional();
   1.117 +  from_list->verify_optional();
   1.118 +
   1.119 +  if (from_list->is_empty()) {
   1.120 +    return;
   1.121 +  }
   1.122 +
   1.123 +#ifdef ASSERT
   1.124 +  FreeRegionListIterator iter(from_list);
   1.125 +  while (iter.more_available()) {
   1.126 +    HeapRegion* hr = iter.get_next();
   1.127 +    // In set_containing_set() we check that we either set the value
   1.128 +    // from NULL to non-NULL or vice versa to catch bugs. So, we have
   1.129 +    // to NULL it first before setting it to the value.
   1.130 +    hr->set_containing_set(NULL);
   1.131 +    hr->set_containing_set(this);
   1.132 +  }
   1.133 +#endif // ASSERT
   1.134 +
   1.135 +  if (_head == NULL) {
   1.136 +    assert(length() == 0 && _tail == NULL, hrs_ext_msg(this, "invariant"));
   1.137 +    _head = from_list->_head;
   1.138 +    _tail = from_list->_tail;
   1.139 +  } else {
   1.140 +    assert(length() > 0 && _tail != NULL, hrs_ext_msg(this, "invariant"));
   1.141 +    if (as_head) {
   1.142 +      from_list->_tail->set_next(_head);
   1.143 +      _head->set_prev(from_list->_tail);
   1.144 +      _head = from_list->_head;
   1.145 +    } else {
   1.146 +      _tail->set_next(from_list->_head);
   1.147 +      from_list->_head->set_prev(_tail);
   1.148 +      _tail = from_list->_tail;
   1.149 +    }
   1.150 +  }
   1.151 +
   1.152 +  _count.increment(from_list->length(), from_list->total_capacity_bytes());
   1.153 +  from_list->clear();
   1.154 +
   1.155 +  verify_optional();
   1.156 +  from_list->verify_optional();
   1.157 +}
   1.158 +
   1.159 +void FreeRegionList::add_as_head(FreeRegionList* from_list) {
   1.160 +  add_as_head_or_tail(from_list, true /* as_head */);
   1.161 +}
   1.162 +
   1.163 +void FreeRegionList::add_as_tail(FreeRegionList* from_list) {
   1.164 +  add_as_head_or_tail(from_list, false /* as_head */);
   1.165 +}
   1.166 +
   1.167 +void FreeRegionList::remove_all() {
   1.168 +  check_mt_safety();
   1.169 +  verify_optional();
   1.170 +
   1.171 +  HeapRegion* curr = _head;
   1.172 +  while (curr != NULL) {
   1.173 +    verify_region(curr);
   1.174 +
   1.175 +    HeapRegion* next = curr->next();
   1.176 +    curr->set_next(NULL);
   1.177 +    curr->set_prev(NULL);
   1.178 +    curr->set_containing_set(NULL);
   1.179 +    curr = next;
   1.180 +  }
   1.181 +  clear();
   1.182 +
   1.183 +  verify_optional();
   1.184 +}
   1.185 +
   1.186 +void FreeRegionList::add_ordered(FreeRegionList* from_list) {
   1.187 +  check_mt_safety();
   1.188 +  from_list->check_mt_safety();
   1.189 +
   1.190 +  verify_optional();
   1.191 +  from_list->verify_optional();
   1.192 +
   1.193 +  if (from_list->is_empty()) {
   1.194 +    return;
   1.195 +  }
   1.196 +
   1.197 +  if (is_empty()) {
   1.198 +    add_as_head(from_list);
   1.199 +    return;
   1.200 +  }
   1.201 +
   1.202 +  #ifdef ASSERT
   1.203 +  FreeRegionListIterator iter(from_list);
   1.204 +  while (iter.more_available()) {
   1.205 +    HeapRegion* hr = iter.get_next();
   1.206 +    // In set_containing_set() we check that we either set the value
   1.207 +    // from NULL to non-NULL or vice versa to catch bugs. So, we have
   1.208 +    // to NULL it first before setting it to the value.
   1.209 +    hr->set_containing_set(NULL);
   1.210 +    hr->set_containing_set(this);
   1.211 +  }
   1.212 +  #endif // ASSERT
   1.213 +
   1.214 +  HeapRegion* curr_to = _head;
   1.215 +  HeapRegion* curr_from = from_list->_head;
   1.216 +
   1.217 +  while (curr_from != NULL) {
   1.218 +    while (curr_to != NULL && curr_to->hrs_index() < curr_from->hrs_index()) {
   1.219 +      curr_to = curr_to->next();
   1.220 +    }
   1.221 +
   1.222 +    if (curr_to == NULL) {
   1.223 +      // The rest of the from list should be added as tail
   1.224 +      _tail->set_next(curr_from);
   1.225 +      curr_from->set_prev(_tail);
   1.226 +      curr_from = NULL;
   1.227 +    } else {
   1.228 +      HeapRegion* next_from = curr_from->next();
   1.229 +
   1.230 +      curr_from->set_next(curr_to);
   1.231 +      curr_from->set_prev(curr_to->prev());
   1.232 +      if (curr_to->prev() == NULL) {
   1.233 +        _head = curr_from;
   1.234 +      } else {
   1.235 +        curr_to->prev()->set_next(curr_from);
   1.236 +      }
   1.237 +      curr_to->set_prev(curr_from);
   1.238 +
   1.239 +      curr_from = next_from;
   1.240 +    }
   1.241 +  }
   1.242 +
   1.243 +  if (_tail->hrs_index() < from_list->_tail->hrs_index()) {
   1.244 +    _tail = from_list->_tail;
   1.245 +  }
   1.246 +
   1.247 +  _count.increment(from_list->length(), from_list->total_capacity_bytes());
   1.248 +  from_list->clear();
   1.249 +
   1.250 +  verify_optional();
   1.251 +  from_list->verify_optional();
   1.252 +}
   1.253 +
   1.254 +void FreeRegionList::remove_all_pending(uint target_count) {
   1.255 +  check_mt_safety();
   1.256 +  assert(target_count > 1, hrs_ext_msg(this, "pre-condition"));
   1.257 +  assert(!is_empty(), hrs_ext_msg(this, "pre-condition"));
   1.258 +
   1.259 +  verify_optional();
   1.260 +  DEBUG_ONLY(uint old_length = length();)
   1.261 +
   1.262 +  HeapRegion* curr = _head;
   1.263 +  uint count = 0;
   1.264 +  while (curr != NULL) {
   1.265 +    verify_region(curr);
   1.266 +    HeapRegion* next = curr->next();
   1.267 +    HeapRegion* prev = curr->prev();
   1.268 +
   1.269 +    if (curr->pending_removal()) {
   1.270 +      assert(count < target_count,
   1.271 +             hrs_err_msg("[%s] should not come across more regions "
   1.272 +                         "pending for removal than target_count: %u",
   1.273 +                         name(), target_count));
   1.274 +
   1.275 +      if (prev == NULL) {
   1.276 +        assert(_head == curr, hrs_ext_msg(this, "invariant"));
   1.277 +        _head = next;
   1.278 +      } else {
   1.279 +        assert(_head != curr, hrs_ext_msg(this, "invariant"));
   1.280 +        prev->set_next(next);
   1.281 +      }
   1.282 +      if (next == NULL) {
   1.283 +        assert(_tail == curr, hrs_ext_msg(this, "invariant"));
   1.284 +        _tail = prev;
   1.285 +      } else {
   1.286 +        assert(_tail != curr, hrs_ext_msg(this, "invariant"));
   1.287 +        next->set_prev(prev);
   1.288 +      }
   1.289 +      if (_last = curr) {
   1.290 +        _last = NULL;
   1.291 +      }
   1.292 +
   1.293 +      curr->set_next(NULL);
   1.294 +      curr->set_prev(NULL);
   1.295 +      remove(curr);
   1.296 +      curr->set_pending_removal(false);
   1.297 +
   1.298 +      count += 1;
   1.299 +
   1.300 +      // If we have come across the target number of regions we can
   1.301 +      // just bail out. However, for debugging purposes, we can just
   1.302 +      // carry on iterating to make sure there are not more regions
   1.303 +      // tagged with pending removal.
   1.304 +      DEBUG_ONLY(if (count == target_count) break;)
   1.305 +    }
   1.306 +    curr = next;
   1.307 +  }
   1.308 +
   1.309 +  assert(count == target_count,
   1.310 +         hrs_err_msg("[%s] count: %u should be == target_count: %u",
   1.311 +                     name(), count, target_count));
   1.312 +  assert(length() + target_count == old_length,
   1.313 +         hrs_err_msg("[%s] new length should be consistent "
   1.314 +                     "new length: %u old length: %u target_count: %u",
   1.315 +                     name(), length(), old_length, target_count));
   1.316 +
   1.317 +  verify_optional();
   1.318 +}
   1.319 +
   1.320 +void FreeRegionList::verify() {
   1.321 +  // See comment in HeapRegionSetBase::verify() about MT safety and
   1.322 +  // verification.
   1.323 +  check_mt_safety();
   1.324 +
   1.325 +  // This will also do the basic verification too.
   1.326 +  verify_start();
   1.327 +
   1.328 +  verify_list();
   1.329 +
   1.330 +  verify_end();
   1.331 +}
   1.332 +
   1.333 +void FreeRegionList::clear() {
   1.334 +  _count = HeapRegionSetCount();
   1.335 +  _head = NULL;
   1.336 +  _tail = NULL;
   1.337 +  _last = NULL;
   1.338 +}
   1.339 +
   1.340 +void FreeRegionList::print_on(outputStream* out, bool print_contents) {
   1.341 +  HeapRegionSetBase::print_on(out, print_contents);
   1.342 +  out->print_cr("  Linking");
   1.343 +  out->print_cr("    head              : "PTR_FORMAT, _head);
   1.344 +  out->print_cr("    tail              : "PTR_FORMAT, _tail);
   1.345 +
   1.346 +  if (print_contents) {
   1.347 +    out->print_cr("  Contents");
   1.348 +    FreeRegionListIterator iter(this);
   1.349 +    while (iter.more_available()) {
   1.350 +      HeapRegion* hr = iter.get_next();
   1.351 +      hr->print_on(out);
   1.352 +    }
   1.353 +  }
   1.354 +}
   1.355 +
   1.356 +void FreeRegionList::verify_list() {
   1.357 +  HeapRegion* curr = head();
   1.358 +  HeapRegion* prev1 = NULL;
   1.359 +  HeapRegion* prev0 = NULL;
   1.360 +  uint count = 0;
   1.361 +  size_t capacity = 0;
   1.362 +  uint last_index = 0;
   1.363 +
   1.364 +  guarantee(_head == NULL || _head->prev() == NULL, "_head should not have a prev");
   1.365 +  while (curr != NULL) {
   1.366 +    verify_region(curr);
   1.367 +
   1.368 +    count++;
   1.369 +    guarantee(count < _unrealistically_long_length,
   1.370 +        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()));
   1.371 +
   1.372 +    if (curr->next() != NULL) {
   1.373 +      guarantee(curr->next()->prev() == curr, "Next or prev pointers messed up");
   1.374 +    }
   1.375 +    guarantee(curr->hrs_index() == 0 || curr->hrs_index() > last_index, "List should be sorted");
   1.376 +    last_index = curr->hrs_index();
   1.377 +
   1.378 +    capacity += curr->capacity();
   1.379 +
   1.380 +    prev1 = prev0;
   1.381 +    prev0 = curr;
   1.382 +    curr = curr->next();
   1.383 +  }
   1.384 +
   1.385 +  guarantee(tail() == prev0, err_msg("Expected %s to end with %u but it ended with %u.", name(), tail()->hrs_index(), prev0->hrs_index()));
   1.386 +  guarantee(_tail == NULL || _tail->next() == NULL, "_tail should not have a next");
   1.387 +  guarantee(length() == count, err_msg("%s count mismatch. Expected %u, actual %u.", name(), length(), count));
   1.388 +  guarantee(total_capacity_bytes() == capacity, err_msg("%s capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
   1.389 +      name(), total_capacity_bytes(), capacity));
   1.390 +}
   1.391 +
   1.392 +// Note on the check_mt_safety() methods below:
   1.393 +//
   1.394 +// Verification of the "master" heap region sets / lists that are
   1.395 +// maintained by G1CollectedHeap is always done during a STW pause and
   1.396 +// by the VM thread at the start / end of the pause. The standard
   1.397 +// verification methods all assert check_mt_safety(). This is
   1.398 +// important as it ensures that verification is done without
   1.399 +// concurrent updates taking place at the same time. It follows, that,
   1.400 +// for the "master" heap region sets / lists, the check_mt_safety()
   1.401 +// method should include the VM thread / STW case.
   1.402 +
   1.403 +void MasterFreeRegionListMtSafeChecker::check() {
   1.404 +  // Master Free List MT safety protocol:
   1.405 +  // (a) If we're at a safepoint, operations on the master free list
   1.406 +  // should be invoked by either the VM thread (which will serialize
   1.407 +  // them) or by the GC workers while holding the
   1.408 +  // FreeList_lock.
   1.409 +  // (b) If we're not at a safepoint, operations on the master free
   1.410 +  // list should be invoked while holding the Heap_lock.
   1.411 +
   1.412 +  if (SafepointSynchronize::is_at_safepoint()) {
   1.413 +    guarantee(Thread::current()->is_VM_thread() ||
   1.414 +              FreeList_lock->owned_by_self(), "master free list MT safety protocol at a safepoint");
   1.415 +  } else {
   1.416 +    guarantee(Heap_lock->owned_by_self(), "master free list MT safety protocol outside a safepoint");
   1.417 +  }
   1.418 +}
   1.419 +
   1.420 +void SecondaryFreeRegionListMtSafeChecker::check() {
   1.421 +  // Secondary Free List MT safety protocol:
   1.422 +  // Operations on the secondary free list should always be invoked
   1.423 +  // while holding the SecondaryFreeList_lock.
   1.424 +
   1.425 +  guarantee(SecondaryFreeList_lock->owned_by_self(), "secondary free list MT safety protocol");
   1.426 +}
   1.427 +
   1.428 +void OldRegionSetMtSafeChecker::check() {
   1.429 +  // Master Old Set MT safety protocol:
   1.430 +  // (a) If we're at a safepoint, operations on the master old set
   1.431 +  // should be invoked:
   1.432 +  // - by the VM thread (which will serialize them), or
   1.433 +  // - by the GC workers while holding the FreeList_lock, if we're
   1.434 +  //   at a safepoint for an evacuation pause (this lock is taken
   1.435 +  //   anyway when an GC alloc region is retired so that a new one
   1.436 +  //   is allocated from the free list), or
   1.437 +  // - by the GC workers while holding the OldSets_lock, if we're at a
   1.438 +  //   safepoint for a cleanup pause.
   1.439 +  // (b) If we're not at a safepoint, operations on the master old set
   1.440 +  // should be invoked while holding the Heap_lock.
   1.441 +
   1.442 +  if (SafepointSynchronize::is_at_safepoint()) {
   1.443 +    guarantee(Thread::current()->is_VM_thread()
   1.444 +        || FreeList_lock->owned_by_self() || OldSets_lock->owned_by_self(),
   1.445 +        "master old set MT safety protocol at a safepoint");
   1.446 +  } else {
   1.447 +    guarantee(Heap_lock->owned_by_self(), "master old set MT safety protocol outside a safepoint");
   1.448 +  }
   1.449 +}
   1.450 +
   1.451 +void HumongousRegionSetMtSafeChecker::check() {
   1.452 +  // Humongous Set MT safety protocol:
   1.453 +  // (a) If we're at a safepoint, operations on the master humongous
   1.454 +  // set should be invoked by either the VM thread (which will
   1.455 +  // serialize them) or by the GC workers while holding the
   1.456 +  // OldSets_lock.
   1.457 +  // (b) If we're not at a safepoint, operations on the master
   1.458 +  // humongous set should be invoked while holding the Heap_lock.
   1.459 +
   1.460 +  if (SafepointSynchronize::is_at_safepoint()) {
   1.461 +    guarantee(Thread::current()->is_VM_thread() ||
   1.462 +              OldSets_lock->owned_by_self(),
   1.463 +              "master humongous set MT safety protocol at a safepoint");
   1.464 +  } else {
   1.465 +    guarantee(Heap_lock->owned_by_self(),
   1.466 +              "master humongous set MT safety protocol outside a safepoint");
   1.467 +  }
   1.468 +}

mercurial