1.1 --- a/src/share/vm/runtime/virtualspace.cpp Fri Jul 11 01:14:44 2008 -0700 1.2 +++ b/src/share/vm/runtime/virtualspace.cpp Sat Jul 19 17:38:22 2008 -0400 1.3 @@ -28,12 +28,15 @@ 1.4 1.5 // ReservedSpace 1.6 ReservedSpace::ReservedSpace(size_t size) { 1.7 - initialize(size, 0, false, NULL); 1.8 + initialize(size, 0, false, NULL, 0); 1.9 } 1.10 1.11 ReservedSpace::ReservedSpace(size_t size, size_t alignment, 1.12 - bool large, char* requested_address) { 1.13 - initialize(size, alignment, large, requested_address); 1.14 + bool large, 1.15 + char* requested_address, 1.16 + const size_t noaccess_prefix) { 1.17 + initialize(size+noaccess_prefix, alignment, large, requested_address, 1.18 + noaccess_prefix); 1.19 } 1.20 1.21 char * 1.22 @@ -105,7 +108,8 @@ 1.23 ReservedSpace::ReservedSpace(const size_t prefix_size, 1.24 const size_t prefix_align, 1.25 const size_t suffix_size, 1.26 - const size_t suffix_align) 1.27 + const size_t suffix_align, 1.28 + const size_t noaccess_prefix) 1.29 { 1.30 assert(prefix_size != 0, "sanity"); 1.31 assert(prefix_align != 0, "sanity"); 1.32 @@ -118,12 +122,16 @@ 1.33 assert((suffix_align & prefix_align - 1) == 0, 1.34 "suffix_align not divisible by prefix_align"); 1.35 1.36 + // Add in noaccess_prefix to prefix_size; 1.37 + const size_t adjusted_prefix_size = prefix_size + noaccess_prefix; 1.38 + const size_t size = adjusted_prefix_size + suffix_size; 1.39 + 1.40 // On systems where the entire region has to be reserved and committed up 1.41 // front, the compound alignment normally done by this method is unnecessary. 1.42 const bool try_reserve_special = UseLargePages && 1.43 prefix_align == os::large_page_size(); 1.44 if (!os::can_commit_large_page_memory() && try_reserve_special) { 1.45 - initialize(prefix_size + suffix_size, prefix_align, true); 1.46 + initialize(size, prefix_align, true, NULL, noaccess_prefix); 1.47 return; 1.48 } 1.49 1.50 @@ -131,15 +139,19 @@ 1.51 _size = 0; 1.52 _alignment = 0; 1.53 _special = false; 1.54 + _noaccess_prefix = 0; 1.55 + 1.56 + // Assert that if noaccess_prefix is used, it is the same as prefix_align. 1.57 + assert(noaccess_prefix == 0 || 1.58 + noaccess_prefix == prefix_align, "noaccess prefix wrong"); 1.59 1.60 // Optimistically try to reserve the exact size needed. 1.61 - const size_t size = prefix_size + suffix_size; 1.62 char* addr = os::reserve_memory(size, NULL, prefix_align); 1.63 if (addr == NULL) return; 1.64 1.65 // Check whether the result has the needed alignment (unlikely unless 1.66 // prefix_align == suffix_align). 1.67 - const size_t ofs = size_t(addr) + prefix_size & suffix_align - 1; 1.68 + const size_t ofs = size_t(addr) + adjusted_prefix_size & suffix_align - 1; 1.69 if (ofs != 0) { 1.70 // Wrong alignment. Release, allocate more space and do manual alignment. 1.71 // 1.72 @@ -153,11 +165,11 @@ 1.73 } 1.74 1.75 const size_t extra = MAX2(ofs, suffix_align - ofs); 1.76 - addr = reserve_and_align(size + extra, prefix_size, prefix_align, 1.77 + addr = reserve_and_align(size + extra, adjusted_prefix_size, prefix_align, 1.78 suffix_size, suffix_align); 1.79 if (addr == NULL) { 1.80 // Try an even larger region. If this fails, address space is exhausted. 1.81 - addr = reserve_and_align(size + suffix_align, prefix_size, 1.82 + addr = reserve_and_align(size + suffix_align, adjusted_prefix_size, 1.83 prefix_align, suffix_size, suffix_align); 1.84 } 1.85 } 1.86 @@ -165,10 +177,12 @@ 1.87 _base = addr; 1.88 _size = size; 1.89 _alignment = prefix_align; 1.90 + _noaccess_prefix = noaccess_prefix; 1.91 } 1.92 1.93 void ReservedSpace::initialize(size_t size, size_t alignment, bool large, 1.94 - char* requested_address) { 1.95 + char* requested_address, 1.96 + const size_t noaccess_prefix) { 1.97 const size_t granularity = os::vm_allocation_granularity(); 1.98 assert((size & granularity - 1) == 0, 1.99 "size not aligned to os::vm_allocation_granularity()"); 1.100 @@ -181,6 +195,7 @@ 1.101 _size = 0; 1.102 _special = false; 1.103 _alignment = 0; 1.104 + _noaccess_prefix = 0; 1.105 if (size == 0) { 1.106 return; 1.107 } 1.108 @@ -220,7 +235,8 @@ 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, requested_address); 1.113 + base = os::attempt_reserve_memory_at(size, 1.114 + requested_address-noaccess_prefix); 1.115 } else { 1.116 base = os::reserve_memory(size, NULL, alignment); 1.117 } 1.118 @@ -259,6 +275,11 @@ 1.119 _base = base; 1.120 _size = size; 1.121 _alignment = MAX2(alignment, (size_t) os::vm_page_size()); 1.122 + _noaccess_prefix = noaccess_prefix; 1.123 + 1.124 + // Assert that if noaccess_prefix is used, it is the same as alignment. 1.125 + assert(noaccess_prefix == 0 || 1.126 + noaccess_prefix == _alignment, "noaccess prefix wrong"); 1.127 1.128 assert(markOopDesc::encode_pointer_as_mark(_base)->decode_pointer() == _base, 1.129 "area must be distinguisable from marks for mark-sweep"); 1.130 @@ -274,6 +295,7 @@ 1.131 _base = base; 1.132 _size = size; 1.133 _alignment = alignment; 1.134 + _noaccess_prefix = 0; 1.135 _special = special; 1.136 } 1.137 1.138 @@ -320,17 +342,58 @@ 1.139 1.140 void ReservedSpace::release() { 1.141 if (is_reserved()) { 1.142 + char *real_base = _base - _noaccess_prefix; 1.143 + const size_t real_size = _size + _noaccess_prefix; 1.144 if (special()) { 1.145 - os::release_memory_special(_base, _size); 1.146 + os::release_memory_special(real_base, real_size); 1.147 } else{ 1.148 - os::release_memory(_base, _size); 1.149 + os::release_memory(real_base, real_size); 1.150 } 1.151 _base = NULL; 1.152 _size = 0; 1.153 + _noaccess_prefix = 0; 1.154 _special = false; 1.155 } 1.156 } 1.157 1.158 +void ReservedSpace::protect_noaccess_prefix(const size_t size) { 1.159 + // If there is noaccess prefix, return. 1.160 + if (_noaccess_prefix == 0) return; 1.161 + 1.162 + assert(_noaccess_prefix >= (size_t)os::vm_page_size(), 1.163 + "must be at least page size big"); 1.164 + 1.165 + // Protect memory at the base of the allocated region. 1.166 + // If special, the page was committed (only matters on windows) 1.167 + if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE, 1.168 + _special)) { 1.169 + fatal("cannot protect protection page"); 1.170 + } 1.171 + 1.172 + _base += _noaccess_prefix; 1.173 + _size -= _noaccess_prefix; 1.174 + assert((size == _size) && ((uintptr_t)_base % _alignment == 0), 1.175 + "must be exactly of required size and alignment"); 1.176 +} 1.177 + 1.178 +ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment, 1.179 + bool large, char* requested_address) : 1.180 + ReservedSpace(size, alignment, large, 1.181 + requested_address, 1.182 + UseCompressedOops ? lcm(os::vm_page_size(), alignment) : 0) { 1.183 + // Only reserved space for the java heap should have a noaccess_prefix 1.184 + // if using compressed oops. 1.185 + protect_noaccess_prefix(size); 1.186 +} 1.187 + 1.188 +ReservedHeapSpace::ReservedHeapSpace(const size_t prefix_size, 1.189 + const size_t prefix_align, 1.190 + const size_t suffix_size, 1.191 + const size_t suffix_align) : 1.192 + ReservedSpace(prefix_size, prefix_align, suffix_size, suffix_align, 1.193 + UseCompressedOops ? lcm(os::vm_page_size(), prefix_align) : 0) { 1.194 + protect_noaccess_prefix(prefix_size+suffix_size); 1.195 +} 1.196 1.197 // VirtualSpace 1.198 1.199 @@ -348,6 +411,7 @@ 1.200 _lower_alignment = 0; 1.201 _middle_alignment = 0; 1.202 _upper_alignment = 0; 1.203 + _special = false; 1.204 } 1.205 1.206 1.207 @@ -402,7 +466,8 @@ 1.208 1.209 1.210 void VirtualSpace::release() { 1.211 - (void)os::release_memory(low_boundary(), reserved_size()); 1.212 + // This does not release memory it never reserved. 1.213 + // Caller must release via rs.release(); 1.214 _low_boundary = NULL; 1.215 _high_boundary = NULL; 1.216 _low = NULL;