hotspot/src/share/vm/gc/parallel/psVirtualspace.cpp
changeset 30764 fec48bf5a827
parent 30291 54cdc5c1a9cb
child 35061 be6025ebffea
equal deleted inserted replaced
30614:e45861098f5a 30764:fec48bf5a827
       
     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 #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::shrink_by(size_t bytes) {
       
   102   assert(is_aligned(bytes), "arg not aligned");
       
   103   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
       
   104 
       
   105   if (committed_size() < bytes) {
       
   106     return false;
       
   107   }
       
   108 
       
   109   char* const base_addr = committed_high_addr() - bytes;
       
   110   bool result = special() || os::uncommit_memory(base_addr, bytes);
       
   111   if (result) {
       
   112     _committed_high_addr -= bytes;
       
   113   }
       
   114 
       
   115   return result;
       
   116 }
       
   117 
       
   118 size_t
       
   119 PSVirtualSpace::expand_into(PSVirtualSpace* other_space, size_t bytes) {
       
   120   assert(is_aligned(bytes), "arg not aligned");
       
   121   assert(grows_up(), "this space must grow up");
       
   122   assert(other_space->grows_down(), "other space must grow down");
       
   123   assert(reserved_high_addr() == other_space->reserved_low_addr(),
       
   124          "spaces not contiguous");
       
   125   assert(special() == other_space->special(), "one space is special, the other is not");
       
   126   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
       
   127   DEBUG_ONLY(PSVirtualSpaceVerifier other_verifier(other_space));
       
   128 
       
   129   size_t bytes_needed = bytes;
       
   130 
       
   131   // First use the uncommitted region in this space.
       
   132   size_t tmp_bytes = MIN2(uncommitted_size(), bytes_needed);
       
   133   if (tmp_bytes > 0) {
       
   134     if (expand_by(tmp_bytes)) {
       
   135       bytes_needed -= tmp_bytes;
       
   136     } else {
       
   137       return 0;
       
   138     }
       
   139   }
       
   140 
       
   141   // Next take from the uncommitted region in the other space, and commit it.
       
   142   tmp_bytes = MIN2(other_space->uncommitted_size(), bytes_needed);
       
   143   if (tmp_bytes > 0) {
       
   144     char* const commit_base = committed_high_addr();
       
   145     if (other_space->special() ||
       
   146         os::commit_memory(commit_base, tmp_bytes, alignment(), !ExecMem)) {
       
   147       // Reduce the reserved region in the other space.
       
   148       other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
       
   149                                 other_space->reserved_high_addr(),
       
   150                                 other_space->special());
       
   151 
       
   152       // Grow both reserved and committed in this space.
       
   153       _reserved_high_addr += tmp_bytes;
       
   154       _committed_high_addr += tmp_bytes;
       
   155       bytes_needed -= tmp_bytes;
       
   156     } else {
       
   157       return bytes - bytes_needed;
       
   158     }
       
   159   }
       
   160 
       
   161   // Finally take from the already committed region in the other space.
       
   162   tmp_bytes = bytes_needed;
       
   163   if (tmp_bytes > 0) {
       
   164     // Reduce both committed and reserved in the other space.
       
   165     other_space->set_committed(other_space->committed_low_addr() + tmp_bytes,
       
   166                                other_space->committed_high_addr());
       
   167     other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
       
   168                               other_space->reserved_high_addr(),
       
   169                               other_space->special());
       
   170 
       
   171     // Grow both reserved and committed in this space.
       
   172     _reserved_high_addr += tmp_bytes;
       
   173     _committed_high_addr += tmp_bytes;
       
   174   }
       
   175 
       
   176   return bytes;
       
   177 }
       
   178 
       
   179 #ifndef PRODUCT
       
   180 bool PSVirtualSpace::is_aligned(size_t value, size_t align) {
       
   181   const size_t tmp_value = value + align - 1;
       
   182   const size_t mask = ~(align - 1);
       
   183   return (tmp_value & mask) == value;
       
   184 }
       
   185 
       
   186 bool PSVirtualSpace::is_aligned(size_t value) const {
       
   187   return is_aligned(value, alignment());
       
   188 }
       
   189 
       
   190 bool PSVirtualSpace::is_aligned(char* value) const {
       
   191   return is_aligned((size_t)value);
       
   192 }
       
   193 
       
   194 void PSVirtualSpace::verify() const {
       
   195   assert(is_aligned(alignment(), os::vm_page_size()), "bad alignment");
       
   196   assert(is_aligned(reserved_low_addr()), "bad reserved_low_addr");
       
   197   assert(is_aligned(reserved_high_addr()), "bad reserved_high_addr");
       
   198   assert(is_aligned(committed_low_addr()), "bad committed_low_addr");
       
   199   assert(is_aligned(committed_high_addr()), "bad committed_high_addr");
       
   200 
       
   201   // Reserved region must be non-empty or both addrs must be 0.
       
   202   assert(reserved_low_addr() < reserved_high_addr() ||
       
   203          reserved_low_addr() == NULL && reserved_high_addr() == NULL,
       
   204          "bad reserved addrs");
       
   205   assert(committed_low_addr() <= committed_high_addr(), "bad committed addrs");
       
   206 
       
   207   if (grows_up()) {
       
   208     assert(reserved_low_addr() == committed_low_addr(), "bad low addrs");
       
   209     assert(reserved_high_addr() >= committed_high_addr(), "bad high addrs");
       
   210   } else {
       
   211     assert(reserved_high_addr() == committed_high_addr(), "bad high addrs");
       
   212     assert(reserved_low_addr() <= committed_low_addr(), "bad low addrs");
       
   213   }
       
   214 }
       
   215 
       
   216 void PSVirtualSpace::print() const {
       
   217   gclog_or_tty->print_cr("virtual space [" PTR_FORMAT "]:  alignment="
       
   218                          SIZE_FORMAT "K grows %s%s",
       
   219                          p2i(this), alignment() / K, grows_up() ? "up" : "down",
       
   220                          special() ? " (pinned in memory)" : "");
       
   221   gclog_or_tty->print_cr("    reserved=" SIZE_FORMAT "K"
       
   222                          " [" PTR_FORMAT "," PTR_FORMAT "]"
       
   223                          " committed=" SIZE_FORMAT "K"
       
   224                          " [" PTR_FORMAT "," PTR_FORMAT "]",
       
   225                          reserved_size() / K,
       
   226                          p2i(reserved_low_addr()), p2i(reserved_high_addr()),
       
   227                          committed_size() / K,
       
   228                          p2i(committed_low_addr()), p2i(committed_high_addr()));
       
   229 }
       
   230 #endif // #ifndef PRODUCT
       
   231 
       
   232 void PSVirtualSpace::print_space_boundaries_on(outputStream* st) const {
       
   233   st->print_cr(" [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")",
       
   234                p2i(low_boundary()), p2i(high()), p2i(high_boundary()));
       
   235 }
       
   236 
       
   237 PSVirtualSpaceHighToLow::PSVirtualSpaceHighToLow(ReservedSpace rs,
       
   238                                                  size_t alignment) :
       
   239   PSVirtualSpace(alignment)
       
   240 {
       
   241   set_reserved(rs);
       
   242   set_committed(reserved_high_addr(), reserved_high_addr());
       
   243   DEBUG_ONLY(verify());
       
   244 }
       
   245 
       
   246 PSVirtualSpaceHighToLow::PSVirtualSpaceHighToLow(ReservedSpace rs) {
       
   247   set_reserved(rs);
       
   248   set_committed(reserved_high_addr(), reserved_high_addr());
       
   249   DEBUG_ONLY(verify());
       
   250 }
       
   251 
       
   252 bool PSVirtualSpaceHighToLow::expand_by(size_t bytes) {
       
   253   assert(is_aligned(bytes), "arg not aligned");
       
   254   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
       
   255 
       
   256   if (uncommitted_size() < bytes) {
       
   257     return false;
       
   258   }
       
   259 
       
   260   char* const base_addr = committed_low_addr() - bytes;
       
   261   bool result = special() ||
       
   262          os::commit_memory(base_addr, bytes, alignment(), !ExecMem);
       
   263   if (result) {
       
   264     _committed_low_addr -= bytes;
       
   265   }
       
   266 
       
   267   return result;
       
   268 }
       
   269 
       
   270 bool PSVirtualSpaceHighToLow::shrink_by(size_t bytes) {
       
   271   assert(is_aligned(bytes), "arg not aligned");
       
   272   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
       
   273 
       
   274   if (committed_size() < bytes) {
       
   275     return false;
       
   276   }
       
   277 
       
   278   char* const base_addr = committed_low_addr();
       
   279   bool result = special() || os::uncommit_memory(base_addr, bytes);
       
   280   if (result) {
       
   281     _committed_low_addr += bytes;
       
   282   }
       
   283 
       
   284   return result;
       
   285 }
       
   286 
       
   287 size_t PSVirtualSpaceHighToLow::expand_into(PSVirtualSpace* other_space,
       
   288                                             size_t bytes) {
       
   289   assert(is_aligned(bytes), "arg not aligned");
       
   290   assert(grows_down(), "this space must grow down");
       
   291   assert(other_space->grows_up(), "other space must grow up");
       
   292   assert(reserved_low_addr() == other_space->reserved_high_addr(),
       
   293          "spaces not contiguous");
       
   294   assert(special() == other_space->special(), "one space is special in memory, the other is not");
       
   295   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
       
   296   DEBUG_ONLY(PSVirtualSpaceVerifier other_verifier(other_space));
       
   297 
       
   298   size_t bytes_needed = bytes;
       
   299 
       
   300   // First use the uncommitted region in this space.
       
   301   size_t tmp_bytes = MIN2(uncommitted_size(), bytes_needed);
       
   302   if (tmp_bytes > 0) {
       
   303     if (expand_by(tmp_bytes)) {
       
   304       bytes_needed -= tmp_bytes;
       
   305     } else {
       
   306       return 0;
       
   307     }
       
   308   }
       
   309 
       
   310   // Next take from the uncommitted region in the other space, and commit it.
       
   311   tmp_bytes = MIN2(other_space->uncommitted_size(), bytes_needed);
       
   312   if (tmp_bytes > 0) {
       
   313     char* const commit_base = committed_low_addr() - tmp_bytes;
       
   314     if (other_space->special() ||
       
   315         os::commit_memory(commit_base, tmp_bytes, alignment(), !ExecMem)) {
       
   316       // Reduce the reserved region in the other space.
       
   317       other_space->set_reserved(other_space->reserved_low_addr(),
       
   318                                 other_space->reserved_high_addr() - tmp_bytes,
       
   319                                 other_space->special());
       
   320 
       
   321       // Grow both reserved and committed in this space.
       
   322       _reserved_low_addr -= tmp_bytes;
       
   323       _committed_low_addr -= tmp_bytes;
       
   324       bytes_needed -= tmp_bytes;
       
   325     } else {
       
   326       return bytes - bytes_needed;
       
   327     }
       
   328   }
       
   329 
       
   330   // Finally take from the already committed region in the other space.
       
   331   tmp_bytes = bytes_needed;
       
   332   if (tmp_bytes > 0) {
       
   333     // Reduce both committed and reserved in the other space.
       
   334     other_space->set_committed(other_space->committed_low_addr(),
       
   335                                other_space->committed_high_addr() - tmp_bytes);
       
   336     other_space->set_reserved(other_space->reserved_low_addr(),
       
   337                               other_space->reserved_high_addr() - tmp_bytes,
       
   338                               other_space->special());
       
   339 
       
   340     // Grow both reserved and committed in this space.
       
   341     _reserved_low_addr -= tmp_bytes;
       
   342     _committed_low_addr -= tmp_bytes;
       
   343   }
       
   344 
       
   345   return bytes;
       
   346 }
       
   347 
       
   348 void
       
   349 PSVirtualSpaceHighToLow::print_space_boundaries_on(outputStream* st) const {
       
   350   st->print_cr(" (" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT "]",
       
   351                p2i(high_boundary()), p2i(low()), p2i(low_boundary()));
       
   352 }