ysr@777: /* tonyp@2469: * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. ysr@777: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ysr@777: * ysr@777: * This code is free software; you can redistribute it and/or modify it ysr@777: * under the terms of the GNU General Public License version 2 only, as ysr@777: * published by the Free Software Foundation. ysr@777: * ysr@777: * This code is distributed in the hope that it will be useful, but WITHOUT ysr@777: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ysr@777: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ysr@777: * version 2 for more details (a copy is included in the LICENSE file that ysr@777: * accompanied this code). ysr@777: * ysr@777: * You should have received a copy of the GNU General Public License version ysr@777: * 2 along with this work; if not, write to the Free Software Foundation, ysr@777: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ysr@777: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. ysr@777: * ysr@777: */ ysr@777: stefank@2314: #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP stefank@2314: #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP stefank@2314: ysr@777: class HeapRegion; ysr@777: class HeapRegionClosure; tonyp@2963: class FreeRegionList; tonyp@2963: tonyp@2963: #define G1_NULL_HRS_INDEX ((size_t) -1) tonyp@2963: tonyp@2963: // This class keeps track of the region metadata (i.e., HeapRegion tonyp@2963: // instances). They are kept in the _regions array in address tonyp@2963: // order. A region's index in the array corresponds to its index in tonyp@2963: // the heap (i.e., 0 is the region at the bottom of the heap, 1 is tonyp@2963: // the one after it, etc.). Two regions that are consecutive in the tonyp@2963: // array should also be adjacent in the address space (i.e., tonyp@2963: // region(i).end() == region(i+1).bottom(). tonyp@2963: // tonyp@2963: // We create a HeapRegion when we commit the region's address space tonyp@2963: // for the first time. When we uncommit the address space of a tonyp@2963: // region we retain the HeapRegion to be able to re-use it in the tonyp@2963: // future (in case we recommit it). tonyp@2963: // tonyp@2963: // We keep track of three lengths: tonyp@2963: // tonyp@2963: // * _length (returned by length()) is the number of currently tonyp@2963: // committed regions. tonyp@2963: // * _allocated_length (not exposed outside this class) is the tonyp@2963: // number of regions for which we have HeapRegions. tonyp@2963: // * _max_length (returned by max_length()) is the maximum number of tonyp@2963: // regions the heap can have. tonyp@2963: // tonyp@2963: // and maintain that: _length <= _allocated_length <= _max_length ysr@777: ysr@777: class HeapRegionSeq: public CHeapObj { tonyp@3168: friend class VMStructs; ysr@777: tonyp@2963: // The array that holds the HeapRegions. tonyp@2963: HeapRegion** _regions; ysr@777: tonyp@2963: // Version of _regions biased to address 0 tonyp@2963: HeapRegion** _regions_biased; ysr@777: tonyp@2963: // The number of regions committed in the heap. tonyp@2963: size_t _length; ysr@777: tonyp@2963: // The address of the first reserved word in the heap. tonyp@2963: HeapWord* _heap_bottom; ysr@777: tonyp@2963: // The address of the last reserved word in the heap - 1. tonyp@2963: HeapWord* _heap_end; tonyp@2963: tonyp@2963: // The log of the region byte size. tonyp@2963: size_t _region_shift; tonyp@2963: tonyp@2963: // A hint for which index to start searching from for humongous tonyp@2963: // allocations. tonyp@2963: size_t _next_search_index; tonyp@2963: tonyp@2963: // The number of regions for which we have allocated HeapRegions for. tonyp@2963: size_t _allocated_length; tonyp@2963: tonyp@2963: // The maximum number of regions in the heap. tonyp@2963: size_t _max_length; tonyp@2963: tonyp@2963: // Find a contiguous set of empty regions of length num, starting tonyp@2963: // from the given index. tonyp@2963: size_t find_contiguous_from(size_t from, size_t num); tonyp@2963: tonyp@2963: // Map a heap address to a biased region index. Assume that the tonyp@2963: // address is valid. tonyp@2963: inline size_t addr_to_index_biased(HeapWord* addr) const; tonyp@2963: tonyp@2963: void increment_length(size_t* length) { tonyp@2963: assert(*length < _max_length, "pre-condition"); tonyp@2963: *length += 1; tonyp@2963: } tonyp@2963: tonyp@2963: void decrement_length(size_t* length) { tonyp@2963: assert(*length > 0, "pre-condition"); tonyp@2963: *length -= 1; tonyp@2963: } ysr@777: ysr@777: public: tonyp@2963: // Empty contructor, we'll initialize it with the initialize() method. tonyp@2963: HeapRegionSeq() { } ysr@777: tonyp@2963: void initialize(HeapWord* bottom, HeapWord* end, size_t max_length); ysr@777: tonyp@2963: // Return the HeapRegion at the given index. Assume that the index tonyp@2963: // is valid. tonyp@2963: inline HeapRegion* at(size_t index) const; ysr@777: tonyp@2963: // If addr is within the committed space return its corresponding tonyp@2963: // HeapRegion, otherwise return NULL. tonyp@2963: inline HeapRegion* addr_to_region(HeapWord* addr) const; ysr@777: tonyp@2963: // Return the HeapRegion that corresponds to the given tonyp@2963: // address. Assume the address is valid. tonyp@2963: inline HeapRegion* addr_to_region_unsafe(HeapWord* addr) const; ysr@777: tonyp@2963: // Return the number of regions that have been committed in the heap. tonyp@2963: size_t length() const { return _length; } tonyp@2963: tonyp@2963: // Return the maximum number of regions in the heap. tonyp@2963: size_t max_length() const { return _max_length; } tonyp@2963: tonyp@2963: // Expand the sequence to reflect that the heap has grown from tonyp@2963: // old_end to new_end. Either create new HeapRegions, or re-use tonyp@2963: // existing ones, and return them in the given list. Returns the tonyp@2963: // memory region that covers the newly-created regions. If a tonyp@2963: // HeapRegion allocation fails, the result memory region might be tonyp@2963: // smaller than the desired one. tonyp@2963: MemRegion expand_by(HeapWord* old_end, HeapWord* new_end, tonyp@2963: FreeRegionList* list); tonyp@2963: tonyp@2963: // Return the number of contiguous regions at the end of the sequence ysr@777: // that are available for allocation. ysr@777: size_t free_suffix(); ysr@777: tonyp@2643: // Find a contiguous set of empty regions of length num and return tonyp@2963: // the index of the first region or G1_NULL_HRS_INDEX if the tonyp@2963: // search was unsuccessful. tonyp@2963: size_t find_contiguous(size_t num); ysr@777: tonyp@2963: // Apply blk->doHeapRegion() on all committed regions in address order, tonyp@2963: // terminating the iteration early if doHeapRegion() returns true. tonyp@2963: void iterate(HeapRegionClosure* blk) const; ysr@777: tonyp@2963: // As above, but start the iteration from hr and loop around. If hr tonyp@2963: // is NULL, we start from the first region in the heap. tonyp@2963: void iterate_from(HeapRegion* hr, HeapRegionClosure* blk) const; ysr@777: tonyp@2963: // Tag as uncommitted as many regions that are completely free as tonyp@2963: // possible, up to shrink_bytes, from the suffix of the committed tonyp@2963: // sequence. Return a MemRegion that corresponds to the address tonyp@2963: // range of the uncommitted regions. Assume shrink_bytes is page and tonyp@2963: // heap region aligned. tonyp@2963: MemRegion shrink_by(size_t shrink_bytes, size_t* num_regions_deleted); ysr@777: tonyp@2963: // Do some sanity checking. tonyp@2963: void verify_optional() PRODUCT_RETURN; ysr@777: }; stefank@2314: stefank@2314: #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP