rev 8049 : imported patch 8058354-stefank-review

   1 /*
   2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "oops/markOop.hpp"
  27 #include "oops/oop.inline.hpp"
  28 #include "runtime/virtualspace.hpp"
  29 #include "services/memTracker.hpp"
  30 
  31 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  32 
  33 // ReservedSpace
  34 
  35 // Dummy constructor
  36 ReservedSpace::ReservedSpace() : _base(NULL), _size(0), _noaccess_prefix(0),
  37     _alignment(0), _special(false), _executable(false) {
  38 }
  39 
  40 ReservedSpace::ReservedSpace(size_t size) {
  41   // Want to use large pages where possible and pad with small pages.
  42   size_t page_size = os::page_size_for_region_unaligned(size, 1);
  43   bool large_pages = page_size != (size_t)os::vm_page_size();







  44   // Don't force the alignment to be large page aligned,
  45   // since that will waste memory.
  46   size_t alignment = os::vm_allocation_granularity();

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