tonyp@2472: /* jwilhelm@6422: * Copyright (c) 2011, 2014, 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: #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_INLINE_HPP tonyp@2472: #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_INLINE_HPP tonyp@2472: tonyp@2472: #include "gc_implementation/g1/heapRegionSet.hpp" tonyp@2472: brutisso@6385: inline void HeapRegionSetBase::add(HeapRegion* hr) { brutisso@6385: check_mt_safety(); brutisso@6385: assert(hr->containing_set() == NULL, hrs_ext_msg(this, "should not already have a containing set %u")); jwilhelm@6549: assert(hr->next() == NULL && hr->prev() == NULL, hrs_ext_msg(this, "should not already be linked")); tonyp@2472: brutisso@6385: _count.increment(1u, hr->capacity()); brutisso@6385: hr->set_containing_set(this); brutisso@6385: verify_region(hr); tonyp@2472: } tonyp@2472: brutisso@6385: inline void HeapRegionSetBase::remove(HeapRegion* hr) { brutisso@6385: check_mt_safety(); brutisso@6385: verify_region(hr); jwilhelm@6549: assert(hr->next() == NULL && hr->prev() == NULL, hrs_ext_msg(this, "should already be unlinked")); tonyp@2472: tonyp@2472: hr->set_containing_set(NULL); brutisso@6385: assert(_count.length() > 0, hrs_ext_msg(this, "pre-condition")); brutisso@6385: _count.decrement(1u, hr->capacity()); tonyp@2472: } tonyp@2472: jwilhelm@6422: inline void FreeRegionList::add_ordered(HeapRegion* hr) { jwilhelm@6422: check_mt_safety(); jwilhelm@6422: assert((length() == 0 && _head == NULL && _tail == NULL) || jwilhelm@6422: (length() > 0 && _head != NULL && _tail != NULL), jwilhelm@6422: hrs_ext_msg(this, "invariant")); jwilhelm@6422: // add() will verify the region and check mt safety. jwilhelm@6422: add(hr); jwilhelm@6422: jwilhelm@6422: // Now link the region jwilhelm@6422: if (_head != NULL) { jwilhelm@6422: HeapRegion* curr; jwilhelm@6422: jwilhelm@6422: if (_last != NULL && _last->hrs_index() < hr->hrs_index()) { jwilhelm@6422: curr = _last; jwilhelm@6422: } else { jwilhelm@6422: curr = _head; jwilhelm@6422: } jwilhelm@6422: jwilhelm@6422: // Find first entry with a Region Index larger than entry to insert. jwilhelm@6422: while (curr != NULL && curr->hrs_index() < hr->hrs_index()) { jwilhelm@6422: curr = curr->next(); jwilhelm@6422: } jwilhelm@6422: jwilhelm@6422: hr->set_next(curr); jwilhelm@6422: jwilhelm@6422: if (curr == NULL) { jwilhelm@6422: // Adding at the end jwilhelm@6422: hr->set_prev(_tail); jwilhelm@6422: _tail->set_next(hr); jwilhelm@6422: _tail = hr; jwilhelm@6422: } else if (curr->prev() == NULL) { jwilhelm@6422: // Adding at the beginning jwilhelm@6422: hr->set_prev(NULL); jwilhelm@6422: _head = hr; jwilhelm@6422: curr->set_prev(hr); jwilhelm@6422: } else { jwilhelm@6422: hr->set_prev(curr->prev()); jwilhelm@6422: hr->prev()->set_next(hr); jwilhelm@6422: curr->set_prev(hr); jwilhelm@6422: } jwilhelm@6422: } else { jwilhelm@6422: // The list was empty jwilhelm@6422: _tail = hr; jwilhelm@6422: _head = hr; jwilhelm@6422: } jwilhelm@6422: _last = hr; jwilhelm@6422: } jwilhelm@6422: brutisso@6385: inline void FreeRegionList::add_as_head(HeapRegion* hr) { tonyp@2714: assert((length() == 0 && _head == NULL && _tail == NULL) || tonyp@2714: (length() > 0 && _head != NULL && _tail != NULL), tonyp@2714: hrs_ext_msg(this, "invariant")); brutisso@6385: // add() will verify the region and check mt safety. brutisso@6385: add(hr); tonyp@2714: tonyp@2714: // Now link the region. tonyp@2714: if (_head != NULL) { tonyp@2714: hr->set_next(_head); jwilhelm@6422: _head->set_prev(hr); tonyp@2714: } else { tonyp@2714: _tail = hr; tonyp@2714: } tonyp@2714: _head = hr; tonyp@2714: } tonyp@2714: brutisso@6385: inline void FreeRegionList::add_as_tail(HeapRegion* hr) { brutisso@6385: check_mt_safety(); tonyp@2472: assert((length() == 0 && _head == NULL && _tail == NULL) || tonyp@2472: (length() > 0 && _head != NULL && _tail != NULL), tonyp@2643: hrs_ext_msg(this, "invariant")); jwilhelm@6422: // add() will verify the region and check mt safety. brutisso@6385: add(hr); tonyp@2472: tonyp@2472: // Now link the region. tonyp@2472: if (_tail != NULL) { tonyp@2472: _tail->set_next(hr); jwilhelm@6422: hr->set_prev(_tail); tonyp@2472: } else { tonyp@2472: _head = hr; tonyp@2472: } tonyp@2472: _tail = hr; tonyp@2472: } tonyp@2472: brutisso@6385: inline HeapRegion* FreeRegionList::remove_head() { tonyp@2643: assert(!is_empty(), hrs_ext_msg(this, "the list should not be empty")); tonyp@2472: assert(length() > 0 && _head != NULL && _tail != NULL, tonyp@2643: hrs_ext_msg(this, "invariant")); tonyp@2472: tonyp@2472: // We need to unlink it first. tonyp@2472: HeapRegion* hr = _head; tonyp@2472: _head = hr->next(); tonyp@2472: if (_head == NULL) { tonyp@2472: _tail = NULL; jwilhelm@6422: } else { jwilhelm@6422: _head->set_prev(NULL); tonyp@2472: } tonyp@2472: hr->set_next(NULL); tonyp@2472: jwilhelm@6422: if (_last == hr) { jwilhelm@6422: _last = NULL; jwilhelm@6422: } jwilhelm@6422: jwilhelm@6422: // remove() will verify the region and check mt safety. brutisso@6385: remove(hr); tonyp@2472: return hr; tonyp@2472: } tonyp@2472: brutisso@6385: inline HeapRegion* FreeRegionList::remove_head_or_null() { brutisso@6385: check_mt_safety(); tonyp@2472: if (!is_empty()) { tonyp@2472: return remove_head(); tonyp@2472: } else { tonyp@2472: return NULL; tonyp@2472: } tonyp@2472: } tonyp@2472: jwilhelm@6422: inline HeapRegion* FreeRegionList::remove_tail() { jwilhelm@6422: assert(!is_empty(), hrs_ext_msg(this, "The list should not be empty")); jwilhelm@6422: assert(length() > 0 && _head != NULL && _tail != NULL, jwilhelm@6422: hrs_ext_msg(this, "invariant")); jwilhelm@6422: jwilhelm@6422: // We need to unlink it first jwilhelm@6422: HeapRegion* hr = _tail; jwilhelm@6422: jwilhelm@6422: _tail = hr->prev(); jwilhelm@6422: if (_tail == NULL) { jwilhelm@6422: _head = NULL; jwilhelm@6422: } else { jwilhelm@6422: _tail->set_next(NULL); jwilhelm@6422: } jwilhelm@6422: hr->set_prev(NULL); jwilhelm@6422: jwilhelm@6422: if (_last == hr) { jwilhelm@6422: _last = NULL; jwilhelm@6422: } jwilhelm@6422: jwilhelm@6422: // remove() will verify the region and check mt safety. jwilhelm@6422: remove(hr); jwilhelm@6422: return hr; jwilhelm@6422: } jwilhelm@6422: jwilhelm@6422: inline HeapRegion* FreeRegionList::remove_tail_or_null() { jwilhelm@6422: check_mt_safety(); jwilhelm@6422: jwilhelm@6422: if (!is_empty()) { jwilhelm@6422: return remove_tail(); jwilhelm@6422: } else { jwilhelm@6422: return NULL; jwilhelm@6422: } jwilhelm@6422: } jwilhelm@6422: jwilhelm@6422: inline HeapRegion* FreeRegionList::remove_region(bool from_head) { jwilhelm@6422: if (from_head) { jwilhelm@6422: return remove_head_or_null(); jwilhelm@6422: } else { jwilhelm@6422: return remove_tail_or_null(); jwilhelm@6422: } jwilhelm@6422: } jwilhelm@6422: tonyp@2472: #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_INLINE_HPP