1 /*
  2  * Copyright (c) 1997, 2020, 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_MEMORY_VIRTUALSPACE_HPP
 26 #define SHARE_MEMORY_VIRTUALSPACE_HPP
 27 
 28 #include "memory/memRegion.hpp"
 29 #include "utilities/globalDefinitions.hpp"
 30 
 31 class outputStream;
 32 
 33 // ReservedSpace is a data structure for reserving a contiguous address range.
 34 
 35 class ReservedSpace {
 36   friend class VMStructs;
 37  protected:
 38   char*  _base;
 39   size_t _size;
 40   size_t _noaccess_prefix;
 41   size_t _alignment;
 42   bool   _special;
 43   int    _fd;
 44  private:
 45   bool   _executable;
 46 
 47   // ReservedSpace
 48   ReservedSpace(char* base, size_t size, size_t alignment, bool special,
 49                 bool executable);
 50  protected:
 51   void initialize(size_t size, size_t alignment, bool large,
 52                   char* requested_address,
 53                   bool executable);
 54 
 55  public:
 56   // Constructor
 57   ReservedSpace();
 58   // Initialize the reserved space with the given size. If preferred_page_size
 59   // is set, use this as minimum page size/alignment. This may waste some space
 60   // if the given size is not aligned to that value, as the reservation will be
 61   // aligned up to the final alignment in this case.
 62   ReservedSpace(size_t size, size_t preferred_page_size = 0);
 63   ReservedSpace(size_t size, size_t alignment, bool large,
 64                 char* requested_address = NULL);
 65 
 66   // Accessors
 67   char*  base()            const { return _base;      }
 68   size_t size()            const { return _size;      }
 69   char*  end()             const { return _base + _size; }
 70   size_t alignment()       const { return _alignment; }
 71   bool   special()         const { return _special;   }
 72   bool   executable()      const { return _executable;   }
 73   size_t noaccess_prefix() const { return _noaccess_prefix;   }
 74   bool is_reserved()       const { return _base != NULL; }
 75   void release();
 76 
 77   // Splitting
 78   // This splits the space into two spaces, the first part of which will be returned.
 79   // If split==true, the resulting two spaces can be released independently from each other.
 80   //  This may cause the original space to loose its content.
 81   //  They also will be tracked individually by NMT and can be tagged with different flags.
 82   //  Note that this may cause the original space to loose its content.
 83   // If split==false, the resulting space will be just a hotspot-internal representation
 84   //  of a sub section of the underlying mapping.
 85   ReservedSpace first_part(size_t partition_size, size_t alignment, bool split = false);
 86   ReservedSpace last_part (size_t partition_size, size_t alignment);
 87 
 88   // These simply call the above using the default alignment.
 89   inline ReservedSpace first_part(size_t partition_size, bool split = false);
 90   inline ReservedSpace last_part (size_t partition_size);
 91 
 92   // Alignment
 93   static size_t page_align_size_up(size_t size);
 94   static size_t page_align_size_down(size_t size);
 95   static size_t allocation_align_size_up(size_t size);
 96   bool contains(const void* p) const {
 97     return (base() <= ((char*)p)) && (((char*)p) < (base() + size()));
 98   }
 99 };
100 
101 ReservedSpace
102 ReservedSpace::first_part(size_t partition_size, bool split)
103 {
104   return first_part(partition_size, alignment(), split);
105 }
106 
107 ReservedSpace ReservedSpace::last_part(size_t partition_size)
108 {
109   return last_part(partition_size, alignment());
110 }
111 
112 // Class encapsulating behavior specific of memory space reserved for Java heap.
113 class ReservedHeapSpace : public ReservedSpace {
114  private:
115   void try_reserve_heap(size_t size, size_t alignment, bool large,
116                         char *requested_address);
117   void try_reserve_range(char *highest_start, char *lowest_start,
118                          size_t attach_point_alignment, char *aligned_HBMA,
119                          char *upper_bound, size_t size, size_t alignment, bool large);
120   void initialize_compressed_heap(const size_t size, size_t alignment, bool large);
121   // Create protection page at the beginning of the space.
122   void establish_noaccess_prefix();
123  public:
124   // Constructor. Tries to find a heap that is good for compressed oops.
125   // heap_allocation_directory is the path to the backing memory for Java heap. When set, Java heap will be allocated
126   // on the device which is managed by the file system where the directory resides.
127   ReservedHeapSpace(size_t size, size_t forced_base_alignment, bool large, const char* heap_allocation_directory = NULL);
128   // Returns the base to be used for compression, i.e. so that null can be
129   // encoded safely and implicit null checks can work.
130   char *compressed_oop_base() const { return _base - _noaccess_prefix; }
131   MemRegion region() const;
132 };
133 
134 // Class encapsulating behavior specific memory space for Code
135 class ReservedCodeSpace : public ReservedSpace {
136  public:
137   // Constructor
138   ReservedCodeSpace(size_t r_size, size_t rs_align, bool large);
139 };
140 
141 // VirtualSpace is data structure for committing a previously reserved address range in smaller chunks.
142 
143 class VirtualSpace {
144   friend class VMStructs;
145  private:
146   // Reserved area
147   char* _low_boundary;
148   char* _high_boundary;
149 
150   // Committed area
151   char* _low;
152   char* _high;
153 
154   // The entire space has been committed and pinned in memory, no
155   // os::commit_memory() or os::uncommit_memory().
156   bool _special;
157 
158   // Need to know if commit should be executable.
159   bool   _executable;
160 
161   // MPSS Support
162   // Each virtualspace region has a lower, middle, and upper region.
163   // Each region has an end boundary and a high pointer which is the
164   // high water mark for the last allocated byte.
165   // The lower and upper unaligned to LargePageSizeInBytes uses default page.
166   // size.  The middle region uses large page size.
167   char* _lower_high;
168   char* _middle_high;
169   char* _upper_high;
170 
171   char* _lower_high_boundary;
172   char* _middle_high_boundary;
173   char* _upper_high_boundary;
174 
175   size_t _lower_alignment;
176   size_t _middle_alignment;
177   size_t _upper_alignment;
178 
179   // MPSS Accessors
180   char* lower_high() const { return _lower_high; }
181   char* middle_high() const { return _middle_high; }
182   char* upper_high() const { return _upper_high; }
183 
184   char* lower_high_boundary() const { return _lower_high_boundary; }
185   char* middle_high_boundary() const { return _middle_high_boundary; }
186   char* upper_high_boundary() const { return _upper_high_boundary; }
187 
188   size_t lower_alignment() const { return _lower_alignment; }
189   size_t middle_alignment() const { return _middle_alignment; }
190   size_t upper_alignment() const { return _upper_alignment; }
191 
192  public:
193   // Committed area
194   char* low()  const { return _low; }
195   char* high() const { return _high; }
196 
197   // Reserved area
198   char* low_boundary()  const { return _low_boundary; }
199   char* high_boundary() const { return _high_boundary; }
200 
201 #if INCLUDE_AOT
202   // Set boundaries for code section in AOT library.
203   void set_low_boundary(char *p)  { _low_boundary = p; }
204   void set_high_boundary(char *p) { _high_boundary = p; }
205   void set_low(char *p)           { _low = p; }
206   void set_high(char *p)          { _high = p; }
207 #endif
208 
209   bool special() const { return _special; }
210 
211  public:
212   // Initialization
213   VirtualSpace();
214   bool initialize_with_granularity(ReservedSpace rs, size_t committed_byte_size, size_t max_commit_ganularity);
215   bool initialize(ReservedSpace rs, size_t committed_byte_size);
216 
217   // Destruction
218   ~VirtualSpace();
219 
220   // Reserved memory
221   size_t reserved_size() const;
222   // Actually committed OS memory
223   size_t actual_committed_size() const;
224   // Memory used/expanded in this virtual space
225   size_t committed_size() const;
226   // Memory left to use/expand in this virtual space
227   size_t uncommitted_size() const;
228 
229   bool   contains(const void* p) const;
230 
231   // Operations
232   // returns true on success, false otherwise
233   bool expand_by(size_t bytes, bool pre_touch = false);
234   void shrink_by(size_t bytes);
235   void release();
236 
237   void check_for_contiguity() PRODUCT_RETURN;
238 
239   // Debugging
240   void print_on(outputStream* out) PRODUCT_RETURN;
241   void print();
242 };
243 
244 #endif // SHARE_MEMORY_VIRTUALSPACE_HPP