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