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 +}