1.1 --- a/src/share/vm/runtime/virtualspace.cpp Tue Jun 22 12:10:07 2010 -0700 1.2 +++ b/src/share/vm/runtime/virtualspace.cpp Wed Jun 23 09:40:11 2010 -0700 1.3 @@ -111,6 +111,35 @@ 1.4 return result; 1.5 } 1.6 1.7 +// Helper method. 1.8 +static bool failed_to_reserve_as_requested(char* base, char* requested_address, 1.9 + const size_t size, bool special) 1.10 +{ 1.11 + if (base == requested_address || requested_address == NULL) 1.12 + return false; // did not fail 1.13 + 1.14 + if (base != NULL) { 1.15 + // Different reserve address may be acceptable in other cases 1.16 + // but for compressed oops heap should be at requested address. 1.17 + assert(UseCompressedOops, "currently requested address used only for compressed oops"); 1.18 + if (PrintCompressedOopsMode) { 1.19 + tty->cr(); 1.20 + tty->print_cr("Reserved memory at not requested address: " PTR_FORMAT " vs " PTR_FORMAT, base, requested_address); 1.21 + } 1.22 + // OS ignored requested address. Try different address. 1.23 + if (special) { 1.24 + if (!os::release_memory_special(base, size)) { 1.25 + fatal("os::release_memory_special failed"); 1.26 + } 1.27 + } else { 1.28 + if (!os::release_memory(base, size)) { 1.29 + fatal("os::release_memory failed"); 1.30 + } 1.31 + } 1.32 + } 1.33 + return true; 1.34 +} 1.35 + 1.36 ReservedSpace::ReservedSpace(const size_t prefix_size, 1.37 const size_t prefix_align, 1.38 const size_t suffix_size, 1.39 @@ -129,6 +158,10 @@ 1.40 assert((suffix_align & prefix_align - 1) == 0, 1.41 "suffix_align not divisible by prefix_align"); 1.42 1.43 + // Assert that if noaccess_prefix is used, it is the same as prefix_align. 1.44 + assert(noaccess_prefix == 0 || 1.45 + noaccess_prefix == prefix_align, "noaccess prefix wrong"); 1.46 + 1.47 // Add in noaccess_prefix to prefix_size; 1.48 const size_t adjusted_prefix_size = prefix_size + noaccess_prefix; 1.49 const size_t size = adjusted_prefix_size + suffix_size; 1.50 @@ -150,15 +183,16 @@ 1.51 _noaccess_prefix = 0; 1.52 _executable = false; 1.53 1.54 - // Assert that if noaccess_prefix is used, it is the same as prefix_align. 1.55 - assert(noaccess_prefix == 0 || 1.56 - noaccess_prefix == prefix_align, "noaccess prefix wrong"); 1.57 - 1.58 // Optimistically try to reserve the exact size needed. 1.59 char* addr; 1.60 if (requested_address != 0) { 1.61 - addr = os::attempt_reserve_memory_at(size, 1.62 - requested_address-noaccess_prefix); 1.63 + requested_address -= noaccess_prefix; // adjust address 1.64 + assert(requested_address != NULL, "huge noaccess prefix?"); 1.65 + addr = os::attempt_reserve_memory_at(size, requested_address); 1.66 + if (failed_to_reserve_as_requested(addr, requested_address, size, false)) { 1.67 + // OS ignored requested address. Try different address. 1.68 + addr = NULL; 1.69 + } 1.70 } else { 1.71 addr = os::reserve_memory(size, NULL, prefix_align); 1.72 } 1.73 @@ -222,11 +256,20 @@ 1.74 bool special = large && !os::can_commit_large_page_memory(); 1.75 char* base = NULL; 1.76 1.77 + if (requested_address != 0) { 1.78 + requested_address -= noaccess_prefix; // adjust requested address 1.79 + assert(requested_address != NULL, "huge noaccess prefix?"); 1.80 + } 1.81 + 1.82 if (special) { 1.83 1.84 base = os::reserve_memory_special(size, requested_address, executable); 1.85 1.86 if (base != NULL) { 1.87 + if (failed_to_reserve_as_requested(base, requested_address, size, true)) { 1.88 + // OS ignored requested address. Try different address. 1.89 + return; 1.90 + } 1.91 // Check alignment constraints 1.92 if (alignment > 0) { 1.93 assert((uintptr_t) base % alignment == 0, 1.94 @@ -235,6 +278,13 @@ 1.95 _special = true; 1.96 } else { 1.97 // failed; try to reserve regular memory below 1.98 + if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) || 1.99 + !FLAG_IS_DEFAULT(LargePageSizeInBytes))) { 1.100 + if (PrintCompressedOopsMode) { 1.101 + tty->cr(); 1.102 + tty->print_cr("Reserve regular memory without large pages."); 1.103 + } 1.104 + } 1.105 } 1.106 } 1.107 1.108 @@ -248,8 +298,11 @@ 1.109 // important. If available space is not detected, return NULL. 1.110 1.111 if (requested_address != 0) { 1.112 - base = os::attempt_reserve_memory_at(size, 1.113 - requested_address-noaccess_prefix); 1.114 + base = os::attempt_reserve_memory_at(size, requested_address); 1.115 + if (failed_to_reserve_as_requested(base, requested_address, size, false)) { 1.116 + // OS ignored requested address. Try different address. 1.117 + base = NULL; 1.118 + } 1.119 } else { 1.120 base = os::reserve_memory(size, NULL, alignment); 1.121 } 1.122 @@ -365,7 +418,12 @@ 1.123 } 1.124 1.125 void ReservedSpace::protect_noaccess_prefix(const size_t size) { 1.126 - // If there is noaccess prefix, return. 1.127 + assert( (_noaccess_prefix != 0) == (UseCompressedOops && _base != NULL && 1.128 + (size_t(_base + _size) > OopEncodingHeapMax) && 1.129 + Universe::narrow_oop_use_implicit_null_checks()), 1.130 + "noaccess_prefix should be used only with non zero based compressed oops"); 1.131 + 1.132 + // If there is no noaccess prefix, return. 1.133 if (_noaccess_prefix == 0) return; 1.134 1.135 assert(_noaccess_prefix >= (size_t)os::vm_page_size(), 1.136 @@ -377,6 +435,10 @@ 1.137 _special)) { 1.138 fatal("cannot protect protection page"); 1.139 } 1.140 + if (PrintCompressedOopsMode) { 1.141 + tty->cr(); 1.142 + tty->print_cr("Protected page at the reserved heap base: " PTR_FORMAT " / " INTX_FORMAT " bytes", _base, _noaccess_prefix); 1.143 + } 1.144 1.145 _base += _noaccess_prefix; 1.146 _size -= _noaccess_prefix;