tonyp@2472: /* tonyp@2472: * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. tonyp@2472: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. tonyp@2472: * tonyp@2472: * This code is free software; you can redistribute it and/or modify it tonyp@2472: * under the terms of the GNU General Public License version 2 only, as tonyp@2472: * published by the Free Software Foundation. tonyp@2472: * tonyp@2472: * This code is distributed in the hope that it will be useful, but WITHOUT tonyp@2472: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or tonyp@2472: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License tonyp@2472: * version 2 for more details (a copy is included in the LICENSE file that tonyp@2472: * accompanied this code). tonyp@2472: * tonyp@2472: * You should have received a copy of the GNU General Public License version tonyp@2472: * 2 along with this work; if not, write to the Free Software Foundation, tonyp@2472: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. tonyp@2472: * tonyp@2472: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA tonyp@2472: * or visit www.oracle.com if you need additional information or have any tonyp@2472: * questions. tonyp@2472: * tonyp@2472: */ tonyp@2472: tonyp@2472: #include "precompiled.hpp" tonyp@2974: #include "gc_implementation/g1/heapRegionRemSet.hpp" tonyp@2472: #include "gc_implementation/g1/heapRegionSets.hpp" tonyp@2472: tonyp@3268: // Note on the check_mt_safety() methods below: tonyp@3268: // tonyp@3268: // Verification of the "master" heap region sets / lists that are tonyp@3268: // maintained by G1CollectedHeap is always done during a STW pause and tonyp@3268: // by the VM thread at the start / end of the pause. The standard tonyp@3268: // verification methods all assert check_mt_safety(). This is tonyp@3268: // important as it ensures that verification is done without tonyp@3268: // concurrent updates taking place at the same time. It follows, that, tonyp@3268: // for the "master" heap region sets / lists, the check_mt_safety() tonyp@3268: // method should include the VM thread / STW case. tonyp@3268: tonyp@2472: //////////////////// FreeRegionList //////////////////// tonyp@2472: tonyp@2472: const char* FreeRegionList::verify_region_extra(HeapRegion* hr) { tonyp@2472: if (hr->is_young()) { tonyp@2472: return "the region should not be young"; tonyp@2472: } tonyp@2472: // The superclass will check that the region is empty and tonyp@3268: // not humongous. tonyp@2472: return HeapRegionLinkedList::verify_region_extra(hr); tonyp@2472: } tonyp@2472: tonyp@2472: //////////////////// MasterFreeRegionList //////////////////// tonyp@2472: tonyp@2974: const char* MasterFreeRegionList::verify_region_extra(HeapRegion* hr) { tonyp@2974: // We should reset the RSet for parallel iteration before we add it tonyp@2974: // to the master free list so that it is ready when the region is tonyp@2974: // re-allocated. tonyp@2974: if (!hr->rem_set()->verify_ready_for_par_iteration()) { tonyp@2974: return "the region's RSet should be ready for parallel iteration"; tonyp@2974: } tonyp@2974: return FreeRegionList::verify_region_extra(hr); tonyp@2974: } tonyp@2974: tonyp@2472: bool MasterFreeRegionList::check_mt_safety() { tonyp@2472: // Master Free List MT safety protocol: tonyp@2472: // (a) If we're at a safepoint, operations on the master free list tonyp@2472: // should be invoked by either the VM thread (which will serialize tonyp@2472: // them) or by the GC workers while holding the tonyp@2472: // FreeList_lock. tonyp@2472: // (b) If we're not at a safepoint, operations on the master free tonyp@2472: // list should be invoked while holding the Heap_lock. tonyp@2472: tonyp@3268: if (SafepointSynchronize::is_at_safepoint()) { tonyp@3268: guarantee(Thread::current()->is_VM_thread() || tonyp@3268: FreeList_lock->owned_by_self(), tonyp@3268: hrs_ext_msg(this, "master free list MT safety protocol " tonyp@3268: "at a safepoint")); tonyp@3268: } else { tonyp@3268: guarantee(Heap_lock->owned_by_self(), tonyp@3268: hrs_ext_msg(this, "master free list MT safety protocol " tonyp@3268: "outside a safepoint")); tonyp@3268: } tonyp@2472: tonyp@2472: return FreeRegionList::check_mt_safety(); tonyp@2472: } tonyp@2472: tonyp@2472: //////////////////// SecondaryFreeRegionList //////////////////// tonyp@2472: tonyp@2472: bool SecondaryFreeRegionList::check_mt_safety() { tonyp@2472: // Secondary Free List MT safety protocol: tonyp@2472: // Operations on the secondary free list should always be invoked tonyp@2472: // while holding the SecondaryFreeList_lock. tonyp@2472: tonyp@2472: guarantee(SecondaryFreeList_lock->owned_by_self(), tonyp@2643: hrs_ext_msg(this, "secondary free list MT safety protocol")); tonyp@2472: tonyp@2472: return FreeRegionList::check_mt_safety(); tonyp@2472: } tonyp@2472: tonyp@3268: //////////////////// OldRegionSet //////////////////// tonyp@3268: tonyp@3268: const char* OldRegionSet::verify_region_extra(HeapRegion* hr) { tonyp@3268: if (hr->is_young()) { tonyp@3268: return "the region should not be young"; tonyp@3268: } tonyp@3268: // The superclass will check that the region is not empty and not tonyp@3268: // humongous. tonyp@3268: return HeapRegionSet::verify_region_extra(hr); tonyp@3268: } tonyp@3268: tonyp@3268: //////////////////// MasterOldRegionSet //////////////////// tonyp@3268: tonyp@3268: bool MasterOldRegionSet::check_mt_safety() { tonyp@3268: // Master Old Set MT safety protocol: tonyp@3268: // (a) If we're at a safepoint, operations on the master old set tonyp@3268: // should be invoked: tonyp@3268: // - by the VM thread (which will serialize them), or tonyp@3268: // - by the GC workers while holding the FreeList_lock, if we're tonyp@3268: // at a safepoint for an evacuation pause (this lock is taken tonyp@3268: // anyway when an GC alloc region is retired so that a new one tonyp@3268: // is allocated from the free list), or tonyp@3268: // - by the GC workers while holding the OldSets_lock, if we're at a tonyp@3268: // safepoint for a cleanup pause. tonyp@3268: // (b) If we're not at a safepoint, operations on the master old set tonyp@3268: // should be invoked while holding the Heap_lock. tonyp@3268: tonyp@3268: if (SafepointSynchronize::is_at_safepoint()) { tonyp@3268: guarantee(Thread::current()->is_VM_thread() || tonyp@3268: _phase == HRSPhaseEvacuation && FreeList_lock->owned_by_self() || tonyp@3268: _phase == HRSPhaseCleanup && OldSets_lock->owned_by_self(), tonyp@3268: hrs_ext_msg(this, "master old set MT safety protocol " tonyp@3268: "at a safepoint")); tonyp@3268: } else { tonyp@3268: guarantee(Heap_lock->owned_by_self(), tonyp@3268: hrs_ext_msg(this, "master old set MT safety protocol " tonyp@3268: "outside a safepoint")); tonyp@3268: } tonyp@3268: tonyp@3268: return OldRegionSet::check_mt_safety(); tonyp@3268: } tonyp@3268: tonyp@2472: //////////////////// HumongousRegionSet //////////////////// tonyp@2472: tonyp@2472: const char* HumongousRegionSet::verify_region_extra(HeapRegion* hr) { tonyp@2472: if (hr->is_young()) { tonyp@2472: return "the region should not be young"; tonyp@2472: } tonyp@2472: // The superclass will check that the region is not empty and tonyp@2472: // humongous. tonyp@2472: return HeapRegionSet::verify_region_extra(hr); tonyp@2472: } tonyp@2472: tonyp@2643: //////////////////// MasterHumongousRegionSet //////////////////// tonyp@2472: tonyp@2472: bool MasterHumongousRegionSet::check_mt_safety() { tonyp@2472: // Master Humongous Set MT safety protocol: tonyp@2472: // (a) If we're at a safepoint, operations on the master humongous tonyp@2472: // set should be invoked by either the VM thread (which will tonyp@2472: // serialize them) or by the GC workers while holding the tonyp@2472: // OldSets_lock. tonyp@2472: // (b) If we're not at a safepoint, operations on the master tonyp@2472: // humongous set should be invoked while holding the Heap_lock. tonyp@2472: tonyp@3268: if (SafepointSynchronize::is_at_safepoint()) { tonyp@3268: guarantee(Thread::current()->is_VM_thread() || tonyp@3268: OldSets_lock->owned_by_self(), tonyp@3268: hrs_ext_msg(this, "master humongous set MT safety protocol " tonyp@3268: "at a safepoint")); tonyp@3268: } else { tonyp@3268: guarantee(Heap_lock->owned_by_self(), tonyp@3268: hrs_ext_msg(this, "master humongous set MT safety protocol " tonyp@3268: "outside a safepoint")); tonyp@3268: } tonyp@3268: tonyp@2472: return HumongousRegionSet::check_mt_safety(); tonyp@2472: }