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   virtual bool grows_up() const   { return true; }
 100           bool grows_down() const { return !grows_up(); }
 101 
 102   // Helper class to verify a space when entering/leaving a block.
 103   class PSVirtualSpaceVerifier: public StackObj {
 104    private:
 105     const PSVirtualSpace* const _space;
 106    public:
 107     PSVirtualSpaceVerifier(PSVirtualSpace* space): _space(space) {
 108       _space->verify();
 109     }
 110     ~PSVirtualSpaceVerifier() { _space->verify(); }
 111   };
 112 #endif
 113 
 114   virtual void print_space_boundaries_on(outputStream* st) const;
 115 
 116  // Included for compatibility with the original VirtualSpace.
 117  public:
 118   // Committed area
 119   char* low()  const { return committed_low_addr(); }
 120   char* high() const { return committed_high_addr(); }
 121 
 122   // Reserved area
 123   char* low_boundary()  const { return reserved_low_addr(); }
 124   char* high_boundary() const { return reserved_high_addr(); }
 125 };
 126 
 127 // A virtual space that grows from high addresses to low addresses.
 128 class PSVirtualSpaceHighToLow : public PSVirtualSpace {
 129   friend class VMStructs;
 130  public:
 131   PSVirtualSpaceHighToLow(ReservedSpace rs, size_t alignment);
 132   PSVirtualSpaceHighToLow(ReservedSpace rs);
 133 
 134   virtual bool   expand_by(size_t bytes);
 135   virtual bool   shrink_by(size_t bytes);
 136   virtual size_t expand_into(PSVirtualSpace* space, size_t bytes);
 137 
 138   virtual void print_space_boundaries_on(outputStream* st) const;
 139 
 140 #ifndef PRODUCT
 141   // Debugging
 142   virtual bool grows_up() const   { return false; }
 143 #endif
 144 };
 145 
 146 //
 147 // PSVirtualSpace inlines.
 148 //
 149 inline size_t
 150 PSVirtualSpace::pointer_delta(const char* left, const char* right) {
 151   return ::pointer_delta((void *)left, (void*)right, sizeof(char));
 152 }
 153 
 154 inline size_t PSVirtualSpace::committed_size() const {
 155   return pointer_delta(committed_high_addr(), committed_low_addr());
 156 }
 157 
 158 inline size_t PSVirtualSpace::reserved_size() const {
 159   return pointer_delta(reserved_high_addr(), reserved_low_addr());
 160 }
 161 
 162 inline size_t PSVirtualSpace::uncommitted_size() const {
 163   return reserved_size() - committed_size();
 164 }
 165 
 166 inline void PSVirtualSpace::set_reserved(char* low_addr, char* high_addr, bool special) {
 167   _reserved_low_addr = low_addr;
 168   _reserved_high_addr = high_addr;
 169   _special = special;
 170 }
 171 
 172 inline void PSVirtualSpace::set_reserved(ReservedSpace rs) {
 173   set_reserved(rs.base(), rs.base() + rs.size(), rs.special());
 174 }
 175 
 176 inline void PSVirtualSpace::set_committed(char* low_addr, char* high_addr) {
 177   _committed_low_addr = low_addr;
 178   _committed_high_addr = high_addr;
 179 }
 180 
 181 #endif // SHARE_VM_GC_PARALLEL_PSVIRTUALSPACE_HPP