tschatzl@7051: /* tschatzl@7051: * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. tschatzl@7051: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. tschatzl@7051: * tschatzl@7051: * This code is free software; you can redistribute it and/or modify it tschatzl@7051: * under the terms of the GNU General Public License version 2 only, as tschatzl@7051: * published by the Free Software Foundation. tschatzl@7051: * tschatzl@7051: * This code is distributed in the hope that it will be useful, but WITHOUT tschatzl@7051: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or tschatzl@7051: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License tschatzl@7051: * version 2 for more details (a copy is included in the LICENSE file that tschatzl@7051: * accompanied this code). tschatzl@7051: * tschatzl@7051: * You should have received a copy of the GNU General Public License version tschatzl@7051: * 2 along with this work; if not, write to the Free Software Foundation, tschatzl@7051: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. tschatzl@7051: * tschatzl@7051: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA tschatzl@7051: * or visit www.oracle.com if you need additional information or have any tschatzl@7051: * questions. tschatzl@7051: * tschatzl@7051: */ tschatzl@7051: tschatzl@7051: #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1PAGEBASEDVIRTUALSPACE_HPP tschatzl@7051: #define SHARE_VM_GC_IMPLEMENTATION_G1_G1PAGEBASEDVIRTUALSPACE_HPP tschatzl@7051: tschatzl@7051: #include "memory/allocation.hpp" tschatzl@7051: #include "memory/memRegion.hpp" tschatzl@7051: #include "runtime/virtualspace.hpp" tschatzl@7051: #include "utilities/bitMap.hpp" tschatzl@7051: tschatzl@7051: // Virtual space management helper for a virtual space with an OS page allocation tschatzl@7051: // granularity. tschatzl@7051: // (De-)Allocation requests are always OS page aligned by passing a page index tschatzl@7051: // and multiples of pages. tschatzl@7781: // For systems that only commits of memory in a given size (always greater than tschatzl@7781: // page size) the base address is required to be aligned to that page size. tschatzl@7781: // The actual size requested need not be aligned to that page size, but the size tschatzl@7781: // of the reservation passed may be rounded up to this page size. Any fragment tschatzl@7781: // (less than the page size) of the actual size at the tail of the request will tschatzl@7781: // be committed using OS small pages. tschatzl@7051: // The implementation gives an error when trying to commit or uncommit pages that tschatzl@7051: // have already been committed or uncommitted. tschatzl@7051: class G1PageBasedVirtualSpace VALUE_OBJ_CLASS_SPEC { tschatzl@7051: friend class VMStructs; tschatzl@7051: private: tschatzl@7051: // Reserved area addresses. tschatzl@7051: char* _low_boundary; tschatzl@7051: char* _high_boundary; tschatzl@7051: tschatzl@7781: // The size of the tail in bytes of the handled space that needs to be committed tschatzl@7781: // using small pages. tschatzl@7781: size_t _tail_size; tschatzl@7781: tschatzl@7781: // The preferred page size used for commit/uncommit in bytes. tschatzl@7051: size_t _page_size; tschatzl@7051: tschatzl@7051: // Bitmap used for verification of commit/uncommit operations. tschatzl@7051: BitMap _committed; tschatzl@7051: sjohanss@7509: // Bitmap used to keep track of which pages are dirty or not for _special sjohanss@7509: // spaces. This is needed because for those spaces the underlying memory sjohanss@7509: // will only be zero filled the first time it is committed. Calls to commit sjohanss@7509: // will use this bitmap and return whether or not the memory is zero filled. sjohanss@7509: BitMap _dirty; sjohanss@7509: tschatzl@7051: // Indicates that the entire space has been committed and pinned in memory, tschatzl@7051: // os::commit_memory() or os::uncommit_memory() have no function. tschatzl@7051: bool _special; tschatzl@7051: tschatzl@7051: // Indicates whether the committed space should be executable. tschatzl@7051: bool _executable; tschatzl@7051: tschatzl@7781: // Helper function for committing memory. Commit the given memory range by using tschatzl@7781: // _page_size pages as much as possible and the remainder with small sized pages. tschatzl@7781: void commit_internal(size_t start_page, size_t end_page); tschatzl@7781: // Commit num_pages pages of _page_size size starting from start. All argument tschatzl@7781: // checking has been performed. tschatzl@7781: void commit_preferred_pages(size_t start_page, size_t end_page); tschatzl@7781: // Commit space at the high end of the space that needs to be committed with small tschatzl@7781: // sized pages. tschatzl@7781: void commit_tail(); tschatzl@7781: tschatzl@7781: // Uncommit the given memory range. tschatzl@7781: void uncommit_internal(size_t start_page, size_t end_page); tschatzl@7781: tschatzl@7781: // Pretouch the given memory range. tschatzl@7781: void pretouch_internal(size_t start_page, size_t end_page); tschatzl@7781: tschatzl@7051: // Returns the index of the page which contains the given address. tschatzl@7051: uintptr_t addr_to_page_index(char* addr) const; tschatzl@7051: // Returns the address of the given page index. tschatzl@7781: char* page_start(size_t index) const; tschatzl@7781: tschatzl@7781: // Is the given page index the last page? tschatzl@7781: bool is_last_page(size_t index) const { return index == (_committed.size() - 1); } tschatzl@7781: // Is the given page index the first after last page? tschatzl@7781: bool is_after_last_page(size_t index) const; tschatzl@7781: // Is the last page only partially covered by this space? tschatzl@7781: bool is_last_page_partial() const { return !is_ptr_aligned(_high_boundary, _page_size); } tschatzl@7781: // Returns the end address of the given page bounded by the reserved space. tschatzl@7781: char* bounded_end_addr(size_t end_page) const; tschatzl@7051: tschatzl@7051: // Returns true if the entire area is backed by committed memory. tschatzl@7781: bool is_area_committed(size_t start_page, size_t size_in_pages) const; tschatzl@7051: // Returns true if the entire area is not backed by committed memory. tschatzl@7781: bool is_area_uncommitted(size_t start_page, size_t size_in_pages) const; tschatzl@7051: tschatzl@7781: void initialize_with_page_size(ReservedSpace rs, size_t used_size, size_t page_size); tschatzl@7051: public: tschatzl@7051: tschatzl@7051: // Commit the given area of pages starting at start being size_in_pages large. sjohanss@7509: // Returns true if the given area is zero filled upon completion. tschatzl@7781: bool commit(size_t start_page, size_t size_in_pages); tschatzl@7051: tschatzl@7051: // Uncommit the given area of pages starting at start being size_in_pages large. tschatzl@7781: void uncommit(size_t start_page, size_t size_in_pages); tschatzl@7051: tschatzl@7781: // Initialize the given reserved space with the given base address and the size tschatzl@7781: // actually used. tschatzl@7781: // Prefer to commit in page_size chunks. tschatzl@7781: G1PageBasedVirtualSpace(ReservedSpace rs, size_t used_size, size_t page_size); tschatzl@7051: tschatzl@7051: // Destruction tschatzl@7051: ~G1PageBasedVirtualSpace(); tschatzl@7051: tschatzl@7051: // Amount of reserved memory. tschatzl@7051: size_t reserved_size() const; tschatzl@7051: // Memory used in this virtual space. tschatzl@7051: size_t committed_size() const; tschatzl@7051: // Memory left to use/expand in this virtual space. tschatzl@7051: size_t uncommitted_size() const; tschatzl@7051: tschatzl@7051: bool contains(const void* p) const; tschatzl@7051: tschatzl@7051: MemRegion reserved() { tschatzl@7051: MemRegion x((HeapWord*)_low_boundary, reserved_size() / HeapWordSize); tschatzl@7051: return x; tschatzl@7051: } tschatzl@7051: tschatzl@7051: void release(); tschatzl@7051: tschatzl@7051: void check_for_contiguity() PRODUCT_RETURN; tschatzl@7051: tschatzl@7051: // Debugging tschatzl@7051: void print_on(outputStream* out) PRODUCT_RETURN; tschatzl@7051: void print(); tschatzl@7051: }; tschatzl@7051: tschatzl@7051: #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1PAGEBASEDVIRTUALSPACE_HPP