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