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