1 /*
   2  * Copyright (c) 1997, 2016, 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 "code/codeCacheExtensions.hpp"
  27 #include "memory/virtualspace.hpp"
  28 #include "oops/markOop.hpp"
  29 #include "oops/oop.inline.hpp"
  30 #include "services/memTracker.hpp"
  31 
  32 // ReservedSpace
  33 
  34 // Dummy constructor
  35 ReservedSpace::ReservedSpace() : _base(NULL), _size(0), _noaccess_prefix(0),
  36     _alignment(0), _special(false), _executable(false) {
  37 }
  38 
  39 ReservedSpace::ReservedSpace(size_t size, size_t preferred_page_size) {
  40   bool has_preferred_page_size = preferred_page_size != 0;
  41   // Want to use large pages where possible and pad with small pages.
  42   size_t page_size = has_preferred_page_size ? preferred_page_size : os::page_size_for_region_unaligned(size, 1);
  43   bool large_pages = page_size != (size_t)os::vm_page_size();
  44   size_t alignment;
  45   if (large_pages && has_preferred_page_size) {
  46     alignment = MAX2(page_size, (size_t)os::vm_allocation_granularity());
  47     // ReservedSpace initialization requires size to be aligned to the given
  48     // alignment. Align the size up.
  49     size = align_size_up(size, alignment);
  50   } else {
  51     // Don't force the alignment to be large page aligned,
  52     // since that will waste memory.
  53     alignment = os::vm_allocation_granularity();
  54   }
  55   initialize(size, alignment, large_pages, NULL, false);
  56 }
  57 
  58 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
  59                              bool large,
  60                              char* requested_address) {
  61   initialize(size, alignment, large, requested_address, false);
  62 }
  63 
  64 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
  65                              bool large,
  66                              bool executable) {
  67   initialize(size, alignment, large, NULL, executable);
  68 }
  69 
  70 // Helper method.
  71 static bool failed_to_reserve_as_requested(char* base, char* requested_address,
  72                                            const size_t size, bool special)
  73 {
  74   if (base == requested_address || requested_address == NULL)
  75     return false; // did not fail
  76 
  77   if (base != NULL) {
  78     // Different reserve address may be acceptable in other cases
  79     // but for compressed oops heap should be at requested address.
  80     assert(UseCompressedOops, "currently requested address used only for compressed oops");
  81     if (PrintCompressedOopsMode) {
  82       tty->cr();
  83       tty->print_cr("Reserved memory not at requested address: " PTR_FORMAT " vs " PTR_FORMAT, p2i(base), p2i(requested_address));
  84     }
  85     // OS ignored requested address. Try different address.
  86     if (special) {
  87       if (!os::release_memory_special(base, size)) {
  88         fatal("os::release_memory_special failed");
  89       }
  90     } else {
  91       if (!os::release_memory(base, size)) {
  92         fatal("os::release_memory failed");
  93       }
  94     }
  95   }
  96   return true;
  97 }
  98 
  99 void ReservedSpace::initialize(size_t size, size_t alignment, bool large,
 100                                char* requested_address,
 101                                bool executable) {
 102   const size_t granularity = os::vm_allocation_granularity();
 103   assert((size & (granularity - 1)) == 0,
 104          "size not aligned to os::vm_allocation_granularity()");
 105   assert((alignment & (granularity - 1)) == 0,
 106          "alignment not aligned to os::vm_allocation_granularity()");
 107   assert(alignment == 0 || is_power_of_2((intptr_t)alignment),
 108          "not a power of 2");
 109 
 110   alignment = MAX2(alignment, (size_t)os::vm_page_size());
 111 
 112   _base = NULL;
 113   _size = 0;
 114   _special = false;
 115   _executable = executable;
 116   _alignment = 0;
 117   _noaccess_prefix = 0;
 118   if (size == 0) {
 119     return;
 120   }
 121 
 122   // If OS doesn't support demand paging for large page memory, we need
 123   // to use reserve_memory_special() to reserve and pin the entire region.
 124   bool special = large && !os::can_commit_large_page_memory();
 125   char* base = NULL;
 126 
 127   if (special) {
 128 
 129     base = os::reserve_memory_special(size, alignment, requested_address, executable);
 130 
 131     if (base != NULL) {
 132       if (failed_to_reserve_as_requested(base, requested_address, size, true)) {
 133         // OS ignored requested address. Try different address.
 134         return;
 135       }
 136       // Check alignment constraints.
 137       assert((uintptr_t) base % alignment == 0,
 138              "Large pages returned a non-aligned address, base: "
 139              PTR_FORMAT " alignment: " SIZE_FORMAT_HEX,
 140              p2i(base), alignment);
 141       _special = true;
 142     } else {
 143       // failed; try to reserve regular memory below
 144       if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
 145                             !FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
 146         if (PrintCompressedOopsMode) {
 147           tty->cr();
 148           tty->print_cr("Reserve regular memory without large pages.");
 149         }
 150       }
 151     }
 152   }
 153 
 154   if (base == NULL) {
 155     // Optimistically assume that the OSes returns an aligned base pointer.
 156     // When reserving a large address range, most OSes seem to align to at
 157     // least 64K.
 158 
 159     // If the memory was requested at a particular address, use
 160     // os::attempt_reserve_memory_at() to avoid over mapping something
 161     // important.  If available space is not detected, return NULL.
 162 
 163     if (requested_address != 0) {
 164       base = os::attempt_reserve_memory_at(size, requested_address);
 165       if (failed_to_reserve_as_requested(base, requested_address, size, false)) {
 166         // OS ignored requested address. Try different address.
 167         base = NULL;
 168       }
 169     } else {
 170       base = os::reserve_memory(size, NULL, alignment);
 171     }
 172 
 173     if (base == NULL) return;
 174 
 175     // Check alignment constraints
 176     if ((((size_t)base) & (alignment - 1)) != 0) {
 177       // Base not aligned, retry
 178       if (!os::release_memory(base, size)) fatal("os::release_memory failed");
 179       // Make sure that size is aligned
 180       size = align_size_up(size, alignment);
 181       base = os::reserve_memory_aligned(size, alignment);
 182 
 183       if (requested_address != 0 &&
 184           failed_to_reserve_as_requested(base, requested_address, size, false)) {
 185         // As a result of the alignment constraints, the allocated base differs
 186         // from the requested address. Return back to the caller who can
 187         // take remedial action (like try again without a requested address).
 188         assert(_base == NULL, "should be");
 189         return;
 190       }
 191     }
 192   }
 193   // Done
 194   _base = base;
 195   _size = size;
 196   _alignment = alignment;
 197 }
 198 
 199 
 200 ReservedSpace::ReservedSpace(char* base, size_t size, size_t alignment,
 201                              bool special, bool executable) {
 202   assert((size % os::vm_allocation_granularity()) == 0,
 203          "size not allocation aligned");
 204   _base = base;
 205   _size = size;
 206   _alignment = alignment;
 207   _noaccess_prefix = 0;
 208   _special = special;
 209   _executable = executable;
 210 }
 211 
 212 
 213 ReservedSpace ReservedSpace::first_part(size_t partition_size, size_t alignment,
 214                                         bool split, bool realloc) {
 215   assert(partition_size <= size(), "partition failed");
 216   if (split) {
 217     os::split_reserved_memory(base(), size(), partition_size, realloc);
 218   }
 219   ReservedSpace result(base(), partition_size, alignment, special(),
 220                        executable());
 221   return result;
 222 }
 223 
 224 
 225 ReservedSpace
 226 ReservedSpace::last_part(size_t partition_size, size_t alignment) {
 227   assert(partition_size <= size(), "partition failed");
 228   ReservedSpace result(base() + partition_size, size() - partition_size,
 229                        alignment, special(), executable());
 230   return result;
 231 }
 232 
 233 
 234 size_t ReservedSpace::page_align_size_up(size_t size) {
 235   return align_size_up(size, os::vm_page_size());
 236 }
 237 
 238 
 239 size_t ReservedSpace::page_align_size_down(size_t size) {
 240   return align_size_down(size, os::vm_page_size());
 241 }
 242 
 243 
 244 size_t ReservedSpace::allocation_align_size_up(size_t size) {
 245   return align_size_up(size, os::vm_allocation_granularity());
 246 }
 247 
 248 
 249 size_t ReservedSpace::allocation_align_size_down(size_t size) {
 250   return align_size_down(size, os::vm_allocation_granularity());
 251 }
 252 
 253 
 254 void ReservedSpace::release() {
 255   if (is_reserved()) {
 256     char *real_base = _base - _noaccess_prefix;
 257     const size_t real_size = _size + _noaccess_prefix;
 258     if (special()) {
 259       os::release_memory_special(real_base, real_size);
 260     } else{
 261       os::release_memory(real_base, real_size);
 262     }
 263     _base = NULL;
 264     _size = 0;
 265     _noaccess_prefix = 0;
 266     _alignment = 0;
 267     _special = false;
 268     _executable = false;
 269   }
 270 }
 271 
 272 static size_t noaccess_prefix_size(size_t alignment) {
 273   return lcm(os::vm_page_size(), alignment);
 274 }
 275 
 276 void ReservedHeapSpace::establish_noaccess_prefix() {
 277   assert(_alignment >= (size_t)os::vm_page_size(), "must be at least page size big");
 278   _noaccess_prefix = noaccess_prefix_size(_alignment);
 279 
 280   if (base() && base() + _size > (char *)OopEncodingHeapMax) {
 281     if (true
 282         WIN64_ONLY(&& !UseLargePages)
 283         AIX_ONLY(&& os::vm_page_size() != SIZE_64K)) {
 284       // Protect memory at the base of the allocated region.
 285       // If special, the page was committed (only matters on windows)
 286       if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE, _special)) {
 287         fatal("cannot protect protection page");
 288       }
 289       if (PrintCompressedOopsMode) {
 290         tty->cr();
 291         tty->print_cr("Protected page at the reserved heap base: "
 292                       PTR_FORMAT " / " INTX_FORMAT " bytes", p2i(_base), _noaccess_prefix);
 293       }
 294       assert(Universe::narrow_oop_use_implicit_null_checks() == true, "not initialized?");
 295     } else {
 296       Universe::set_narrow_oop_use_implicit_null_checks(false);
 297     }
 298   }
 299 
 300   _base += _noaccess_prefix;
 301   _size -= _noaccess_prefix;
 302   assert(((uintptr_t)_base % _alignment == 0), "must be exactly of required alignment");
 303 }
 304 
 305 // Tries to allocate memory of size 'size' at address requested_address with alignment 'alignment'.
 306 // Does not check whether the reserved memory actually is at requested_address, as the memory returned
 307 // might still fulfill the wishes of the caller.
 308 // Assures the memory is aligned to 'alignment'.
 309 // NOTE: If ReservedHeapSpace already points to some reserved memory this is freed, first.
 310 void ReservedHeapSpace::try_reserve_heap(size_t size,
 311                                          size_t alignment,
 312                                          bool large,
 313                                          char* requested_address) {
 314   if (_base != NULL) {
 315     // We tried before, but we didn't like the address delivered.
 316     release();
 317   }
 318 
 319   // If OS doesn't support demand paging for large page memory, we need
 320   // to use reserve_memory_special() to reserve and pin the entire region.
 321   bool special = large && !os::can_commit_large_page_memory();
 322   char* base = NULL;
 323 
 324   if (PrintCompressedOopsMode && Verbose) {
 325     tty->print("Trying to allocate at address " PTR_FORMAT " heap of size " SIZE_FORMAT_HEX ".\n",
 326                p2i(requested_address), size);
 327   }
 328 
 329   if (special) {
 330     base = os::reserve_memory_special(size, alignment, requested_address, false);
 331 
 332     if (base != NULL) {
 333       // Check alignment constraints.
 334       assert((uintptr_t) base % alignment == 0,
 335              "Large pages returned a non-aligned address, base: "
 336              PTR_FORMAT " alignment: " SIZE_FORMAT_HEX,
 337              p2i(base), alignment);
 338       _special = true;
 339     }
 340   }
 341 
 342   if (base == NULL) {
 343     // Failed; try to reserve regular memory below
 344     if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
 345                           !FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
 346       if (PrintCompressedOopsMode) {
 347         tty->cr();
 348         tty->print_cr("Reserve regular memory without large pages.");
 349       }
 350     }
 351 
 352     // Optimistically assume that the OSes returns an aligned base pointer.
 353     // When reserving a large address range, most OSes seem to align to at
 354     // least 64K.
 355 
 356     // If the memory was requested at a particular address, use
 357     // os::attempt_reserve_memory_at() to avoid over mapping something
 358     // important.  If available space is not detected, return NULL.
 359 
 360     if (requested_address != 0) {
 361       base = os::attempt_reserve_memory_at(size, requested_address);
 362     } else {
 363       base = os::reserve_memory(size, NULL, alignment);
 364     }
 365   }
 366   if (base == NULL) { return; }
 367 
 368   // Done
 369   _base = base;
 370   _size = size;
 371   _alignment = alignment;
 372 
 373   // Check alignment constraints
 374   if ((((size_t)base) & (alignment - 1)) != 0) {
 375     // Base not aligned, retry.
 376     release();
 377   }
 378 }
 379 
 380 void ReservedHeapSpace::try_reserve_range(char *highest_start,
 381                                           char *lowest_start,
 382                                           size_t attach_point_alignment,
 383                                           char *aligned_heap_base_min_address,
 384                                           char *upper_bound,
 385                                           size_t size,
 386                                           size_t alignment,
 387                                           bool large) {
 388   const size_t attach_range = highest_start - lowest_start;
 389   // Cap num_attempts at possible number.
 390   // At least one is possible even for 0 sized attach range.
 391   const uint64_t num_attempts_possible = (attach_range / attach_point_alignment) + 1;
 392   const uint64_t num_attempts_to_try   = MIN2((uint64_t)HeapSearchSteps, num_attempts_possible);
 393 
 394   const size_t stepsize = (attach_range == 0) ? // Only one try.
 395     (size_t) highest_start : align_size_up(attach_range / num_attempts_to_try, attach_point_alignment);
 396 
 397   // Try attach points from top to bottom.
 398   char* attach_point = highest_start;
 399   while (attach_point >= lowest_start  &&
 400          attach_point <= highest_start &&  // Avoid wrap around.
 401          ((_base == NULL) ||
 402           (_base < aligned_heap_base_min_address || _base + size > upper_bound))) {
 403     try_reserve_heap(size, alignment, large, attach_point);
 404     attach_point -= stepsize;
 405   }
 406 }
 407 
 408 #define SIZE_64K  ((uint64_t) UCONST64(      0x10000))
 409 #define SIZE_256M ((uint64_t) UCONST64(   0x10000000))
 410 #define SIZE_32G  ((uint64_t) UCONST64(  0x800000000))
 411 
 412 // Helper for heap allocation. Returns an array with addresses
 413 // (OS-specific) which are suited for disjoint base mode. Array is
 414 // NULL terminated.
 415 static char** get_attach_addresses_for_disjoint_mode() {
 416   static uint64_t addresses[] = {
 417      2 * SIZE_32G,
 418      3 * SIZE_32G,
 419      4 * SIZE_32G,
 420      8 * SIZE_32G,
 421     10 * SIZE_32G,
 422      1 * SIZE_64K * SIZE_32G,
 423      2 * SIZE_64K * SIZE_32G,
 424      3 * SIZE_64K * SIZE_32G,
 425      4 * SIZE_64K * SIZE_32G,
 426     16 * SIZE_64K * SIZE_32G,
 427     32 * SIZE_64K * SIZE_32G,
 428     34 * SIZE_64K * SIZE_32G,
 429     0
 430   };
 431 
 432   // Sort out addresses smaller than HeapBaseMinAddress. This assumes
 433   // the array is sorted.
 434   uint i = 0;
 435   while (addresses[i] != 0 &&
 436          (addresses[i] < OopEncodingHeapMax || addresses[i] < HeapBaseMinAddress)) {
 437     i++;
 438   }
 439   uint start = i;
 440 
 441   // Avoid more steps than requested.
 442   i = 0;
 443   while (addresses[start+i] != 0) {
 444     if (i == HeapSearchSteps) {
 445       addresses[start+i] = 0;
 446       break;
 447     }
 448     i++;
 449   }
 450 
 451   return (char**) &addresses[start];
 452 }
 453 
 454 void ReservedHeapSpace::initialize_compressed_heap(const size_t size, size_t alignment, bool large) {
 455   guarantee(size + noaccess_prefix_size(alignment) <= OopEncodingHeapMax,
 456             "can not allocate compressed oop heap for this size");
 457   guarantee(alignment == MAX2(alignment, (size_t)os::vm_page_size()), "alignment too small");
 458   assert(HeapBaseMinAddress > 0, "sanity");
 459 
 460   const size_t granularity = os::vm_allocation_granularity();
 461   assert((size & (granularity - 1)) == 0,
 462          "size not aligned to os::vm_allocation_granularity()");
 463   assert((alignment & (granularity - 1)) == 0,
 464          "alignment not aligned to os::vm_allocation_granularity()");
 465   assert(alignment == 0 || is_power_of_2((intptr_t)alignment),
 466          "not a power of 2");
 467 
 468   // The necessary attach point alignment for generated wish addresses.
 469   // This is needed to increase the chance of attaching for mmap and shmat.
 470   const size_t os_attach_point_alignment =
 471     AIX_ONLY(SIZE_256M)  // Known shm boundary alignment.
 472     NOT_AIX(os::vm_allocation_granularity());
 473   const size_t attach_point_alignment = lcm(alignment, os_attach_point_alignment);
 474 
 475   char *aligned_heap_base_min_address = (char *)align_ptr_up((void *)HeapBaseMinAddress, alignment);
 476   size_t noaccess_prefix = ((aligned_heap_base_min_address + size) > (char*)OopEncodingHeapMax) ?
 477     noaccess_prefix_size(alignment) : 0;
 478 
 479   // Attempt to alloc at user-given address.
 480   if (!FLAG_IS_DEFAULT(HeapBaseMinAddress)) {
 481     try_reserve_heap(size + noaccess_prefix, alignment, large, aligned_heap_base_min_address);
 482     if (_base != aligned_heap_base_min_address) { // Enforce this exact address.
 483       release();
 484     }
 485   }
 486 
 487   // Keep heap at HeapBaseMinAddress.
 488   if (_base == NULL) {
 489 
 490     // Try to allocate the heap at addresses that allow efficient oop compression.
 491     // Different schemes are tried, in order of decreasing optimization potential.
 492     //
 493     // For this, try_reserve_heap() is called with the desired heap base addresses.
 494     // A call into the os layer to allocate at a given address can return memory
 495     // at a different address than requested.  Still, this might be memory at a useful
 496     // address. try_reserve_heap() always returns this allocated memory, as only here
 497     // the criteria for a good heap are checked.
 498 
 499     // Attempt to allocate so that we can run without base and scale (32-Bit unscaled compressed oops).
 500     // Give it several tries from top of range to bottom.
 501     if (aligned_heap_base_min_address + size <= (char *)UnscaledOopHeapMax) {
 502 
 503       // Calc address range within we try to attach (range of possible start addresses).
 504       char* const highest_start = (char *)align_ptr_down((char *)UnscaledOopHeapMax - size, attach_point_alignment);
 505       char* const lowest_start  = (char *)align_ptr_up(aligned_heap_base_min_address, attach_point_alignment);
 506       try_reserve_range(highest_start, lowest_start, attach_point_alignment,
 507                         aligned_heap_base_min_address, (char *)UnscaledOopHeapMax, size, alignment, large);
 508     }
 509 
 510     // zerobased: Attempt to allocate in the lower 32G.
 511     // But leave room for the compressed class pointers, which is allocated above
 512     // the heap.
 513     char *zerobased_max = (char *)OopEncodingHeapMax;
 514     const size_t class_space = align_size_up(CompressedClassSpaceSize, alignment);
 515     // For small heaps, save some space for compressed class pointer
 516     // space so it can be decoded with no base.
 517     if (UseCompressedClassPointers && !UseSharedSpaces &&
 518         OopEncodingHeapMax <= KlassEncodingMetaspaceMax &&
 519         (uint64_t)(aligned_heap_base_min_address + size + class_space) <= KlassEncodingMetaspaceMax) {
 520       zerobased_max = (char *)OopEncodingHeapMax - class_space;
 521     }
 522 
 523     // Give it several tries from top of range to bottom.
 524     if (aligned_heap_base_min_address + size <= zerobased_max &&    // Zerobased theoretical possible.
 525         ((_base == NULL) ||                        // No previous try succeeded.
 526          (_base + size > zerobased_max))) {        // Unscaled delivered an arbitrary address.
 527 
 528       // Calc address range within we try to attach (range of possible start addresses).
 529       char *const highest_start = (char *)align_ptr_down(zerobased_max - size, attach_point_alignment);
 530       // Need to be careful about size being guaranteed to be less
 531       // than UnscaledOopHeapMax due to type constraints.
 532       char *lowest_start = aligned_heap_base_min_address;
 533       uint64_t unscaled_end = UnscaledOopHeapMax - size;
 534       if (unscaled_end < UnscaledOopHeapMax) { // unscaled_end wrapped if size is large
 535         lowest_start = MAX2(lowest_start, (char*)unscaled_end);
 536       }
 537       lowest_start  = (char *)align_ptr_up(lowest_start, attach_point_alignment);
 538       try_reserve_range(highest_start, lowest_start, attach_point_alignment,
 539                         aligned_heap_base_min_address, zerobased_max, size, alignment, large);
 540     }
 541 
 542     // Now we go for heaps with base != 0.  We need a noaccess prefix to efficiently
 543     // implement null checks.
 544     noaccess_prefix = noaccess_prefix_size(alignment);
 545 
 546     // Try to attach at addresses that are aligned to OopEncodingHeapMax. Disjointbase mode.
 547     char** addresses = get_attach_addresses_for_disjoint_mode();
 548     int i = 0;
 549     while (addresses[i] &&                                 // End of array not yet reached.
 550            ((_base == NULL) ||                             // No previous try succeeded.
 551             (_base + size >  (char *)OopEncodingHeapMax && // Not zerobased or unscaled address.
 552              !Universe::is_disjoint_heap_base_address((address)_base)))) {  // Not disjoint address.
 553       char* const attach_point = addresses[i];
 554       assert(attach_point >= aligned_heap_base_min_address, "Flag support broken");
 555       try_reserve_heap(size + noaccess_prefix, alignment, large, attach_point);
 556       i++;
 557     }
 558 
 559     // Last, desperate try without any placement.
 560     if (_base == NULL) {
 561       if (PrintCompressedOopsMode && Verbose) {
 562         tty->print("Trying to allocate at address NULL heap of size " SIZE_FORMAT_HEX ".\n", size + noaccess_prefix);
 563       }
 564       initialize(size + noaccess_prefix, alignment, large, NULL, false);
 565     }
 566   }
 567 }
 568 
 569 ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment, bool large) : ReservedSpace() {
 570 
 571   if (size == 0) {
 572     return;
 573   }
 574 
 575   // Heap size should be aligned to alignment, too.
 576   guarantee(is_size_aligned(size, alignment), "set by caller");
 577 
 578   if (UseCompressedOops) {
 579     initialize_compressed_heap(size, alignment, large);
 580     if (_size > size) {
 581       // We allocated heap with noaccess prefix.
 582       // It can happen we get a zerobased/unscaled heap with noaccess prefix,
 583       // if we had to try at arbitrary address.
 584       establish_noaccess_prefix();
 585     }
 586   } else {
 587     initialize(size, alignment, large, NULL, false);
 588   }
 589 
 590   assert(markOopDesc::encode_pointer_as_mark(_base)->decode_pointer() == _base,
 591          "area must be distinguishable from marks for mark-sweep");
 592   assert(markOopDesc::encode_pointer_as_mark(&_base[size])->decode_pointer() == &_base[size],
 593          "area must be distinguishable from marks for mark-sweep");
 594 
 595   if (base() > 0) {
 596     MemTracker::record_virtual_memory_type((address)base(), mtJavaHeap);
 597   }
 598 }
 599 
 600 // Reserve space for code segment.  Same as Java heap only we mark this as
 601 // executable.
 602 ReservedCodeSpace::ReservedCodeSpace(size_t r_size,
 603                                      size_t rs_align,
 604                                      bool large) :
 605   ReservedSpace(r_size, rs_align, large, /*executable*/ CodeCacheExtensions::support_dynamic_code()) {
 606   MemTracker::record_virtual_memory_type((address)base(), mtCode);
 607 }
 608 
 609 // VirtualSpace
 610 
 611 VirtualSpace::VirtualSpace() {
 612   _low_boundary           = NULL;
 613   _high_boundary          = NULL;
 614   _low                    = NULL;
 615   _high                   = NULL;
 616   _lower_high             = NULL;
 617   _middle_high            = NULL;
 618   _upper_high             = NULL;
 619   _lower_high_boundary    = NULL;
 620   _middle_high_boundary   = NULL;
 621   _upper_high_boundary    = NULL;
 622   _lower_alignment        = 0;
 623   _middle_alignment       = 0;
 624   _upper_alignment        = 0;
 625   _special                = false;
 626   _executable             = false;
 627 }
 628 
 629 
 630 bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) {
 631   const size_t max_commit_granularity = os::page_size_for_region_unaligned(rs.size(), 1);
 632   return initialize_with_granularity(rs, committed_size, max_commit_granularity);
 633 }
 634 
 635 bool VirtualSpace::initialize_with_granularity(ReservedSpace rs, size_t committed_size, size_t max_commit_granularity) {
 636   if(!rs.is_reserved()) return false;  // allocation failed.
 637   assert(_low_boundary == NULL, "VirtualSpace already initialized");
 638   assert(max_commit_granularity > 0, "Granularity must be non-zero.");
 639 
 640   _low_boundary  = rs.base();
 641   _high_boundary = low_boundary() + rs.size();
 642 
 643   _low = low_boundary();
 644   _high = low();
 645 
 646   _special = rs.special();
 647   _executable = rs.executable();
 648 
 649   // When a VirtualSpace begins life at a large size, make all future expansion
 650   // and shrinking occur aligned to a granularity of large pages.  This avoids
 651   // fragmentation of physical addresses that inhibits the use of large pages
 652   // by the OS virtual memory system.  Empirically,  we see that with a 4MB
 653   // page size, the only spaces that get handled this way are codecache and
 654   // the heap itself, both of which provide a substantial performance
 655   // boost in many benchmarks when covered by large pages.
 656   //
 657   // No attempt is made to force large page alignment at the very top and
 658   // bottom of the space if they are not aligned so already.
 659   _lower_alignment  = os::vm_page_size();
 660   _middle_alignment = max_commit_granularity;
 661   _upper_alignment  = os::vm_page_size();
 662 
 663   // End of each region
 664   _lower_high_boundary = (char*) round_to((intptr_t) low_boundary(), middle_alignment());
 665   _middle_high_boundary = (char*) round_down((intptr_t) high_boundary(), middle_alignment());
 666   _upper_high_boundary = high_boundary();
 667 
 668   // High address of each region
 669   _lower_high = low_boundary();
 670   _middle_high = lower_high_boundary();
 671   _upper_high = middle_high_boundary();
 672 
 673   // commit to initial size
 674   if (committed_size > 0) {
 675     if (!expand_by(committed_size)) {
 676       return false;
 677     }
 678   }
 679   return true;
 680 }
 681 
 682 
 683 VirtualSpace::~VirtualSpace() {
 684   release();
 685 }
 686 
 687 
 688 void VirtualSpace::release() {
 689   // This does not release memory it never reserved.
 690   // Caller must release via rs.release();
 691   _low_boundary           = NULL;
 692   _high_boundary          = NULL;
 693   _low                    = NULL;
 694   _high                   = NULL;
 695   _lower_high             = NULL;
 696   _middle_high            = NULL;
 697   _upper_high             = NULL;
 698   _lower_high_boundary    = NULL;
 699   _middle_high_boundary   = NULL;
 700   _upper_high_boundary    = NULL;
 701   _lower_alignment        = 0;
 702   _middle_alignment       = 0;
 703   _upper_alignment        = 0;
 704   _special                = false;
 705   _executable             = false;
 706 }
 707 
 708 
 709 size_t VirtualSpace::committed_size() const {
 710   return pointer_delta(high(), low(), sizeof(char));
 711 }
 712 
 713 
 714 size_t VirtualSpace::reserved_size() const {
 715   return pointer_delta(high_boundary(), low_boundary(), sizeof(char));
 716 }
 717 
 718 
 719 size_t VirtualSpace::uncommitted_size()  const {
 720   return reserved_size() - committed_size();
 721 }
 722 
 723 size_t VirtualSpace::actual_committed_size() const {
 724   // Special VirtualSpaces commit all reserved space up front.
 725   if (special()) {
 726     return reserved_size();
 727   }
 728 
 729   size_t committed_low    = pointer_delta(_lower_high,  _low_boundary,         sizeof(char));
 730   size_t committed_middle = pointer_delta(_middle_high, _lower_high_boundary,  sizeof(char));
 731   size_t committed_high   = pointer_delta(_upper_high,  _middle_high_boundary, sizeof(char));
 732 
 733 #ifdef ASSERT
 734   size_t lower  = pointer_delta(_lower_high_boundary,  _low_boundary,         sizeof(char));
 735   size_t middle = pointer_delta(_middle_high_boundary, _lower_high_boundary,  sizeof(char));
 736   size_t upper  = pointer_delta(_upper_high_boundary,  _middle_high_boundary, sizeof(char));
 737 
 738   if (committed_high > 0) {
 739     assert(committed_low == lower, "Must be");
 740     assert(committed_middle == middle, "Must be");
 741   }
 742 
 743   if (committed_middle > 0) {
 744     assert(committed_low == lower, "Must be");
 745   }
 746   if (committed_middle < middle) {
 747     assert(committed_high == 0, "Must be");
 748   }
 749 
 750   if (committed_low < lower) {
 751     assert(committed_high == 0, "Must be");
 752     assert(committed_middle == 0, "Must be");
 753   }
 754 #endif
 755 
 756   return committed_low + committed_middle + committed_high;
 757 }
 758 
 759 
 760 bool VirtualSpace::contains(const void* p) const {
 761   return low() <= (const char*) p && (const char*) p < high();
 762 }
 763 
 764 /*
 765    First we need to determine if a particular virtual space is using large
 766    pages.  This is done at the initialize function and only virtual spaces
 767    that are larger than LargePageSizeInBytes use large pages.  Once we
 768    have determined this, all expand_by and shrink_by calls must grow and
 769    shrink by large page size chunks.  If a particular request
 770    is within the current large page, the call to commit and uncommit memory
 771    can be ignored.  In the case that the low and high boundaries of this
 772    space is not large page aligned, the pages leading to the first large
 773    page address and the pages after the last large page address must be
 774    allocated with default pages.
 775 */
 776 bool VirtualSpace::expand_by(size_t bytes, bool pre_touch) {
 777   if (uncommitted_size() < bytes) return false;
 778 
 779   if (special()) {
 780     // don't commit memory if the entire space is pinned in memory
 781     _high += bytes;
 782     return true;
 783   }
 784 
 785   char* previous_high = high();
 786   char* unaligned_new_high = high() + bytes;
 787   assert(unaligned_new_high <= high_boundary(),
 788          "cannot expand by more than upper boundary");
 789 
 790   // Calculate where the new high for each of the regions should be.  If
 791   // the low_boundary() and high_boundary() are LargePageSizeInBytes aligned
 792   // then the unaligned lower and upper new highs would be the
 793   // lower_high() and upper_high() respectively.
 794   char* unaligned_lower_new_high =
 795     MIN2(unaligned_new_high, lower_high_boundary());
 796   char* unaligned_middle_new_high =
 797     MIN2(unaligned_new_high, middle_high_boundary());
 798   char* unaligned_upper_new_high =
 799     MIN2(unaligned_new_high, upper_high_boundary());
 800 
 801   // Align the new highs based on the regions alignment.  lower and upper
 802   // alignment will always be default page size.  middle alignment will be
 803   // LargePageSizeInBytes if the actual size of the virtual space is in
 804   // fact larger than LargePageSizeInBytes.
 805   char* aligned_lower_new_high =
 806     (char*) round_to((intptr_t) unaligned_lower_new_high, lower_alignment());
 807   char* aligned_middle_new_high =
 808     (char*) round_to((intptr_t) unaligned_middle_new_high, middle_alignment());
 809   char* aligned_upper_new_high =
 810     (char*) round_to((intptr_t) unaligned_upper_new_high, upper_alignment());
 811 
 812   // Determine which regions need to grow in this expand_by call.
 813   // If you are growing in the lower region, high() must be in that
 814   // region so calculate the size based on high().  For the middle and
 815   // upper regions, determine the starting point of growth based on the
 816   // location of high().  By getting the MAX of the region's low address
 817   // (or the previous region's high address) and high(), we can tell if it
 818   // is an intra or inter region growth.
 819   size_t lower_needs = 0;
 820   if (aligned_lower_new_high > lower_high()) {
 821     lower_needs =
 822       pointer_delta(aligned_lower_new_high, lower_high(), sizeof(char));
 823   }
 824   size_t middle_needs = 0;
 825   if (aligned_middle_new_high > middle_high()) {
 826     middle_needs =
 827       pointer_delta(aligned_middle_new_high, middle_high(), sizeof(char));
 828   }
 829   size_t upper_needs = 0;
 830   if (aligned_upper_new_high > upper_high()) {
 831     upper_needs =
 832       pointer_delta(aligned_upper_new_high, upper_high(), sizeof(char));
 833   }
 834 
 835   // Check contiguity.
 836   assert(low_boundary() <= lower_high() &&
 837          lower_high() <= lower_high_boundary(),
 838          "high address must be contained within the region");
 839   assert(lower_high_boundary() <= middle_high() &&
 840          middle_high() <= middle_high_boundary(),
 841          "high address must be contained within the region");
 842   assert(middle_high_boundary() <= upper_high() &&
 843          upper_high() <= upper_high_boundary(),
 844          "high address must be contained within the region");
 845 
 846   // Commit regions
 847   if (lower_needs > 0) {
 848     assert(low_boundary() <= lower_high() &&
 849            lower_high() + lower_needs <= lower_high_boundary(),
 850            "must not expand beyond region");
 851     if (!os::commit_memory(lower_high(), lower_needs, _executable)) {
 852       debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
 853                          ", lower_needs=" SIZE_FORMAT ", %d) failed",
 854                          p2i(lower_high()), lower_needs, _executable);)
 855       return false;
 856     } else {
 857       _lower_high += lower_needs;
 858     }
 859   }
 860   if (middle_needs > 0) {
 861     assert(lower_high_boundary() <= middle_high() &&
 862            middle_high() + middle_needs <= middle_high_boundary(),
 863            "must not expand beyond region");
 864     if (!os::commit_memory(middle_high(), middle_needs, middle_alignment(),
 865                            _executable)) {
 866       debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
 867                          ", middle_needs=" SIZE_FORMAT ", " SIZE_FORMAT
 868                          ", %d) failed", p2i(middle_high()), middle_needs,
 869                          middle_alignment(), _executable);)
 870       return false;
 871     }
 872     _middle_high += middle_needs;
 873   }
 874   if (upper_needs > 0) {
 875     assert(middle_high_boundary() <= upper_high() &&
 876            upper_high() + upper_needs <= upper_high_boundary(),
 877            "must not expand beyond region");
 878     if (!os::commit_memory(upper_high(), upper_needs, _executable)) {
 879       debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
 880                          ", upper_needs=" SIZE_FORMAT ", %d) failed",
 881                          p2i(upper_high()), upper_needs, _executable);)
 882       return false;
 883     } else {
 884       _upper_high += upper_needs;
 885     }
 886   }
 887 
 888   if (pre_touch || AlwaysPreTouch) {
 889     os::pretouch_memory(previous_high, unaligned_new_high);
 890   }
 891 
 892   _high += bytes;
 893   return true;
 894 }
 895 
 896 // A page is uncommitted if the contents of the entire page is deemed unusable.
 897 // Continue to decrement the high() pointer until it reaches a page boundary
 898 // in which case that particular page can now be uncommitted.
 899 void VirtualSpace::shrink_by(size_t size) {
 900   if (committed_size() < size)
 901     fatal("Cannot shrink virtual space to negative size");
 902 
 903   if (special()) {
 904     // don't uncommit if the entire space is pinned in memory
 905     _high -= size;
 906     return;
 907   }
 908 
 909   char* unaligned_new_high = high() - size;
 910   assert(unaligned_new_high >= low_boundary(), "cannot shrink past lower boundary");
 911 
 912   // Calculate new unaligned address
 913   char* unaligned_upper_new_high =
 914     MAX2(unaligned_new_high, middle_high_boundary());
 915   char* unaligned_middle_new_high =
 916     MAX2(unaligned_new_high, lower_high_boundary());
 917   char* unaligned_lower_new_high =
 918     MAX2(unaligned_new_high, low_boundary());
 919 
 920   // Align address to region's alignment
 921   char* aligned_upper_new_high =
 922     (char*) round_to((intptr_t) unaligned_upper_new_high, upper_alignment());
 923   char* aligned_middle_new_high =
 924     (char*) round_to((intptr_t) unaligned_middle_new_high, middle_alignment());
 925   char* aligned_lower_new_high =
 926     (char*) round_to((intptr_t) unaligned_lower_new_high, lower_alignment());
 927 
 928   // Determine which regions need to shrink
 929   size_t upper_needs = 0;
 930   if (aligned_upper_new_high < upper_high()) {
 931     upper_needs =
 932       pointer_delta(upper_high(), aligned_upper_new_high, sizeof(char));
 933   }
 934   size_t middle_needs = 0;
 935   if (aligned_middle_new_high < middle_high()) {
 936     middle_needs =
 937       pointer_delta(middle_high(), aligned_middle_new_high, sizeof(char));
 938   }
 939   size_t lower_needs = 0;
 940   if (aligned_lower_new_high < lower_high()) {
 941     lower_needs =
 942       pointer_delta(lower_high(), aligned_lower_new_high, sizeof(char));
 943   }
 944 
 945   // Check contiguity.
 946   assert(middle_high_boundary() <= upper_high() &&
 947          upper_high() <= upper_high_boundary(),
 948          "high address must be contained within the region");
 949   assert(lower_high_boundary() <= middle_high() &&
 950          middle_high() <= middle_high_boundary(),
 951          "high address must be contained within the region");
 952   assert(low_boundary() <= lower_high() &&
 953          lower_high() <= lower_high_boundary(),
 954          "high address must be contained within the region");
 955 
 956   // Uncommit
 957   if (upper_needs > 0) {
 958     assert(middle_high_boundary() <= aligned_upper_new_high &&
 959            aligned_upper_new_high + upper_needs <= upper_high_boundary(),
 960            "must not shrink beyond region");
 961     if (!os::uncommit_memory(aligned_upper_new_high, upper_needs)) {
 962       debug_only(warning("os::uncommit_memory failed"));
 963       return;
 964     } else {
 965       _upper_high -= upper_needs;
 966     }
 967   }
 968   if (middle_needs > 0) {
 969     assert(lower_high_boundary() <= aligned_middle_new_high &&
 970            aligned_middle_new_high + middle_needs <= middle_high_boundary(),
 971            "must not shrink beyond region");
 972     if (!os::uncommit_memory(aligned_middle_new_high, middle_needs)) {
 973       debug_only(warning("os::uncommit_memory failed"));
 974       return;
 975     } else {
 976       _middle_high -= middle_needs;
 977     }
 978   }
 979   if (lower_needs > 0) {
 980     assert(low_boundary() <= aligned_lower_new_high &&
 981            aligned_lower_new_high + lower_needs <= lower_high_boundary(),
 982            "must not shrink beyond region");
 983     if (!os::uncommit_memory(aligned_lower_new_high, lower_needs)) {
 984       debug_only(warning("os::uncommit_memory failed"));
 985       return;
 986     } else {
 987       _lower_high -= lower_needs;
 988     }
 989   }
 990 
 991   _high -= size;
 992 }
 993 
 994 #ifndef PRODUCT
 995 void VirtualSpace::check_for_contiguity() {
 996   // Check contiguity.
 997   assert(low_boundary() <= lower_high() &&
 998          lower_high() <= lower_high_boundary(),
 999          "high address must be contained within the region");
1000   assert(lower_high_boundary() <= middle_high() &&
1001          middle_high() <= middle_high_boundary(),
1002          "high address must be contained within the region");
1003   assert(middle_high_boundary() <= upper_high() &&
1004          upper_high() <= upper_high_boundary(),
1005          "high address must be contained within the region");
1006   assert(low() >= low_boundary(), "low");
1007   assert(low_boundary() <= lower_high_boundary(), "lower high boundary");
1008   assert(upper_high_boundary() <= high_boundary(), "upper high boundary");
1009   assert(high() <= upper_high(), "upper high");
1010 }
1011 
1012 void VirtualSpace::print_on(outputStream* out) {
1013   out->print   ("Virtual space:");
1014   if (special()) out->print(" (pinned in memory)");
1015   out->cr();
1016   out->print_cr(" - committed: " SIZE_FORMAT, committed_size());
1017   out->print_cr(" - reserved:  " SIZE_FORMAT, reserved_size());
1018   out->print_cr(" - [low, high]:     [" INTPTR_FORMAT ", " INTPTR_FORMAT "]",  p2i(low()), p2i(high()));
1019   out->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]",  p2i(low_boundary()), p2i(high_boundary()));
1020 }
1021 
1022 void VirtualSpace::print() {
1023   print_on(tty);
1024 }
1025 
1026 /////////////// Unit tests ///////////////
1027 
1028 #ifndef PRODUCT
1029 
1030 #define test_log(...) \
1031   do {\
1032     if (VerboseInternalVMTests) { \
1033       tty->print_cr(__VA_ARGS__); \
1034       tty->flush(); \
1035     }\
1036   } while (false)
1037 
1038 class TestReservedSpace : AllStatic {
1039  public:
1040   static void small_page_write(void* addr, size_t size) {
1041     size_t page_size = os::vm_page_size();
1042 
1043     char* end = (char*)addr + size;
1044     for (char* p = (char*)addr; p < end; p += page_size) {
1045       *p = 1;
1046     }
1047   }
1048 
1049   static void release_memory_for_test(ReservedSpace rs) {
1050     if (rs.special()) {
1051       guarantee(os::release_memory_special(rs.base(), rs.size()), "Shouldn't fail");
1052     } else {
1053       guarantee(os::release_memory(rs.base(), rs.size()), "Shouldn't fail");
1054     }
1055   }
1056 
1057   static void test_reserved_space1(size_t size, size_t alignment) {
1058     test_log("test_reserved_space1(%p)", (void*) (uintptr_t) size);
1059 
1060     assert(is_size_aligned(size, alignment), "Incorrect input parameters");
1061 
1062     ReservedSpace rs(size,          // size
1063                      alignment,     // alignment
1064                      UseLargePages, // large
1065                      (char *)NULL); // requested_address
1066 
1067     test_log(" rs.special() == %d", rs.special());
1068 
1069     assert(rs.base() != NULL, "Must be");
1070     assert(rs.size() == size, "Must be");
1071 
1072     assert(is_ptr_aligned(rs.base(), alignment), "aligned sizes should always give aligned addresses");
1073     assert(is_size_aligned(rs.size(), alignment), "aligned sizes should always give aligned addresses");
1074 
1075     if (rs.special()) {
1076       small_page_write(rs.base(), size);
1077     }
1078 
1079     release_memory_for_test(rs);
1080   }
1081 
1082   static void test_reserved_space2(size_t size) {
1083     test_log("test_reserved_space2(%p)", (void*)(uintptr_t)size);
1084 
1085     assert(is_size_aligned(size, os::vm_allocation_granularity()), "Must be at least AG aligned");
1086 
1087     ReservedSpace rs(size);
1088 
1089     test_log(" rs.special() == %d", rs.special());
1090 
1091     assert(rs.base() != NULL, "Must be");
1092     assert(rs.size() == size, "Must be");
1093 
1094     if (rs.special()) {
1095       small_page_write(rs.base(), size);
1096     }
1097 
1098     release_memory_for_test(rs);
1099   }
1100 
1101   static void test_reserved_space3(size_t size, size_t alignment, bool maybe_large) {
1102     test_log("test_reserved_space3(%p, %p, %d)",
1103         (void*)(uintptr_t)size, (void*)(uintptr_t)alignment, maybe_large);
1104 
1105     assert(is_size_aligned(size, os::vm_allocation_granularity()), "Must be at least AG aligned");
1106     assert(is_size_aligned(size, alignment), "Must be at least aligned against alignment");
1107 
1108     bool large = maybe_large && UseLargePages && size >= os::large_page_size();
1109 
1110     ReservedSpace rs(size, alignment, large, false);
1111 
1112     test_log(" rs.special() == %d", rs.special());
1113 
1114     assert(rs.base() != NULL, "Must be");
1115     assert(rs.size() == size, "Must be");
1116 
1117     if (rs.special()) {
1118       small_page_write(rs.base(), size);
1119     }
1120 
1121     release_memory_for_test(rs);
1122   }
1123 
1124 
1125   static void test_reserved_space1() {
1126     size_t size = 2 * 1024 * 1024;
1127     size_t ag   = os::vm_allocation_granularity();
1128 
1129     test_reserved_space1(size,      ag);
1130     test_reserved_space1(size * 2,  ag);
1131     test_reserved_space1(size * 10, ag);
1132   }
1133 
1134   static void test_reserved_space2() {
1135     size_t size = 2 * 1024 * 1024;
1136     size_t ag = os::vm_allocation_granularity();
1137 
1138     test_reserved_space2(size * 1);
1139     test_reserved_space2(size * 2);
1140     test_reserved_space2(size * 10);
1141     test_reserved_space2(ag);
1142     test_reserved_space2(size - ag);
1143     test_reserved_space2(size);
1144     test_reserved_space2(size + ag);
1145     test_reserved_space2(size * 2);
1146     test_reserved_space2(size * 2 - ag);
1147     test_reserved_space2(size * 2 + ag);
1148     test_reserved_space2(size * 3);
1149     test_reserved_space2(size * 3 - ag);
1150     test_reserved_space2(size * 3 + ag);
1151     test_reserved_space2(size * 10);
1152     test_reserved_space2(size * 10 + size / 2);
1153   }
1154 
1155   static void test_reserved_space3() {
1156     size_t ag = os::vm_allocation_granularity();
1157 
1158     test_reserved_space3(ag,      ag    , false);
1159     test_reserved_space3(ag * 2,  ag    , false);
1160     test_reserved_space3(ag * 3,  ag    , false);
1161     test_reserved_space3(ag * 2,  ag * 2, false);
1162     test_reserved_space3(ag * 4,  ag * 2, false);
1163     test_reserved_space3(ag * 8,  ag * 2, false);
1164     test_reserved_space3(ag * 4,  ag * 4, false);
1165     test_reserved_space3(ag * 8,  ag * 4, false);
1166     test_reserved_space3(ag * 16, ag * 4, false);
1167 
1168     if (UseLargePages) {
1169       size_t lp = os::large_page_size();
1170 
1171       // Without large pages
1172       test_reserved_space3(lp,     ag * 4, false);
1173       test_reserved_space3(lp * 2, ag * 4, false);
1174       test_reserved_space3(lp * 4, ag * 4, false);
1175       test_reserved_space3(lp,     lp    , false);
1176       test_reserved_space3(lp * 2, lp    , false);
1177       test_reserved_space3(lp * 3, lp    , false);
1178       test_reserved_space3(lp * 2, lp * 2, false);
1179       test_reserved_space3(lp * 4, lp * 2, false);
1180       test_reserved_space3(lp * 8, lp * 2, false);
1181 
1182       // With large pages
1183       test_reserved_space3(lp, ag * 4    , true);
1184       test_reserved_space3(lp * 2, ag * 4, true);
1185       test_reserved_space3(lp * 4, ag * 4, true);
1186       test_reserved_space3(lp, lp        , true);
1187       test_reserved_space3(lp * 2, lp    , true);
1188       test_reserved_space3(lp * 3, lp    , true);
1189       test_reserved_space3(lp * 2, lp * 2, true);
1190       test_reserved_space3(lp * 4, lp * 2, true);
1191       test_reserved_space3(lp * 8, lp * 2, true);
1192     }
1193   }
1194 
1195   static void test_reserved_space() {
1196     test_reserved_space1();
1197     test_reserved_space2();
1198     test_reserved_space3();
1199   }
1200 };
1201 
1202 void TestReservedSpace_test() {
1203   TestReservedSpace::test_reserved_space();
1204 }
1205 
1206 #define assert_equals(actual, expected)  \
1207   assert(actual == expected,             \
1208          "Got " SIZE_FORMAT " expected " \
1209          SIZE_FORMAT, actual, expected);
1210 
1211 #define assert_ge(value1, value2)                  \
1212   assert(value1 >= value2,                         \
1213          "'" #value1 "': " SIZE_FORMAT " '"        \
1214          #value2 "': " SIZE_FORMAT, value1, value2);
1215 
1216 #define assert_lt(value1, value2)                  \
1217   assert(value1 < value2,                          \
1218          "'" #value1 "': " SIZE_FORMAT " '"        \
1219          #value2 "': " SIZE_FORMAT, value1, value2);
1220 
1221 
1222 class TestVirtualSpace : AllStatic {
1223   enum TestLargePages {
1224     Default,
1225     Disable,
1226     Reserve,
1227     Commit
1228   };
1229 
1230   static ReservedSpace reserve_memory(size_t reserve_size_aligned, TestLargePages mode) {
1231     switch(mode) {
1232     default:
1233     case Default:
1234     case Reserve:
1235       return ReservedSpace(reserve_size_aligned);
1236     case Disable:
1237     case Commit:
1238       return ReservedSpace(reserve_size_aligned,
1239                            os::vm_allocation_granularity(),
1240                            /* large */ false, /* exec */ false);
1241     }
1242   }
1243 
1244   static bool initialize_virtual_space(VirtualSpace& vs, ReservedSpace rs, TestLargePages mode) {
1245     switch(mode) {
1246     default:
1247     case Default:
1248     case Reserve:
1249       return vs.initialize(rs, 0);
1250     case Disable:
1251       return vs.initialize_with_granularity(rs, 0, os::vm_page_size());
1252     case Commit:
1253       return vs.initialize_with_granularity(rs, 0, os::page_size_for_region_unaligned(rs.size(), 1));
1254     }
1255   }
1256 
1257  public:
1258   static void test_virtual_space_actual_committed_space(size_t reserve_size, size_t commit_size,
1259                                                         TestLargePages mode = Default) {
1260     size_t granularity = os::vm_allocation_granularity();
1261     size_t reserve_size_aligned = align_size_up(reserve_size, granularity);
1262 
1263     ReservedSpace reserved = reserve_memory(reserve_size_aligned, mode);
1264 
1265     assert(reserved.is_reserved(), "Must be");
1266 
1267     VirtualSpace vs;
1268     bool initialized = initialize_virtual_space(vs, reserved, mode);
1269     assert(initialized, "Failed to initialize VirtualSpace");
1270 
1271     vs.expand_by(commit_size, false);
1272 
1273     if (vs.special()) {
1274       assert_equals(vs.actual_committed_size(), reserve_size_aligned);
1275     } else {
1276       assert_ge(vs.actual_committed_size(), commit_size);
1277       // Approximate the commit granularity.
1278       // Make sure that we don't commit using large pages
1279       // if large pages has been disabled for this VirtualSpace.
1280       size_t commit_granularity = (mode == Disable || !UseLargePages) ?
1281                                    os::vm_page_size() : os::large_page_size();
1282       assert_lt(vs.actual_committed_size(), commit_size + commit_granularity);
1283     }
1284 
1285     reserved.release();
1286   }
1287 
1288   static void test_virtual_space_actual_committed_space_one_large_page() {
1289     if (!UseLargePages) {
1290       return;
1291     }
1292 
1293     size_t large_page_size = os::large_page_size();
1294 
1295     ReservedSpace reserved(large_page_size, large_page_size, true, false);
1296 
1297     assert(reserved.is_reserved(), "Must be");
1298 
1299     VirtualSpace vs;
1300     bool initialized = vs.initialize(reserved, 0);
1301     assert(initialized, "Failed to initialize VirtualSpace");
1302 
1303     vs.expand_by(large_page_size, false);
1304 
1305     assert_equals(vs.actual_committed_size(), large_page_size);
1306 
1307     reserved.release();
1308   }
1309 
1310   static void test_virtual_space_actual_committed_space() {
1311     test_virtual_space_actual_committed_space(4 * K, 0);
1312     test_virtual_space_actual_committed_space(4 * K, 4 * K);
1313     test_virtual_space_actual_committed_space(8 * K, 0);
1314     test_virtual_space_actual_committed_space(8 * K, 4 * K);
1315     test_virtual_space_actual_committed_space(8 * K, 8 * K);
1316     test_virtual_space_actual_committed_space(12 * K, 0);
1317     test_virtual_space_actual_committed_space(12 * K, 4 * K);
1318     test_virtual_space_actual_committed_space(12 * K, 8 * K);
1319     test_virtual_space_actual_committed_space(12 * K, 12 * K);
1320     test_virtual_space_actual_committed_space(64 * K, 0);
1321     test_virtual_space_actual_committed_space(64 * K, 32 * K);
1322     test_virtual_space_actual_committed_space(64 * K, 64 * K);
1323     test_virtual_space_actual_committed_space(2 * M, 0);
1324     test_virtual_space_actual_committed_space(2 * M, 4 * K);
1325     test_virtual_space_actual_committed_space(2 * M, 64 * K);
1326     test_virtual_space_actual_committed_space(2 * M, 1 * M);
1327     test_virtual_space_actual_committed_space(2 * M, 2 * M);
1328     test_virtual_space_actual_committed_space(10 * M, 0);
1329     test_virtual_space_actual_committed_space(10 * M, 4 * K);
1330     test_virtual_space_actual_committed_space(10 * M, 8 * K);
1331     test_virtual_space_actual_committed_space(10 * M, 1 * M);
1332     test_virtual_space_actual_committed_space(10 * M, 2 * M);
1333     test_virtual_space_actual_committed_space(10 * M, 5 * M);
1334     test_virtual_space_actual_committed_space(10 * M, 10 * M);
1335   }
1336 
1337   static void test_virtual_space_disable_large_pages() {
1338     if (!UseLargePages) {
1339       return;
1340     }
1341     // These test cases verify that if we force VirtualSpace to disable large pages
1342     test_virtual_space_actual_committed_space(10 * M, 0, Disable);
1343     test_virtual_space_actual_committed_space(10 * M, 4 * K, Disable);
1344     test_virtual_space_actual_committed_space(10 * M, 8 * K, Disable);
1345     test_virtual_space_actual_committed_space(10 * M, 1 * M, Disable);
1346     test_virtual_space_actual_committed_space(10 * M, 2 * M, Disable);
1347     test_virtual_space_actual_committed_space(10 * M, 5 * M, Disable);
1348     test_virtual_space_actual_committed_space(10 * M, 10 * M, Disable);
1349 
1350     test_virtual_space_actual_committed_space(10 * M, 0, Reserve);
1351     test_virtual_space_actual_committed_space(10 * M, 4 * K, Reserve);
1352     test_virtual_space_actual_committed_space(10 * M, 8 * K, Reserve);
1353     test_virtual_space_actual_committed_space(10 * M, 1 * M, Reserve);
1354     test_virtual_space_actual_committed_space(10 * M, 2 * M, Reserve);
1355     test_virtual_space_actual_committed_space(10 * M, 5 * M, Reserve);
1356     test_virtual_space_actual_committed_space(10 * M, 10 * M, Reserve);
1357 
1358     test_virtual_space_actual_committed_space(10 * M, 0, Commit);
1359     test_virtual_space_actual_committed_space(10 * M, 4 * K, Commit);
1360     test_virtual_space_actual_committed_space(10 * M, 8 * K, Commit);
1361     test_virtual_space_actual_committed_space(10 * M, 1 * M, Commit);
1362     test_virtual_space_actual_committed_space(10 * M, 2 * M, Commit);
1363     test_virtual_space_actual_committed_space(10 * M, 5 * M, Commit);
1364     test_virtual_space_actual_committed_space(10 * M, 10 * M, Commit);
1365   }
1366 
1367   static void test_virtual_space() {
1368     test_virtual_space_actual_committed_space();
1369     test_virtual_space_actual_committed_space_one_large_page();
1370     test_virtual_space_disable_large_pages();
1371   }
1372 };
1373 
1374 void TestVirtualSpace_test() {
1375   TestVirtualSpace::test_virtual_space();
1376 }
1377 
1378 #endif // PRODUCT
1379 
1380 #endif