src/share/vm/runtime/virtualspace.cpp

Fri, 27 Sep 2013 08:39:19 +0200

author
rbackman
date
Fri, 27 Sep 2013 08:39:19 +0200
changeset 5791
c9ccd7b85f20
parent 5708
8c5e6482cbfc
child 5859
04b18a42c2f3
permissions
-rw-r--r--

8024924: Intrinsify java.lang.Math.addExact
Reviewed-by: kvn, twisti

     1 /*
     2  * Copyright (c) 1997, 2013, 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 "oops/markOop.hpp"
    27 #include "oops/oop.inline.hpp"
    28 #include "runtime/virtualspace.hpp"
    29 #include "services/memTracker.hpp"
    30 #ifdef TARGET_OS_FAMILY_linux
    31 # include "os_linux.inline.hpp"
    32 #endif
    33 #ifdef TARGET_OS_FAMILY_solaris
    34 # include "os_solaris.inline.hpp"
    35 #endif
    36 #ifdef TARGET_OS_FAMILY_windows
    37 # include "os_windows.inline.hpp"
    38 #endif
    39 #ifdef TARGET_OS_FAMILY_bsd
    40 # include "os_bsd.inline.hpp"
    41 #endif
    44 // ReservedSpace
    46 // Dummy constructor
    47 ReservedSpace::ReservedSpace() : _base(NULL), _size(0), _noaccess_prefix(0),
    48     _alignment(0), _special(false), _executable(false) {
    49 }
    51 ReservedSpace::ReservedSpace(size_t size) {
    52   size_t page_size = os::page_size_for_region(size, size, 1);
    53   bool large_pages = page_size != (size_t)os::vm_page_size();
    54   // Don't force the alignment to be large page aligned,
    55   // since that will waste memory.
    56   size_t alignment = os::vm_allocation_granularity();
    57   initialize(size, alignment, large_pages, NULL, 0, false);
    58 }
    60 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
    61                              bool large,
    62                              char* requested_address,
    63                              const size_t noaccess_prefix) {
    64   initialize(size+noaccess_prefix, alignment, large, requested_address,
    65              noaccess_prefix, false);
    66 }
    68 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
    69                              bool large,
    70                              bool executable) {
    71   initialize(size, alignment, large, NULL, 0, executable);
    72 }
    74 // Helper method.
    75 static bool failed_to_reserve_as_requested(char* base, char* requested_address,
    76                                            const size_t size, bool special)
    77 {
    78   if (base == requested_address || requested_address == NULL)
    79     return false; // did not fail
    81   if (base != NULL) {
    82     // Different reserve address may be acceptable in other cases
    83     // but for compressed oops heap should be at requested address.
    84     assert(UseCompressedOops, "currently requested address used only for compressed oops");
    85     if (PrintCompressedOopsMode) {
    86       tty->cr();
    87       tty->print_cr("Reserved memory not at requested address: " PTR_FORMAT " vs " PTR_FORMAT, base, requested_address);
    88     }
    89     // OS ignored requested address. Try different address.
    90     if (special) {
    91       if (!os::release_memory_special(base, size)) {
    92         fatal("os::release_memory_special failed");
    93       }
    94     } else {
    95       if (!os::release_memory(base, size)) {
    96         fatal("os::release_memory failed");
    97       }
    98     }
    99   }
   100   return true;
   101 }
   103 void ReservedSpace::initialize(size_t size, size_t alignment, bool large,
   104                                char* requested_address,
   105                                const size_t noaccess_prefix,
   106                                bool executable) {
   107   const size_t granularity = os::vm_allocation_granularity();
   108   assert((size & (granularity - 1)) == 0,
   109          "size not aligned to os::vm_allocation_granularity()");
   110   assert((alignment & (granularity - 1)) == 0,
   111          "alignment not aligned to os::vm_allocation_granularity()");
   112   assert(alignment == 0 || is_power_of_2((intptr_t)alignment),
   113          "not a power of 2");
   115   alignment = MAX2(alignment, (size_t)os::vm_page_size());
   117   // Assert that if noaccess_prefix is used, it is the same as alignment.
   118   assert(noaccess_prefix == 0 ||
   119          noaccess_prefix == alignment, "noaccess prefix wrong");
   121   _base = NULL;
   122   _size = 0;
   123   _special = false;
   124   _executable = executable;
   125   _alignment = 0;
   126   _noaccess_prefix = 0;
   127   if (size == 0) {
   128     return;
   129   }
   131   // If OS doesn't support demand paging for large page memory, we need
   132   // to use reserve_memory_special() to reserve and pin the entire region.
   133   bool special = large && !os::can_commit_large_page_memory();
   134   char* base = NULL;
   136   if (requested_address != 0) {
   137     requested_address -= noaccess_prefix; // adjust requested address
   138     assert(requested_address != NULL, "huge noaccess prefix?");
   139   }
   141   if (special) {
   143     base = os::reserve_memory_special(size, alignment, requested_address, executable);
   145     if (base != NULL) {
   146       if (failed_to_reserve_as_requested(base, requested_address, size, true)) {
   147         // OS ignored requested address. Try different address.
   148         return;
   149       }
   150       // Check alignment constraints.
   151       assert((uintptr_t) base % alignment == 0,
   152              err_msg("Large pages returned a non-aligned address, base: "
   153                  PTR_FORMAT " alignment: " PTR_FORMAT,
   154                  base, (void*)(uintptr_t)alignment));
   155       _special = true;
   156     } else {
   157       // failed; try to reserve regular memory below
   158       if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
   159                             !FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
   160         if (PrintCompressedOopsMode) {
   161           tty->cr();
   162           tty->print_cr("Reserve regular memory without large pages.");
   163         }
   164       }
   165     }
   166   }
   168   if (base == NULL) {
   169     // Optimistically assume that the OSes returns an aligned base pointer.
   170     // When reserving a large address range, most OSes seem to align to at
   171     // least 64K.
   173     // If the memory was requested at a particular address, use
   174     // os::attempt_reserve_memory_at() to avoid over mapping something
   175     // important.  If available space is not detected, return NULL.
   177     if (requested_address != 0) {
   178       base = os::attempt_reserve_memory_at(size, requested_address);
   179       if (failed_to_reserve_as_requested(base, requested_address, size, false)) {
   180         // OS ignored requested address. Try different address.
   181         base = NULL;
   182       }
   183     } else {
   184       base = os::reserve_memory(size, NULL, alignment);
   185     }
   187     if (base == NULL) return;
   189     // Check alignment constraints
   190     if ((((size_t)base + noaccess_prefix) & (alignment - 1)) != 0) {
   191       // Base not aligned, retry
   192       if (!os::release_memory(base, size)) fatal("os::release_memory failed");
   193       // Make sure that size is aligned
   194       size = align_size_up(size, alignment);
   195       base = os::reserve_memory_aligned(size, alignment);
   197       if (requested_address != 0 &&
   198           failed_to_reserve_as_requested(base, requested_address, size, false)) {
   199         // As a result of the alignment constraints, the allocated base differs
   200         // from the requested address. Return back to the caller who can
   201         // take remedial action (like try again without a requested address).
   202         assert(_base == NULL, "should be");
   203         return;
   204       }
   205     }
   206   }
   207   // Done
   208   _base = base;
   209   _size = size;
   210   _alignment = alignment;
   211   _noaccess_prefix = noaccess_prefix;
   213   // Assert that if noaccess_prefix is used, it is the same as alignment.
   214   assert(noaccess_prefix == 0 ||
   215          noaccess_prefix == _alignment, "noaccess prefix wrong");
   217   assert(markOopDesc::encode_pointer_as_mark(_base)->decode_pointer() == _base,
   218          "area must be distinguisable from marks for mark-sweep");
   219   assert(markOopDesc::encode_pointer_as_mark(&_base[size])->decode_pointer() == &_base[size],
   220          "area must be distinguisable from marks for mark-sweep");
   221 }
   224 ReservedSpace::ReservedSpace(char* base, size_t size, size_t alignment,
   225                              bool special, bool executable) {
   226   assert((size % os::vm_allocation_granularity()) == 0,
   227          "size not allocation aligned");
   228   _base = base;
   229   _size = size;
   230   _alignment = alignment;
   231   _noaccess_prefix = 0;
   232   _special = special;
   233   _executable = executable;
   234 }
   237 ReservedSpace ReservedSpace::first_part(size_t partition_size, size_t alignment,
   238                                         bool split, bool realloc) {
   239   assert(partition_size <= size(), "partition failed");
   240   if (split) {
   241     os::split_reserved_memory(base(), size(), partition_size, realloc);
   242   }
   243   ReservedSpace result(base(), partition_size, alignment, special(),
   244                        executable());
   245   return result;
   246 }
   249 ReservedSpace
   250 ReservedSpace::last_part(size_t partition_size, size_t alignment) {
   251   assert(partition_size <= size(), "partition failed");
   252   ReservedSpace result(base() + partition_size, size() - partition_size,
   253                        alignment, special(), executable());
   254   return result;
   255 }
   258 size_t ReservedSpace::page_align_size_up(size_t size) {
   259   return align_size_up(size, os::vm_page_size());
   260 }
   263 size_t ReservedSpace::page_align_size_down(size_t size) {
   264   return align_size_down(size, os::vm_page_size());
   265 }
   268 size_t ReservedSpace::allocation_align_size_up(size_t size) {
   269   return align_size_up(size, os::vm_allocation_granularity());
   270 }
   273 size_t ReservedSpace::allocation_align_size_down(size_t size) {
   274   return align_size_down(size, os::vm_allocation_granularity());
   275 }
   278 void ReservedSpace::release() {
   279   if (is_reserved()) {
   280     char *real_base = _base - _noaccess_prefix;
   281     const size_t real_size = _size + _noaccess_prefix;
   282     if (special()) {
   283       os::release_memory_special(real_base, real_size);
   284     } else{
   285       os::release_memory(real_base, real_size);
   286     }
   287     _base = NULL;
   288     _size = 0;
   289     _noaccess_prefix = 0;
   290     _special = false;
   291     _executable = false;
   292   }
   293 }
   295 void ReservedSpace::protect_noaccess_prefix(const size_t size) {
   296   assert( (_noaccess_prefix != 0) == (UseCompressedOops && _base != NULL &&
   297                                       (Universe::narrow_oop_base() != NULL) &&
   298                                       Universe::narrow_oop_use_implicit_null_checks()),
   299          "noaccess_prefix should be used only with non zero based compressed oops");
   301   // If there is no noaccess prefix, return.
   302   if (_noaccess_prefix == 0) return;
   304   assert(_noaccess_prefix >= (size_t)os::vm_page_size(),
   305          "must be at least page size big");
   307   // Protect memory at the base of the allocated region.
   308   // If special, the page was committed (only matters on windows)
   309   if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE,
   310                           _special)) {
   311     fatal("cannot protect protection page");
   312   }
   313   if (PrintCompressedOopsMode) {
   314     tty->cr();
   315     tty->print_cr("Protected page at the reserved heap base: " PTR_FORMAT " / " INTX_FORMAT " bytes", _base, _noaccess_prefix);
   316   }
   318   _base += _noaccess_prefix;
   319   _size -= _noaccess_prefix;
   320   assert((size == _size) && ((uintptr_t)_base % _alignment == 0),
   321          "must be exactly of required size and alignment");
   322 }
   324 ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment,
   325                                      bool large, char* requested_address) :
   326   ReservedSpace(size, alignment, large,
   327                 requested_address,
   328                 (UseCompressedOops && (Universe::narrow_oop_base() != NULL) &&
   329                  Universe::narrow_oop_use_implicit_null_checks()) ?
   330                   lcm(os::vm_page_size(), alignment) : 0) {
   331   if (base() > 0) {
   332     MemTracker::record_virtual_memory_type((address)base(), mtJavaHeap);
   333   }
   335   // Only reserved space for the java heap should have a noaccess_prefix
   336   // if using compressed oops.
   337   protect_noaccess_prefix(size);
   338 }
   340 // Reserve space for code segment.  Same as Java heap only we mark this as
   341 // executable.
   342 ReservedCodeSpace::ReservedCodeSpace(size_t r_size,
   343                                      size_t rs_align,
   344                                      bool large) :
   345   ReservedSpace(r_size, rs_align, large, /*executable*/ true) {
   346   MemTracker::record_virtual_memory_type((address)base(), mtCode);
   347 }
   349 // VirtualSpace
   351 VirtualSpace::VirtualSpace() {
   352   _low_boundary           = NULL;
   353   _high_boundary          = NULL;
   354   _low                    = NULL;
   355   _high                   = NULL;
   356   _lower_high             = NULL;
   357   _middle_high            = NULL;
   358   _upper_high             = NULL;
   359   _lower_high_boundary    = NULL;
   360   _middle_high_boundary   = NULL;
   361   _upper_high_boundary    = NULL;
   362   _lower_alignment        = 0;
   363   _middle_alignment       = 0;
   364   _upper_alignment        = 0;
   365   _special                = false;
   366   _executable             = false;
   367 }
   370 bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) {
   371   if(!rs.is_reserved()) return false;  // allocation failed.
   372   assert(_low_boundary == NULL, "VirtualSpace already initialized");
   373   _low_boundary  = rs.base();
   374   _high_boundary = low_boundary() + rs.size();
   376   _low = low_boundary();
   377   _high = low();
   379   _special = rs.special();
   380   _executable = rs.executable();
   382   // When a VirtualSpace begins life at a large size, make all future expansion
   383   // and shrinking occur aligned to a granularity of large pages.  This avoids
   384   // fragmentation of physical addresses that inhibits the use of large pages
   385   // by the OS virtual memory system.  Empirically,  we see that with a 4MB
   386   // page size, the only spaces that get handled this way are codecache and
   387   // the heap itself, both of which provide a substantial performance
   388   // boost in many benchmarks when covered by large pages.
   389   //
   390   // No attempt is made to force large page alignment at the very top and
   391   // bottom of the space if they are not aligned so already.
   392   _lower_alignment  = os::vm_page_size();
   393   _middle_alignment = os::page_size_for_region(rs.size(), rs.size(), 1);
   394   _upper_alignment  = os::vm_page_size();
   396   // End of each region
   397   _lower_high_boundary = (char*) round_to((intptr_t) low_boundary(), middle_alignment());
   398   _middle_high_boundary = (char*) round_down((intptr_t) high_boundary(), middle_alignment());
   399   _upper_high_boundary = high_boundary();
   401   // High address of each region
   402   _lower_high = low_boundary();
   403   _middle_high = lower_high_boundary();
   404   _upper_high = middle_high_boundary();
   406   // commit to initial size
   407   if (committed_size > 0) {
   408     if (!expand_by(committed_size)) {
   409       return false;
   410     }
   411   }
   412   return true;
   413 }
   416 VirtualSpace::~VirtualSpace() {
   417   release();
   418 }
   421 void VirtualSpace::release() {
   422   // This does not release memory it never reserved.
   423   // Caller must release via rs.release();
   424   _low_boundary           = NULL;
   425   _high_boundary          = NULL;
   426   _low                    = NULL;
   427   _high                   = NULL;
   428   _lower_high             = NULL;
   429   _middle_high            = NULL;
   430   _upper_high             = NULL;
   431   _lower_high_boundary    = NULL;
   432   _middle_high_boundary   = NULL;
   433   _upper_high_boundary    = NULL;
   434   _lower_alignment        = 0;
   435   _middle_alignment       = 0;
   436   _upper_alignment        = 0;
   437   _special                = false;
   438   _executable             = false;
   439 }
   442 size_t VirtualSpace::committed_size() const {
   443   return pointer_delta(high(), low(), sizeof(char));
   444 }
   447 size_t VirtualSpace::reserved_size() const {
   448   return pointer_delta(high_boundary(), low_boundary(), sizeof(char));
   449 }
   452 size_t VirtualSpace::uncommitted_size()  const {
   453   return reserved_size() - committed_size();
   454 }
   456 size_t VirtualSpace::actual_committed_size() const {
   457   // Special VirtualSpaces commit all reserved space up front.
   458   if (special()) {
   459     return reserved_size();
   460   }
   462   size_t committed_low    = pointer_delta(_lower_high,  _low_boundary,         sizeof(char));
   463   size_t committed_middle = pointer_delta(_middle_high, _lower_high_boundary,  sizeof(char));
   464   size_t committed_high   = pointer_delta(_upper_high,  _middle_high_boundary, sizeof(char));
   466 #ifdef ASSERT
   467   size_t lower  = pointer_delta(_lower_high_boundary,  _low_boundary,         sizeof(char));
   468   size_t middle = pointer_delta(_middle_high_boundary, _lower_high_boundary,  sizeof(char));
   469   size_t upper  = pointer_delta(_upper_high_boundary,  _middle_high_boundary, sizeof(char));
   471   if (committed_high > 0) {
   472     assert(committed_low == lower, "Must be");
   473     assert(committed_middle == middle, "Must be");
   474   }
   476   if (committed_middle > 0) {
   477     assert(committed_low == lower, "Must be");
   478   }
   479   if (committed_middle < middle) {
   480     assert(committed_high == 0, "Must be");
   481   }
   483   if (committed_low < lower) {
   484     assert(committed_high == 0, "Must be");
   485     assert(committed_middle == 0, "Must be");
   486   }
   487 #endif
   489   return committed_low + committed_middle + committed_high;
   490 }
   493 bool VirtualSpace::contains(const void* p) const {
   494   return low() <= (const char*) p && (const char*) p < high();
   495 }
   497 /*
   498    First we need to determine if a particular virtual space is using large
   499    pages.  This is done at the initialize function and only virtual spaces
   500    that are larger than LargePageSizeInBytes use large pages.  Once we
   501    have determined this, all expand_by and shrink_by calls must grow and
   502    shrink by large page size chunks.  If a particular request
   503    is within the current large page, the call to commit and uncommit memory
   504    can be ignored.  In the case that the low and high boundaries of this
   505    space is not large page aligned, the pages leading to the first large
   506    page address and the pages after the last large page address must be
   507    allocated with default pages.
   508 */
   509 bool VirtualSpace::expand_by(size_t bytes, bool pre_touch) {
   510   if (uncommitted_size() < bytes) return false;
   512   if (special()) {
   513     // don't commit memory if the entire space is pinned in memory
   514     _high += bytes;
   515     return true;
   516   }
   518   char* previous_high = high();
   519   char* unaligned_new_high = high() + bytes;
   520   assert(unaligned_new_high <= high_boundary(),
   521          "cannot expand by more than upper boundary");
   523   // Calculate where the new high for each of the regions should be.  If
   524   // the low_boundary() and high_boundary() are LargePageSizeInBytes aligned
   525   // then the unaligned lower and upper new highs would be the
   526   // lower_high() and upper_high() respectively.
   527   char* unaligned_lower_new_high =
   528     MIN2(unaligned_new_high, lower_high_boundary());
   529   char* unaligned_middle_new_high =
   530     MIN2(unaligned_new_high, middle_high_boundary());
   531   char* unaligned_upper_new_high =
   532     MIN2(unaligned_new_high, upper_high_boundary());
   534   // Align the new highs based on the regions alignment.  lower and upper
   535   // alignment will always be default page size.  middle alignment will be
   536   // LargePageSizeInBytes if the actual size of the virtual space is in
   537   // fact larger than LargePageSizeInBytes.
   538   char* aligned_lower_new_high =
   539     (char*) round_to((intptr_t) unaligned_lower_new_high, lower_alignment());
   540   char* aligned_middle_new_high =
   541     (char*) round_to((intptr_t) unaligned_middle_new_high, middle_alignment());
   542   char* aligned_upper_new_high =
   543     (char*) round_to((intptr_t) unaligned_upper_new_high, upper_alignment());
   545   // Determine which regions need to grow in this expand_by call.
   546   // If you are growing in the lower region, high() must be in that
   547   // region so calcuate the size based on high().  For the middle and
   548   // upper regions, determine the starting point of growth based on the
   549   // location of high().  By getting the MAX of the region's low address
   550   // (or the prevoius region's high address) and high(), we can tell if it
   551   // is an intra or inter region growth.
   552   size_t lower_needs = 0;
   553   if (aligned_lower_new_high > lower_high()) {
   554     lower_needs =
   555       pointer_delta(aligned_lower_new_high, lower_high(), sizeof(char));
   556   }
   557   size_t middle_needs = 0;
   558   if (aligned_middle_new_high > middle_high()) {
   559     middle_needs =
   560       pointer_delta(aligned_middle_new_high, middle_high(), sizeof(char));
   561   }
   562   size_t upper_needs = 0;
   563   if (aligned_upper_new_high > upper_high()) {
   564     upper_needs =
   565       pointer_delta(aligned_upper_new_high, upper_high(), sizeof(char));
   566   }
   568   // Check contiguity.
   569   assert(low_boundary() <= lower_high() &&
   570          lower_high() <= lower_high_boundary(),
   571          "high address must be contained within the region");
   572   assert(lower_high_boundary() <= middle_high() &&
   573          middle_high() <= middle_high_boundary(),
   574          "high address must be contained within the region");
   575   assert(middle_high_boundary() <= upper_high() &&
   576          upper_high() <= upper_high_boundary(),
   577          "high address must be contained within the region");
   579   // Commit regions
   580   if (lower_needs > 0) {
   581     assert(low_boundary() <= lower_high() &&
   582            lower_high() + lower_needs <= lower_high_boundary(),
   583            "must not expand beyond region");
   584     if (!os::commit_memory(lower_high(), lower_needs, _executable)) {
   585       debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
   586                          ", lower_needs=" SIZE_FORMAT ", %d) failed",
   587                          lower_high(), lower_needs, _executable);)
   588       return false;
   589     } else {
   590       _lower_high += lower_needs;
   591     }
   592   }
   593   if (middle_needs > 0) {
   594     assert(lower_high_boundary() <= middle_high() &&
   595            middle_high() + middle_needs <= middle_high_boundary(),
   596            "must not expand beyond region");
   597     if (!os::commit_memory(middle_high(), middle_needs, middle_alignment(),
   598                            _executable)) {
   599       debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
   600                          ", middle_needs=" SIZE_FORMAT ", " SIZE_FORMAT
   601                          ", %d) failed", middle_high(), middle_needs,
   602                          middle_alignment(), _executable);)
   603       return false;
   604     }
   605     _middle_high += middle_needs;
   606   }
   607   if (upper_needs > 0) {
   608     assert(middle_high_boundary() <= upper_high() &&
   609            upper_high() + upper_needs <= upper_high_boundary(),
   610            "must not expand beyond region");
   611     if (!os::commit_memory(upper_high(), upper_needs, _executable)) {
   612       debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
   613                          ", upper_needs=" SIZE_FORMAT ", %d) failed",
   614                          upper_high(), upper_needs, _executable);)
   615       return false;
   616     } else {
   617       _upper_high += upper_needs;
   618     }
   619   }
   621   if (pre_touch || AlwaysPreTouch) {
   622     int vm_ps = os::vm_page_size();
   623     for (char* curr = previous_high;
   624          curr < unaligned_new_high;
   625          curr += vm_ps) {
   626       // Note the use of a write here; originally we tried just a read, but
   627       // since the value read was unused, the optimizer removed the read.
   628       // If we ever have a concurrent touchahead thread, we'll want to use
   629       // a read, to avoid the potential of overwriting data (if a mutator
   630       // thread beats the touchahead thread to a page).  There are various
   631       // ways of making sure this read is not optimized away: for example,
   632       // generating the code for a read procedure at runtime.
   633       *curr = 0;
   634     }
   635   }
   637   _high += bytes;
   638   return true;
   639 }
   641 // A page is uncommitted if the contents of the entire page is deemed unusable.
   642 // Continue to decrement the high() pointer until it reaches a page boundary
   643 // in which case that particular page can now be uncommitted.
   644 void VirtualSpace::shrink_by(size_t size) {
   645   if (committed_size() < size)
   646     fatal("Cannot shrink virtual space to negative size");
   648   if (special()) {
   649     // don't uncommit if the entire space is pinned in memory
   650     _high -= size;
   651     return;
   652   }
   654   char* unaligned_new_high = high() - size;
   655   assert(unaligned_new_high >= low_boundary(), "cannot shrink past lower boundary");
   657   // Calculate new unaligned address
   658   char* unaligned_upper_new_high =
   659     MAX2(unaligned_new_high, middle_high_boundary());
   660   char* unaligned_middle_new_high =
   661     MAX2(unaligned_new_high, lower_high_boundary());
   662   char* unaligned_lower_new_high =
   663     MAX2(unaligned_new_high, low_boundary());
   665   // Align address to region's alignment
   666   char* aligned_upper_new_high =
   667     (char*) round_to((intptr_t) unaligned_upper_new_high, upper_alignment());
   668   char* aligned_middle_new_high =
   669     (char*) round_to((intptr_t) unaligned_middle_new_high, middle_alignment());
   670   char* aligned_lower_new_high =
   671     (char*) round_to((intptr_t) unaligned_lower_new_high, lower_alignment());
   673   // Determine which regions need to shrink
   674   size_t upper_needs = 0;
   675   if (aligned_upper_new_high < upper_high()) {
   676     upper_needs =
   677       pointer_delta(upper_high(), aligned_upper_new_high, sizeof(char));
   678   }
   679   size_t middle_needs = 0;
   680   if (aligned_middle_new_high < middle_high()) {
   681     middle_needs =
   682       pointer_delta(middle_high(), aligned_middle_new_high, sizeof(char));
   683   }
   684   size_t lower_needs = 0;
   685   if (aligned_lower_new_high < lower_high()) {
   686     lower_needs =
   687       pointer_delta(lower_high(), aligned_lower_new_high, sizeof(char));
   688   }
   690   // Check contiguity.
   691   assert(middle_high_boundary() <= upper_high() &&
   692          upper_high() <= upper_high_boundary(),
   693          "high address must be contained within the region");
   694   assert(lower_high_boundary() <= middle_high() &&
   695          middle_high() <= middle_high_boundary(),
   696          "high address must be contained within the region");
   697   assert(low_boundary() <= lower_high() &&
   698          lower_high() <= lower_high_boundary(),
   699          "high address must be contained within the region");
   701   // Uncommit
   702   if (upper_needs > 0) {
   703     assert(middle_high_boundary() <= aligned_upper_new_high &&
   704            aligned_upper_new_high + upper_needs <= upper_high_boundary(),
   705            "must not shrink beyond region");
   706     if (!os::uncommit_memory(aligned_upper_new_high, upper_needs)) {
   707       debug_only(warning("os::uncommit_memory failed"));
   708       return;
   709     } else {
   710       _upper_high -= upper_needs;
   711     }
   712   }
   713   if (middle_needs > 0) {
   714     assert(lower_high_boundary() <= aligned_middle_new_high &&
   715            aligned_middle_new_high + middle_needs <= middle_high_boundary(),
   716            "must not shrink beyond region");
   717     if (!os::uncommit_memory(aligned_middle_new_high, middle_needs)) {
   718       debug_only(warning("os::uncommit_memory failed"));
   719       return;
   720     } else {
   721       _middle_high -= middle_needs;
   722     }
   723   }
   724   if (lower_needs > 0) {
   725     assert(low_boundary() <= aligned_lower_new_high &&
   726            aligned_lower_new_high + lower_needs <= lower_high_boundary(),
   727            "must not shrink beyond region");
   728     if (!os::uncommit_memory(aligned_lower_new_high, lower_needs)) {
   729       debug_only(warning("os::uncommit_memory failed"));
   730       return;
   731     } else {
   732       _lower_high -= lower_needs;
   733     }
   734   }
   736   _high -= size;
   737 }
   739 #ifndef PRODUCT
   740 void VirtualSpace::check_for_contiguity() {
   741   // Check contiguity.
   742   assert(low_boundary() <= lower_high() &&
   743          lower_high() <= lower_high_boundary(),
   744          "high address must be contained within the region");
   745   assert(lower_high_boundary() <= middle_high() &&
   746          middle_high() <= middle_high_boundary(),
   747          "high address must be contained within the region");
   748   assert(middle_high_boundary() <= upper_high() &&
   749          upper_high() <= upper_high_boundary(),
   750          "high address must be contained within the region");
   751   assert(low() >= low_boundary(), "low");
   752   assert(low_boundary() <= lower_high_boundary(), "lower high boundary");
   753   assert(upper_high_boundary() <= high_boundary(), "upper high boundary");
   754   assert(high() <= upper_high(), "upper high");
   755 }
   757 void VirtualSpace::print_on(outputStream* out) {
   758   out->print   ("Virtual space:");
   759   if (special()) out->print(" (pinned in memory)");
   760   out->cr();
   761   out->print_cr(" - committed: " SIZE_FORMAT, committed_size());
   762   out->print_cr(" - reserved:  " SIZE_FORMAT, reserved_size());
   763   out->print_cr(" - [low, high]:     [" INTPTR_FORMAT ", " INTPTR_FORMAT "]",  low(), high());
   764   out->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]",  low_boundary(), high_boundary());
   765 }
   767 void VirtualSpace::print() {
   768   print_on(tty);
   769 }
   771 /////////////// Unit tests ///////////////
   773 #ifndef PRODUCT
   775 #define test_log(...) \
   776   do {\
   777     if (VerboseInternalVMTests) { \
   778       tty->print_cr(__VA_ARGS__); \
   779       tty->flush(); \
   780     }\
   781   } while (false)
   783 class TestReservedSpace : AllStatic {
   784  public:
   785   static void small_page_write(void* addr, size_t size) {
   786     size_t page_size = os::vm_page_size();
   788     char* end = (char*)addr + size;
   789     for (char* p = (char*)addr; p < end; p += page_size) {
   790       *p = 1;
   791     }
   792   }
   794   static void release_memory_for_test(ReservedSpace rs) {
   795     if (rs.special()) {
   796       guarantee(os::release_memory_special(rs.base(), rs.size()), "Shouldn't fail");
   797     } else {
   798       guarantee(os::release_memory(rs.base(), rs.size()), "Shouldn't fail");
   799     }
   800   }
   802   static void test_reserved_space1(size_t size, size_t alignment) {
   803     test_log("test_reserved_space1(%p)", (void*) (uintptr_t) size);
   805     assert(is_size_aligned(size, alignment), "Incorrect input parameters");
   807     ReservedSpace rs(size,          // size
   808                      alignment,     // alignment
   809                      UseLargePages, // large
   810                      NULL,          // requested_address
   811                      0);            // noacces_prefix
   813     test_log(" rs.special() == %d", rs.special());
   815     assert(rs.base() != NULL, "Must be");
   816     assert(rs.size() == size, "Must be");
   818     assert(is_ptr_aligned(rs.base(), alignment), "aligned sizes should always give aligned addresses");
   819     assert(is_size_aligned(rs.size(), alignment), "aligned sizes should always give aligned addresses");
   821     if (rs.special()) {
   822       small_page_write(rs.base(), size);
   823     }
   825     release_memory_for_test(rs);
   826   }
   828   static void test_reserved_space2(size_t size) {
   829     test_log("test_reserved_space2(%p)", (void*)(uintptr_t)size);
   831     assert(is_size_aligned(size, os::vm_allocation_granularity()), "Must be at least AG aligned");
   833     ReservedSpace rs(size);
   835     test_log(" rs.special() == %d", rs.special());
   837     assert(rs.base() != NULL, "Must be");
   838     assert(rs.size() == size, "Must be");
   840     if (rs.special()) {
   841       small_page_write(rs.base(), size);
   842     }
   844     release_memory_for_test(rs);
   845   }
   847   static void test_reserved_space3(size_t size, size_t alignment, bool maybe_large) {
   848     test_log("test_reserved_space3(%p, %p, %d)",
   849         (void*)(uintptr_t)size, (void*)(uintptr_t)alignment, maybe_large);
   851     assert(is_size_aligned(size, os::vm_allocation_granularity()), "Must be at least AG aligned");
   852     assert(is_size_aligned(size, alignment), "Must be at least aligned against alignment");
   854     bool large = maybe_large && UseLargePages && size >= os::large_page_size();
   856     ReservedSpace rs(size, alignment, large, false);
   858     test_log(" rs.special() == %d", rs.special());
   860     assert(rs.base() != NULL, "Must be");
   861     assert(rs.size() == size, "Must be");
   863     if (rs.special()) {
   864       small_page_write(rs.base(), size);
   865     }
   867     release_memory_for_test(rs);
   868   }
   871   static void test_reserved_space1() {
   872     size_t size = 2 * 1024 * 1024;
   873     size_t ag   = os::vm_allocation_granularity();
   875     test_reserved_space1(size,      ag);
   876     test_reserved_space1(size * 2,  ag);
   877     test_reserved_space1(size * 10, ag);
   878   }
   880   static void test_reserved_space2() {
   881     size_t size = 2 * 1024 * 1024;
   882     size_t ag = os::vm_allocation_granularity();
   884     test_reserved_space2(size * 1);
   885     test_reserved_space2(size * 2);
   886     test_reserved_space2(size * 10);
   887     test_reserved_space2(ag);
   888     test_reserved_space2(size - ag);
   889     test_reserved_space2(size);
   890     test_reserved_space2(size + ag);
   891     test_reserved_space2(size * 2);
   892     test_reserved_space2(size * 2 - ag);
   893     test_reserved_space2(size * 2 + ag);
   894     test_reserved_space2(size * 3);
   895     test_reserved_space2(size * 3 - ag);
   896     test_reserved_space2(size * 3 + ag);
   897     test_reserved_space2(size * 10);
   898     test_reserved_space2(size * 10 + size / 2);
   899   }
   901   static void test_reserved_space3() {
   902     size_t ag = os::vm_allocation_granularity();
   904     test_reserved_space3(ag,      ag    , false);
   905     test_reserved_space3(ag * 2,  ag    , false);
   906     test_reserved_space3(ag * 3,  ag    , false);
   907     test_reserved_space3(ag * 2,  ag * 2, false);
   908     test_reserved_space3(ag * 4,  ag * 2, false);
   909     test_reserved_space3(ag * 8,  ag * 2, false);
   910     test_reserved_space3(ag * 4,  ag * 4, false);
   911     test_reserved_space3(ag * 8,  ag * 4, false);
   912     test_reserved_space3(ag * 16, ag * 4, false);
   914     if (UseLargePages) {
   915       size_t lp = os::large_page_size();
   917       // Without large pages
   918       test_reserved_space3(lp,     ag * 4, false);
   919       test_reserved_space3(lp * 2, ag * 4, false);
   920       test_reserved_space3(lp * 4, ag * 4, false);
   921       test_reserved_space3(lp,     lp    , false);
   922       test_reserved_space3(lp * 2, lp    , false);
   923       test_reserved_space3(lp * 3, lp    , false);
   924       test_reserved_space3(lp * 2, lp * 2, false);
   925       test_reserved_space3(lp * 4, lp * 2, false);
   926       test_reserved_space3(lp * 8, lp * 2, false);
   928       // With large pages
   929       test_reserved_space3(lp, ag * 4    , true);
   930       test_reserved_space3(lp * 2, ag * 4, true);
   931       test_reserved_space3(lp * 4, ag * 4, true);
   932       test_reserved_space3(lp, lp        , true);
   933       test_reserved_space3(lp * 2, lp    , true);
   934       test_reserved_space3(lp * 3, lp    , true);
   935       test_reserved_space3(lp * 2, lp * 2, true);
   936       test_reserved_space3(lp * 4, lp * 2, true);
   937       test_reserved_space3(lp * 8, lp * 2, true);
   938     }
   939   }
   941   static void test_reserved_space() {
   942     test_reserved_space1();
   943     test_reserved_space2();
   944     test_reserved_space3();
   945   }
   946 };
   948 void TestReservedSpace_test() {
   949   TestReservedSpace::test_reserved_space();
   950 }
   952 #define assert_equals(actual, expected)     \
   953   assert(actual == expected,                \
   954     err_msg("Got " SIZE_FORMAT " expected " \
   955       SIZE_FORMAT, actual, expected));
   957 #define assert_ge(value1, value2)                  \
   958   assert(value1 >= value2,                         \
   959     err_msg("'" #value1 "': " SIZE_FORMAT " '"     \
   960       #value2 "': " SIZE_FORMAT, value1, value2));
   962 #define assert_lt(value1, value2)                  \
   963   assert(value1 < value2,                          \
   964     err_msg("'" #value1 "': " SIZE_FORMAT " '"     \
   965       #value2 "': " SIZE_FORMAT, value1, value2));
   968 class TestVirtualSpace : AllStatic {
   969  public:
   970   static void test_virtual_space_actual_committed_space(size_t reserve_size, size_t commit_size) {
   971     size_t granularity = os::vm_allocation_granularity();
   972     size_t reserve_size_aligned = align_size_up(reserve_size, granularity);
   974     ReservedSpace reserved(reserve_size_aligned);
   976     assert(reserved.is_reserved(), "Must be");
   978     VirtualSpace vs;
   979     bool initialized = vs.initialize(reserved, 0);
   980     assert(initialized, "Failed to initialize VirtualSpace");
   982     vs.expand_by(commit_size, false);
   984     if (vs.special()) {
   985       assert_equals(vs.actual_committed_size(), reserve_size_aligned);
   986     } else {
   987       assert_ge(vs.actual_committed_size(), commit_size);
   988       // Approximate the commit granularity.
   989       size_t commit_granularity = UseLargePages ? os::large_page_size() : os::vm_page_size();
   990       assert_lt(vs.actual_committed_size(), commit_size + commit_granularity);
   991     }
   993     reserved.release();
   994   }
   996   static void test_virtual_space_actual_committed_space_one_large_page() {
   997     if (!UseLargePages) {
   998       return;
   999     }
  1001     size_t large_page_size = os::large_page_size();
  1003     ReservedSpace reserved(large_page_size, large_page_size, true, false);
  1005     assert(reserved.is_reserved(), "Must be");
  1007     VirtualSpace vs;
  1008     bool initialized = vs.initialize(reserved, 0);
  1009     assert(initialized, "Failed to initialize VirtualSpace");
  1011     vs.expand_by(large_page_size, false);
  1013     assert_equals(vs.actual_committed_size(), large_page_size);
  1015     reserved.release();
  1018   static void test_virtual_space_actual_committed_space() {
  1019     test_virtual_space_actual_committed_space(4 * K, 0);
  1020     test_virtual_space_actual_committed_space(4 * K, 4 * K);
  1021     test_virtual_space_actual_committed_space(8 * K, 0);
  1022     test_virtual_space_actual_committed_space(8 * K, 4 * K);
  1023     test_virtual_space_actual_committed_space(8 * K, 8 * K);
  1024     test_virtual_space_actual_committed_space(12 * K, 0);
  1025     test_virtual_space_actual_committed_space(12 * K, 4 * K);
  1026     test_virtual_space_actual_committed_space(12 * K, 8 * K);
  1027     test_virtual_space_actual_committed_space(12 * K, 12 * K);
  1028     test_virtual_space_actual_committed_space(64 * K, 0);
  1029     test_virtual_space_actual_committed_space(64 * K, 32 * K);
  1030     test_virtual_space_actual_committed_space(64 * K, 64 * K);
  1031     test_virtual_space_actual_committed_space(2 * M, 0);
  1032     test_virtual_space_actual_committed_space(2 * M, 4 * K);
  1033     test_virtual_space_actual_committed_space(2 * M, 64 * K);
  1034     test_virtual_space_actual_committed_space(2 * M, 1 * M);
  1035     test_virtual_space_actual_committed_space(2 * M, 2 * M);
  1036     test_virtual_space_actual_committed_space(10 * M, 0);
  1037     test_virtual_space_actual_committed_space(10 * M, 4 * K);
  1038     test_virtual_space_actual_committed_space(10 * M, 8 * K);
  1039     test_virtual_space_actual_committed_space(10 * M, 1 * M);
  1040     test_virtual_space_actual_committed_space(10 * M, 2 * M);
  1041     test_virtual_space_actual_committed_space(10 * M, 5 * M);
  1042     test_virtual_space_actual_committed_space(10 * M, 10 * M);
  1045   static void test_virtual_space() {
  1046     test_virtual_space_actual_committed_space();
  1047     test_virtual_space_actual_committed_space_one_large_page();
  1049 };
  1051 void TestVirtualSpace_test() {
  1052   TestVirtualSpace::test_virtual_space();
  1055 #endif // PRODUCT
  1057 #endif

mercurial