1 /*
   2  * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_GC_PARALLEL_PSVIRTUALSPACE_HPP
  26 #define SHARE_VM_GC_PARALLEL_PSVIRTUALSPACE_HPP
  27 
  28 #include "memory/virtualspace.hpp"
  29 
  30 // VirtualSpace for the parallel scavenge collector.
  31 //
  32 // VirtualSpace is data structure for committing a previously reserved address
  33 // range in smaller chunks.
  34 
  35 class PSVirtualSpace : public CHeapObj<mtGC> {
  36   friend class VMStructs;
  37  protected:
  38   // The space is committed/uncommitted in chunks of size _alignment.  The
  39   // ReservedSpace passed to initialize() must be aligned to this value.
  40   const size_t _alignment;
  41 
  42   // Reserved area
  43   char* _reserved_low_addr;
  44   char* _reserved_high_addr;
  45 
  46   // Committed area
  47   char* _committed_low_addr;
  48   char* _committed_high_addr;
  49 
  50   // The entire space has been committed and pinned in memory, no
  51   // os::commit_memory() or os::uncommit_memory().
  52   bool _special;
  53 
  54   // Convenience wrapper.
  55   inline static size_t pointer_delta(const char* left, const char* right);
  56 
  57  public:
  58   PSVirtualSpace(ReservedSpace rs, size_t alignment);
  59   PSVirtualSpace(ReservedSpace rs);
  60 
  61   ~PSVirtualSpace();
  62 
  63   // Eventually all instances should be created with the above 1- or 2-arg
  64   // constructors.  Then the 1st constructor below should become protected and
  65   // the 2nd ctor and initialize() removed.
  66   PSVirtualSpace(size_t alignment): _alignment(alignment) { }
  67   PSVirtualSpace();
  68   bool initialize(ReservedSpace rs, size_t commit_size);
  69 
  70   bool contains(void* p)      const;
  71 
  72   // Accessors (all sizes are bytes).
  73   size_t alignment()          const { return _alignment; }
  74   char* reserved_low_addr()   const { return _reserved_low_addr; }
  75   char* reserved_high_addr()  const { return _reserved_high_addr; }
  76   char* committed_low_addr()  const { return _committed_low_addr; }
  77   char* committed_high_addr() const { return _committed_high_addr; }
  78   bool  special()             const { return _special; }
  79 
  80   inline size_t committed_size()   const;
  81   inline size_t reserved_size()    const;
  82   inline size_t uncommitted_size() const;
  83 
  84   // Operations.
  85   inline  void   set_reserved(char* low_addr, char* high_addr, bool special);
  86   inline  void   set_reserved(ReservedSpace rs);
  87   inline  void   set_committed(char* low_addr, char* high_addr);
  88   virtual bool   expand_by(size_t bytes);
  89   virtual bool   shrink_by(size_t bytes);
  90   virtual size_t expand_into(PSVirtualSpace* space, size_t bytes);
  91   void           release();
  92 
  93 #ifndef PRODUCT
  94   // Debugging
  95   static  bool is_aligned(size_t val, size_t align);
  96           bool is_aligned(size_t val) const;
  97           bool is_aligned(char* val) const;
  98           void verify() const;
  99           void print() const;
 100   virtual bool grows_up() const   { return true; }
 101           bool grows_down() const { return !grows_up(); }
 102 
 103   // Helper class to verify a space when entering/leaving a block.
 104   class PSVirtualSpaceVerifier: public StackObj {
 105    private:
 106     const PSVirtualSpace* const _space;
 107    public:
 108     PSVirtualSpaceVerifier(PSVirtualSpace* space): _space(space) {
 109       _space->verify();
 110     }
 111     ~PSVirtualSpaceVerifier() { _space->verify(); }
 112   };
 113 #endif
 114 
 115   virtual void print_space_boundaries_on(outputStream* st) const;
 116 
 117  // Included for compatibility with the original VirtualSpace.
 118  public:
 119   // Committed area
 120   char* low()  const { return committed_low_addr(); }
 121   char* high() const { return committed_high_addr(); }
 122 
 123   // Reserved area
 124   char* low_boundary()  const { return reserved_low_addr(); }
 125   char* high_boundary() const { return reserved_high_addr(); }
 126 };
 127 
 128 // A virtual space that grows from high addresses to low addresses.
 129 class PSVirtualSpaceHighToLow : public PSVirtualSpace {
 130   friend class VMStructs;
 131  public:
 132   PSVirtualSpaceHighToLow(ReservedSpace rs, size_t alignment);
 133   PSVirtualSpaceHighToLow(ReservedSpace rs);
 134 
 135   virtual bool   expand_by(size_t bytes);
 136   virtual bool   shrink_by(size_t bytes);
 137   virtual size_t expand_into(PSVirtualSpace* space, size_t bytes);
 138 
 139   virtual void print_space_boundaries_on(outputStream* st) const;
 140 
 141 #ifndef PRODUCT
 142   // Debugging
 143   virtual bool grows_up() const   { return false; }
 144 #endif
 145 };
 146 
 147 //
 148 // PSVirtualSpace inlines.
 149 //
 150 inline size_t
 151 PSVirtualSpace::pointer_delta(const char* left, const char* right) {
 152   return ::pointer_delta((void *)left, (void*)right, sizeof(char));
 153 }
 154 
 155 inline size_t PSVirtualSpace::committed_size() const {
 156   return pointer_delta(committed_high_addr(), committed_low_addr());
 157 }
 158 
 159 inline size_t PSVirtualSpace::reserved_size() const {
 160   return pointer_delta(reserved_high_addr(), reserved_low_addr());
 161 }
 162 
 163 inline size_t PSVirtualSpace::uncommitted_size() const {
 164   return reserved_size() - committed_size();
 165 }
 166 
 167 inline void PSVirtualSpace::set_reserved(char* low_addr, char* high_addr, bool special) {
 168   _reserved_low_addr = low_addr;
 169   _reserved_high_addr = high_addr;
 170   _special = special;
 171 }
 172 
 173 inline void PSVirtualSpace::set_reserved(ReservedSpace rs) {
 174   set_reserved(rs.base(), rs.base() + rs.size(), rs.special());
 175 }
 176 
 177 inline void PSVirtualSpace::set_committed(char* low_addr, char* high_addr) {
 178   _committed_low_addr = low_addr;
 179   _committed_high_addr = high_addr;
 180 }
 181 
 182 #endif // SHARE_VM_GC_PARALLEL_PSVIRTUALSPACE_HPP