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

Mon, 09 Mar 2009 13:28:46 -0700

author
xdono
date
Mon, 09 Mar 2009 13:28:46 -0700
changeset 1014
0fbdb4381b99
parent 970
4e400c36026f
child 1907
c18cbe5936b8
permissions
-rw-r--r--

6814575: Update copyright year
Summary: Update copyright for files that have been modified in 2009, up to 03/09
Reviewed-by: katleman, tbell, ohair

     1 /*
     2  * Copyright 2003-2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 #include "incls/_precompiled.incl"
    26 #include "incls/_psVirtualspace.cpp.incl"
    28 // PSVirtualSpace
    30 PSVirtualSpace::PSVirtualSpace(ReservedSpace rs, size_t alignment) :
    31   _alignment(alignment)
    32 {
    33   set_reserved(rs);
    34   set_committed(reserved_low_addr(), reserved_low_addr());
    35   DEBUG_ONLY(verify());
    36 }
    38 PSVirtualSpace::PSVirtualSpace(ReservedSpace rs) :
    39   _alignment(os::vm_page_size())
    40 {
    41   set_reserved(rs);
    42   set_committed(reserved_low_addr(), reserved_low_addr());
    43   DEBUG_ONLY(verify());
    44 }
    46 // Deprecated.
    47 PSVirtualSpace::PSVirtualSpace(): _alignment(os::vm_page_size()) {
    48 }
    50 // Deprecated.
    51 bool PSVirtualSpace::initialize(ReservedSpace rs,
    52                                 size_t commit_size) {
    53   set_reserved(rs);
    54   set_committed(reserved_low_addr(), reserved_low_addr());
    56   // Commit to initial size.
    57   assert(commit_size <= rs.size(), "commit_size too big");
    58   bool result = commit_size > 0 ? expand_by(commit_size) : true;
    59   DEBUG_ONLY(verify());
    60   return result;
    61 }
    63 PSVirtualSpace::~PSVirtualSpace() {
    64   release();
    65 }
    67 bool PSVirtualSpace::contains(void* p) const {
    68   char* const cp = (char*)p;
    69   return cp >= committed_low_addr() && cp < committed_high_addr();
    70 }
    72 void PSVirtualSpace::release() {
    73   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
    74   // This may not release memory it didn't reserve.
    75   // Use rs.release() to release the underlying memory instead.
    76   _reserved_low_addr = _reserved_high_addr = NULL;
    77   _committed_low_addr = _committed_high_addr = NULL;
    78   _special = false;
    79 }
    81 bool PSVirtualSpace::expand_by(size_t bytes) {
    82   assert(is_aligned(bytes), "arg not aligned");
    83   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
    85   if (uncommitted_size() < bytes) {
    86     return false;
    87   }
    89   char* const base_addr = committed_high_addr();
    90   bool result = special() || os::commit_memory(base_addr, bytes, alignment());
    91   if (result) {
    92     _committed_high_addr += bytes;
    93   }
    95   return result;
    96 }
    98 bool PSVirtualSpace::shrink_by(size_t bytes) {
    99   assert(is_aligned(bytes), "arg not aligned");
   100   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
   102   if (committed_size() < bytes) {
   103     return false;
   104   }
   106   char* const base_addr = committed_high_addr() - bytes;
   107   bool result = special() || os::uncommit_memory(base_addr, bytes);
   108   if (result) {
   109     _committed_high_addr -= bytes;
   110   }
   112   return result;
   113 }
   115 size_t
   116 PSVirtualSpace::expand_into(PSVirtualSpace* other_space, size_t bytes) {
   117   assert(is_aligned(bytes), "arg not aligned");
   118   assert(grows_up(), "this space must grow up");
   119   assert(other_space->grows_down(), "other space must grow down");
   120   assert(reserved_high_addr() == other_space->reserved_low_addr(),
   121          "spaces not contiguous");
   122   assert(special() == other_space->special(), "one space is special, the other is not");
   123   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
   124   DEBUG_ONLY(PSVirtualSpaceVerifier other_verifier(other_space));
   126   size_t bytes_needed = bytes;
   128   // First use the uncommitted region in this space.
   129   size_t tmp_bytes = MIN2(uncommitted_size(), bytes_needed);
   130   if (tmp_bytes > 0) {
   131     if (expand_by(tmp_bytes)) {
   132       bytes_needed -= tmp_bytes;
   133     } else {
   134       return 0;
   135     }
   136   }
   138   // Next take from the uncommitted region in the other space, and commit it.
   139   tmp_bytes = MIN2(other_space->uncommitted_size(), bytes_needed);
   140   if (tmp_bytes > 0) {
   141     char* const commit_base = committed_high_addr();
   142     if (other_space->special() ||
   143         os::commit_memory(commit_base, tmp_bytes, alignment())) {
   144       // Reduce the reserved region in the other space.
   145       other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
   146                                 other_space->reserved_high_addr(),
   147                                 other_space->special());
   149       // Grow both reserved and committed in this space.
   150       _reserved_high_addr += tmp_bytes;
   151       _committed_high_addr += tmp_bytes;
   152       bytes_needed -= tmp_bytes;
   153     } else {
   154       return bytes - bytes_needed;
   155     }
   156   }
   158   // Finally take from the already committed region in the other space.
   159   tmp_bytes = bytes_needed;
   160   if (tmp_bytes > 0) {
   161     // Reduce both committed and reserved in the other space.
   162     other_space->set_committed(other_space->committed_low_addr() + tmp_bytes,
   163                                other_space->committed_high_addr());
   164     other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
   165                               other_space->reserved_high_addr(),
   166                               other_space->special());
   168     // Grow both reserved and committed in this space.
   169     _reserved_high_addr += tmp_bytes;
   170     _committed_high_addr += tmp_bytes;
   171   }
   173   return bytes;
   174 }
   176 #ifndef PRODUCT
   177 bool PSVirtualSpace::is_aligned(size_t value, size_t align) {
   178   const size_t tmp_value = value + align - 1;
   179   const size_t mask = ~(align - 1);
   180   return (tmp_value & mask) == value;
   181 }
   183 bool PSVirtualSpace::is_aligned(size_t value) const {
   184   return is_aligned(value, alignment());
   185 }
   187 bool PSVirtualSpace::is_aligned(char* value) const {
   188   return is_aligned((size_t)value);
   189 }
   191 void PSVirtualSpace::verify() const {
   192   assert(is_aligned(alignment(), os::vm_page_size()), "bad alignment");
   193   assert(is_aligned(reserved_low_addr()), "bad reserved_low_addr");
   194   assert(is_aligned(reserved_high_addr()), "bad reserved_high_addr");
   195   assert(is_aligned(committed_low_addr()), "bad committed_low_addr");
   196   assert(is_aligned(committed_high_addr()), "bad committed_high_addr");
   198   // Reserved region must be non-empty or both addrs must be 0.
   199   assert(reserved_low_addr() < reserved_high_addr() ||
   200          reserved_low_addr() == NULL && reserved_high_addr() == NULL,
   201          "bad reserved addrs");
   202   assert(committed_low_addr() <= committed_high_addr(), "bad committed addrs");
   204   if (grows_up()) {
   205     assert(reserved_low_addr() == committed_low_addr(), "bad low addrs");
   206     assert(reserved_high_addr() >= committed_high_addr(), "bad high addrs");
   207   } else {
   208     assert(reserved_high_addr() == committed_high_addr(), "bad high addrs");
   209     assert(reserved_low_addr() <= committed_low_addr(), "bad low addrs");
   210   }
   211 }
   213 void PSVirtualSpace::print() const {
   214   gclog_or_tty->print_cr("virtual space [" PTR_FORMAT "]:  alignment="
   215                          SIZE_FORMAT "K grows %s%s",
   216                          this, alignment() / K, grows_up() ? "up" : "down",
   217                          special() ? " (pinned in memory)" : "");
   218   gclog_or_tty->print_cr("    reserved=" SIZE_FORMAT "K"
   219                          " [" PTR_FORMAT "," PTR_FORMAT "]"
   220                          " committed=" SIZE_FORMAT "K"
   221                          " [" PTR_FORMAT "," PTR_FORMAT "]",
   222                          reserved_size() / K,
   223                          reserved_low_addr(), reserved_high_addr(),
   224                          committed_size() / K,
   225                          committed_low_addr(), committed_high_addr());
   226 }
   227 #endif // #ifndef PRODUCT
   229 void PSVirtualSpace::print_space_boundaries_on(outputStream* st) const {
   230   st->print_cr(" [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")",
   231                low_boundary(), high(), high_boundary());
   232 }
   234 PSVirtualSpaceHighToLow::PSVirtualSpaceHighToLow(ReservedSpace rs,
   235                                                  size_t alignment) :
   236   PSVirtualSpace(alignment)
   237 {
   238   set_reserved(rs);
   239   set_committed(reserved_high_addr(), reserved_high_addr());
   240   DEBUG_ONLY(verify());
   241 }
   243 PSVirtualSpaceHighToLow::PSVirtualSpaceHighToLow(ReservedSpace rs) {
   244   set_reserved(rs);
   245   set_committed(reserved_high_addr(), reserved_high_addr());
   246   DEBUG_ONLY(verify());
   247 }
   249 bool PSVirtualSpaceHighToLow::expand_by(size_t bytes) {
   250   assert(is_aligned(bytes), "arg not aligned");
   251   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
   253   if (uncommitted_size() < bytes) {
   254     return false;
   255   }
   257   char* const base_addr = committed_low_addr() - bytes;
   258   bool result = special() || os::commit_memory(base_addr, bytes, alignment());
   259   if (result) {
   260     _committed_low_addr -= bytes;
   261   }
   263   return result;
   264 }
   266 bool PSVirtualSpaceHighToLow::shrink_by(size_t bytes) {
   267   assert(is_aligned(bytes), "arg not aligned");
   268   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
   270   if (committed_size() < bytes) {
   271     return false;
   272   }
   274   char* const base_addr = committed_low_addr();
   275   bool result = special() || os::uncommit_memory(base_addr, bytes);
   276   if (result) {
   277     _committed_low_addr += bytes;
   278   }
   280   return result;
   281 }
   283 size_t PSVirtualSpaceHighToLow::expand_into(PSVirtualSpace* other_space,
   284                                             size_t bytes) {
   285   assert(is_aligned(bytes), "arg not aligned");
   286   assert(grows_down(), "this space must grow down");
   287   assert(other_space->grows_up(), "other space must grow up");
   288   assert(reserved_low_addr() == other_space->reserved_high_addr(),
   289          "spaces not contiguous");
   290   assert(special() == other_space->special(), "one space is special in memory, the other is not");
   291   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
   292   DEBUG_ONLY(PSVirtualSpaceVerifier other_verifier(other_space));
   294   size_t bytes_needed = bytes;
   296   // First use the uncommitted region in this space.
   297   size_t tmp_bytes = MIN2(uncommitted_size(), bytes_needed);
   298   if (tmp_bytes > 0) {
   299     if (expand_by(tmp_bytes)) {
   300       bytes_needed -= tmp_bytes;
   301     } else {
   302       return 0;
   303     }
   304   }
   306   // Next take from the uncommitted region in the other space, and commit it.
   307   tmp_bytes = MIN2(other_space->uncommitted_size(), bytes_needed);
   308   if (tmp_bytes > 0) {
   309     char* const commit_base = committed_low_addr() - tmp_bytes;
   310     if (other_space->special() ||
   311         os::commit_memory(commit_base, tmp_bytes, alignment())) {
   312       // Reduce the reserved region in the other space.
   313       other_space->set_reserved(other_space->reserved_low_addr(),
   314                                 other_space->reserved_high_addr() - tmp_bytes,
   315                                 other_space->special());
   317       // Grow both reserved and committed in this space.
   318       _reserved_low_addr -= tmp_bytes;
   319       _committed_low_addr -= tmp_bytes;
   320       bytes_needed -= tmp_bytes;
   321     } else {
   322       return bytes - bytes_needed;
   323     }
   324   }
   326   // Finally take from the already committed region in the other space.
   327   tmp_bytes = bytes_needed;
   328   if (tmp_bytes > 0) {
   329     // Reduce both committed and reserved in the other space.
   330     other_space->set_committed(other_space->committed_low_addr(),
   331                                other_space->committed_high_addr() - tmp_bytes);
   332     other_space->set_reserved(other_space->reserved_low_addr(),
   333                               other_space->reserved_high_addr() - tmp_bytes,
   334                               other_space->special());
   336     // Grow both reserved and committed in this space.
   337     _reserved_low_addr -= tmp_bytes;
   338     _committed_low_addr -= tmp_bytes;
   339   }
   341   return bytes;
   342 }
   344 void
   345 PSVirtualSpaceHighToLow::print_space_boundaries_on(outputStream* st) const {
   346   st->print_cr(" (" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT "]",
   347                high_boundary(), low(), low_boundary());
   348 }

mercurial