src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp

Sat, 07 Nov 2020 10:30:02 +0800

author
aoqi
date
Sat, 07 Nov 2020 10:30:02 +0800
changeset 10026
8c95980d0b66
parent 6876
710a3c8b516e
permissions
-rw-r--r--

Added tag mips-jdk8u275-b01 for changeset d3b4d62f391f

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

mercurial