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