1 /*
  2  * Copyright (c) 2003, 2019, 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 #include "precompiled.hpp"
 26 #include "gc/parallel/psVirtualspace.hpp"
 27 #include "memory/virtualspace.hpp"
 28 #include "runtime/os.hpp"
 29 
 30 // PSVirtualSpace
 31 
 32 PSVirtualSpace::PSVirtualSpace(ReservedSpace rs, size_t alignment) :
 33   _alignment(alignment)
 34 {
 35   set_reserved(rs);
 36   set_committed(reserved_low_addr(), reserved_low_addr());
 37   DEBUG_ONLY(verify());
 38 }
 39 
 40 PSVirtualSpace::PSVirtualSpace(ReservedSpace rs) :
 41   _alignment(os::vm_page_size())
 42 {
 43   set_reserved(rs);
 44   set_committed(reserved_low_addr(), reserved_low_addr());
 45   DEBUG_ONLY(verify());
 46 }
 47 
 48 // Deprecated.
 49 PSVirtualSpace::PSVirtualSpace():
 50   _alignment(os::vm_page_size()),
 51   _reserved_low_addr(NULL),
 52   _reserved_high_addr(NULL),
 53   _committed_low_addr(NULL),
 54   _committed_high_addr(NULL),
 55   _special(false) {
 56 }
 57 
 58 // Deprecated.
 59 bool PSVirtualSpace::initialize(ReservedSpace rs,
 60                                 size_t commit_size) {
 61   set_reserved(rs);
 62   set_committed(reserved_low_addr(), reserved_low_addr());
 63 
 64   // Commit to initial size.
 65   assert(commit_size <= rs.size(), "commit_size too big");
 66   bool result = commit_size > 0 ? expand_by(commit_size) : true;
 67   DEBUG_ONLY(verify());
 68   return result;
 69 }
 70 
 71 PSVirtualSpace::~PSVirtualSpace() {
 72   release();
 73 }
 74 
 75 bool PSVirtualSpace::contains(void* p) const {
 76   char* const cp = (char*)p;
 77   return cp >= committed_low_addr() && cp < committed_high_addr();
 78 }
 79 
 80 void PSVirtualSpace::release() {
 81   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
 82   // This may not release memory it didn't reserve.
 83   // Use rs.release() to release the underlying memory instead.
 84   _reserved_low_addr = _reserved_high_addr = NULL;
 85   _committed_low_addr = _committed_high_addr = NULL;
 86   _special = false;
 87 }
 88 
 89 bool PSVirtualSpace::expand_by(size_t bytes) {
 90   assert(is_aligned(bytes), "arg not aligned");
 91   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
 92 
 93   if (uncommitted_size() < bytes) {
 94     return false;
 95   }
 96 
 97   char* const base_addr = committed_high_addr();
 98   bool result = special() ||
 99          os::commit_memory(base_addr, bytes, alignment(), !ExecMem);
100   if (result) {
101     _committed_high_addr += bytes;
102   }
103 
104   return result;
105 }
106 
107 bool PSVirtualSpace::shrink_by(size_t bytes) {
108   assert(is_aligned(bytes), "arg not aligned");
109   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
110 
111   if (committed_size() < bytes) {
112     return false;
113   }
114 
115   char* const base_addr = committed_high_addr() - bytes;
116   bool result = special() || os::uncommit_memory(base_addr, bytes);
117   if (result) {
118     _committed_high_addr -= bytes;
119   }
120 
121   return result;
122 }
123 
124 size_t
125 PSVirtualSpace::expand_into(PSVirtualSpace* other_space, size_t bytes) {
126   assert(is_aligned(bytes), "arg not aligned");
127   assert(grows_up(), "this space must grow up");
128   assert(other_space->grows_down(), "other space must grow down");
129   assert(reserved_high_addr() == other_space->reserved_low_addr(),
130          "spaces not contiguous");
131   assert(special() == other_space->special(), "one space is special, the other is not");
132   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
133   DEBUG_ONLY(PSVirtualSpaceVerifier other_verifier(other_space));
134 
135   size_t bytes_needed = bytes;
136 
137   // First use the uncommitted region in this space.
138   size_t tmp_bytes = MIN2(uncommitted_size(), bytes_needed);
139   if (tmp_bytes > 0) {
140     if (expand_by(tmp_bytes)) {
141       bytes_needed -= tmp_bytes;
142     } else {
143       return 0;
144     }
145   }
146 
147   // Next take from the uncommitted region in the other space, and commit it.
148   tmp_bytes = MIN2(other_space->uncommitted_size(), bytes_needed);
149   if (tmp_bytes > 0) {
150     char* const commit_base = committed_high_addr();
151     if (other_space->special() ||
152         os::commit_memory(commit_base, tmp_bytes, alignment(), !ExecMem)) {
153       // Reduce the reserved region in the other space.
154       other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
155                                 other_space->reserved_high_addr(),
156                                 other_space->special());
157 
158       // Grow both reserved and committed in this space.
159       _reserved_high_addr += tmp_bytes;
160       _committed_high_addr += tmp_bytes;
161       bytes_needed -= tmp_bytes;
162     } else {
163       return bytes - bytes_needed;
164     }
165   }
166 
167   // Finally take from the already committed region in the other space.
168   tmp_bytes = bytes_needed;
169   if (tmp_bytes > 0) {
170     // Reduce both committed and reserved in the other space.
171     other_space->set_committed(other_space->committed_low_addr() + tmp_bytes,
172                                other_space->committed_high_addr());
173     other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
174                               other_space->reserved_high_addr(),
175                               other_space->special());
176 
177     // Grow both reserved and committed in this space.
178     _reserved_high_addr += tmp_bytes;
179     _committed_high_addr += tmp_bytes;
180   }
181 
182   return bytes;
183 }
184 
185 #ifndef PRODUCT
186 bool PSVirtualSpace::is_aligned(size_t value, size_t align) {
187   const size_t tmp_value = value + align - 1;
188   const size_t mask = ~(align - 1);
189   return (tmp_value & mask) == value;
190 }
191 
192 bool PSVirtualSpace::is_aligned(size_t value) const {
193   return is_aligned(value, alignment());
194 }
195 
196 bool PSVirtualSpace::is_aligned(char* value) const {
197   return is_aligned((size_t)value);
198 }
199 
200 void PSVirtualSpace::verify() const {
201   assert(is_aligned(alignment(), os::vm_page_size()), "bad alignment");
202   assert(is_aligned(reserved_low_addr()), "bad reserved_low_addr");
203   assert(is_aligned(reserved_high_addr()), "bad reserved_high_addr");
204   assert(is_aligned(committed_low_addr()), "bad committed_low_addr");
205   assert(is_aligned(committed_high_addr()), "bad committed_high_addr");
206 
207   // Reserved region must be non-empty or both addrs must be 0.
208   assert(reserved_low_addr() < reserved_high_addr() ||
209          reserved_low_addr() == NULL && reserved_high_addr() == NULL,
210          "bad reserved addrs");
211   assert(committed_low_addr() <= committed_high_addr(), "bad committed addrs");
212 
213   if (grows_up()) {
214     assert(reserved_low_addr() == committed_low_addr(), "bad low addrs");
215     assert(reserved_high_addr() >= committed_high_addr(), "bad high addrs");
216   } else {
217     assert(reserved_high_addr() == committed_high_addr(), "bad high addrs");
218     assert(reserved_low_addr() <= committed_low_addr(), "bad low addrs");
219   }
220 }
221 
222 #endif // #ifndef PRODUCT
223 
224 void PSVirtualSpace::print_space_boundaries_on(outputStream* st) const {
225   st->print_cr(" [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")",
226                p2i(low_boundary()), p2i(high()), p2i(high_boundary()));
227 }
228 
229 PSVirtualSpaceHighToLow::PSVirtualSpaceHighToLow(ReservedSpace rs,
230                                                  size_t alignment) :
231   PSVirtualSpace(alignment)
232 {
233   set_reserved(rs);
234   set_committed(reserved_high_addr(), reserved_high_addr());
235   DEBUG_ONLY(verify());
236 }
237 
238 PSVirtualSpaceHighToLow::PSVirtualSpaceHighToLow(ReservedSpace rs) {
239   set_reserved(rs);
240   set_committed(reserved_high_addr(), reserved_high_addr());
241   DEBUG_ONLY(verify());
242 }
243 
244 bool PSVirtualSpaceHighToLow::expand_by(size_t bytes) {
245   assert(is_aligned(bytes), "arg not aligned");
246   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
247 
248   if (uncommitted_size() < bytes) {
249     return false;
250   }
251 
252   char* const base_addr = committed_low_addr() - bytes;
253   bool result = special() ||
254          os::commit_memory(base_addr, bytes, alignment(), !ExecMem);
255   if (result) {
256     _committed_low_addr -= bytes;
257   }
258 
259   return result;
260 }
261 
262 bool PSVirtualSpaceHighToLow::shrink_by(size_t bytes) {
263   assert(is_aligned(bytes), "arg not aligned");
264   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
265 
266   if (committed_size() < bytes) {
267     return false;
268   }
269 
270   char* const base_addr = committed_low_addr();
271   bool result = special() || os::uncommit_memory(base_addr, bytes);
272   if (result) {
273     _committed_low_addr += bytes;
274   }
275 
276   return result;
277 }
278 
279 size_t PSVirtualSpaceHighToLow::expand_into(PSVirtualSpace* other_space,
280                                             size_t bytes) {
281   assert(is_aligned(bytes), "arg not aligned");
282   assert(grows_down(), "this space must grow down");
283   assert(other_space->grows_up(), "other space must grow up");
284   assert(reserved_low_addr() == other_space->reserved_high_addr(),
285          "spaces not contiguous");
286   assert(special() == other_space->special(), "one space is special in memory, the other is not");
287   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
288   DEBUG_ONLY(PSVirtualSpaceVerifier other_verifier(other_space));
289 
290   size_t bytes_needed = bytes;
291 
292   // First use the uncommitted region in this space.
293   size_t tmp_bytes = MIN2(uncommitted_size(), bytes_needed);
294   if (tmp_bytes > 0) {
295     if (expand_by(tmp_bytes)) {
296       bytes_needed -= tmp_bytes;
297     } else {
298       return 0;
299     }
300   }
301 
302   // Next take from the uncommitted region in the other space, and commit it.
303   tmp_bytes = MIN2(other_space->uncommitted_size(), bytes_needed);
304   if (tmp_bytes > 0) {
305     char* const commit_base = committed_low_addr() - tmp_bytes;
306     if (other_space->special() ||
307         os::commit_memory(commit_base, tmp_bytes, alignment(), !ExecMem)) {
308       // Reduce the reserved region in the other space.
309       other_space->set_reserved(other_space->reserved_low_addr(),
310                                 other_space->reserved_high_addr() - tmp_bytes,
311                                 other_space->special());
312 
313       // Grow both reserved and committed in this space.
314       _reserved_low_addr -= tmp_bytes;
315       _committed_low_addr -= tmp_bytes;
316       bytes_needed -= tmp_bytes;
317     } else {
318       return bytes - bytes_needed;
319     }
320   }
321 
322   // Finally take from the already committed region in the other space.
323   tmp_bytes = bytes_needed;
324   if (tmp_bytes > 0) {
325     // Reduce both committed and reserved in the other space.
326     other_space->set_committed(other_space->committed_low_addr(),
327                                other_space->committed_high_addr() - tmp_bytes);
328     other_space->set_reserved(other_space->reserved_low_addr(),
329                               other_space->reserved_high_addr() - tmp_bytes,
330                               other_space->special());
331 
332     // Grow both reserved and committed in this space.
333     _reserved_low_addr -= tmp_bytes;
334     _committed_low_addr -= tmp_bytes;
335   }
336 
337   return bytes;
338 }
339 
340 void
341 PSVirtualSpaceHighToLow::print_space_boundaries_on(outputStream* st) const {
342   st->print_cr(" (" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT "]",
343                p2i(high_boundary()), p2i(low()), p2i(low_boundary()));
344 }