/* * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. * */ #ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSVIRTUALSPACE_HPP #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSVIRTUALSPACE_HPP #include "runtime/virtualspace.hpp" // VirtualSpace for the parallel scavenge collector. // // VirtualSpace is data structure for committing a previously reserved address // range in smaller chunks. class PSVirtualSpace : public CHeapObj { friend class VMStructs; protected: // The space is committed/uncommited in chunks of size _alignment. The // ReservedSpace passed to initialize() must be aligned to this value. const size_t _alignment; // Reserved area char* _reserved_low_addr; char* _reserved_high_addr; // Committed area char* _committed_low_addr; char* _committed_high_addr; // The entire space has been committed and pinned in memory, no // os::commit_memory() or os::uncommit_memory(). bool _special; // Convenience wrapper. inline static size_t pointer_delta(const char* left, const char* right); public: PSVirtualSpace(ReservedSpace rs, size_t alignment); PSVirtualSpace(ReservedSpace rs); ~PSVirtualSpace(); // Eventually all instances should be created with the above 1- or 2-arg // constructors. Then the 1st constructor below should become protected and // the 2nd ctor and initialize() removed. PSVirtualSpace(size_t alignment): _alignment(alignment) { } PSVirtualSpace(); bool initialize(ReservedSpace rs, size_t commit_size); bool contains(void* p) const; // Accessors (all sizes are bytes). size_t alignment() const { return _alignment; } char* reserved_low_addr() const { return _reserved_low_addr; } char* reserved_high_addr() const { return _reserved_high_addr; } char* committed_low_addr() const { return _committed_low_addr; } char* committed_high_addr() const { return _committed_high_addr; } bool special() const { return _special; } inline size_t committed_size() const; inline size_t reserved_size() const; inline size_t uncommitted_size() const; // Operations. inline void set_reserved(char* low_addr, char* high_addr, bool special); inline void set_reserved(ReservedSpace rs); inline void set_committed(char* low_addr, char* high_addr); virtual bool expand_by(size_t bytes); virtual bool shrink_by(size_t bytes); virtual size_t expand_into(PSVirtualSpace* space, size_t bytes); void release(); #ifndef PRODUCT // Debugging static bool is_aligned(size_t val, size_t align); bool is_aligned(size_t val) const; bool is_aligned(char* val) const; void verify() const; void print() const; virtual bool grows_up() const { return true; } bool grows_down() const { return !grows_up(); } // Helper class to verify a space when entering/leaving a block. class PSVirtualSpaceVerifier: public StackObj { private: const PSVirtualSpace* const _space; public: PSVirtualSpaceVerifier(PSVirtualSpace* space): _space(space) { _space->verify(); } ~PSVirtualSpaceVerifier() { _space->verify(); } }; #endif virtual void print_space_boundaries_on(outputStream* st) const; // Included for compatibility with the original VirtualSpace. public: // Committed area char* low() const { return committed_low_addr(); } char* high() const { return committed_high_addr(); } // Reserved area char* low_boundary() const { return reserved_low_addr(); } char* high_boundary() const { return reserved_high_addr(); } }; // A virtual space that grows from high addresses to low addresses. class PSVirtualSpaceHighToLow : public PSVirtualSpace { friend class VMStructs; public: PSVirtualSpaceHighToLow(ReservedSpace rs, size_t alignment); PSVirtualSpaceHighToLow(ReservedSpace rs); virtual bool expand_by(size_t bytes); virtual bool shrink_by(size_t bytes); virtual size_t expand_into(PSVirtualSpace* space, size_t bytes); virtual void print_space_boundaries_on(outputStream* st) const; #ifndef PRODUCT // Debugging virtual bool grows_up() const { return false; } #endif }; // // PSVirtualSpace inlines. // inline size_t PSVirtualSpace::pointer_delta(const char* left, const char* right) { return ::pointer_delta((void *)left, (void*)right, sizeof(char)); } inline size_t PSVirtualSpace::committed_size() const { return pointer_delta(committed_high_addr(), committed_low_addr()); } inline size_t PSVirtualSpace::reserved_size() const { return pointer_delta(reserved_high_addr(), reserved_low_addr()); } inline size_t PSVirtualSpace::uncommitted_size() const { return reserved_size() - committed_size(); } inline void PSVirtualSpace::set_reserved(char* low_addr, char* high_addr, bool special) { _reserved_low_addr = low_addr; _reserved_high_addr = high_addr; _special = special; } inline void PSVirtualSpace::set_reserved(ReservedSpace rs) { set_reserved(rs.base(), rs.base() + rs.size(), rs.special()); } inline void PSVirtualSpace::set_committed(char* low_addr, char* high_addr) { _committed_low_addr = low_addr; _committed_high_addr = high_addr; } #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSVIRTUALSPACE_HPP