comparison src/share/vm/runtime/virtualspace.cpp @ 1618:5f249b390094

6947341: JVM Crash running Oracle ATG CRMDemo Summary: Missing protected page below heap with compressed oops on Linux with large pages use. Reviewed-by: never, phh, jcoomes
author kvn
date Wed, 23 Jun 2010 09:40:11 -0700
parents c18cbe5936b8
children f95d63e2154a
comparison
equal deleted inserted replaced
1617:9887b5e57f9e 1618:5f249b390094
109 #endif 109 #endif
110 110
111 return result; 111 return result;
112 } 112 }
113 113
114 // Helper method.
115 static bool failed_to_reserve_as_requested(char* base, char* requested_address,
116 const size_t size, bool special)
117 {
118 if (base == requested_address || requested_address == NULL)
119 return false; // did not fail
120
121 if (base != NULL) {
122 // Different reserve address may be acceptable in other cases
123 // but for compressed oops heap should be at requested address.
124 assert(UseCompressedOops, "currently requested address used only for compressed oops");
125 if (PrintCompressedOopsMode) {
126 tty->cr();
127 tty->print_cr("Reserved memory at not requested address: " PTR_FORMAT " vs " PTR_FORMAT, base, requested_address);
128 }
129 // OS ignored requested address. Try different address.
130 if (special) {
131 if (!os::release_memory_special(base, size)) {
132 fatal("os::release_memory_special failed");
133 }
134 } else {
135 if (!os::release_memory(base, size)) {
136 fatal("os::release_memory failed");
137 }
138 }
139 }
140 return true;
141 }
142
114 ReservedSpace::ReservedSpace(const size_t prefix_size, 143 ReservedSpace::ReservedSpace(const size_t prefix_size,
115 const size_t prefix_align, 144 const size_t prefix_align,
116 const size_t suffix_size, 145 const size_t suffix_size,
117 const size_t suffix_align, 146 const size_t suffix_align,
118 char* requested_address, 147 char* requested_address,
127 assert((suffix_size & suffix_align - 1) == 0, 156 assert((suffix_size & suffix_align - 1) == 0,
128 "suffix_size not divisible by suffix_align"); 157 "suffix_size not divisible by suffix_align");
129 assert((suffix_align & prefix_align - 1) == 0, 158 assert((suffix_align & prefix_align - 1) == 0,
130 "suffix_align not divisible by prefix_align"); 159 "suffix_align not divisible by prefix_align");
131 160
161 // Assert that if noaccess_prefix is used, it is the same as prefix_align.
162 assert(noaccess_prefix == 0 ||
163 noaccess_prefix == prefix_align, "noaccess prefix wrong");
164
132 // Add in noaccess_prefix to prefix_size; 165 // Add in noaccess_prefix to prefix_size;
133 const size_t adjusted_prefix_size = prefix_size + noaccess_prefix; 166 const size_t adjusted_prefix_size = prefix_size + noaccess_prefix;
134 const size_t size = adjusted_prefix_size + suffix_size; 167 const size_t size = adjusted_prefix_size + suffix_size;
135 168
136 // On systems where the entire region has to be reserved and committed up 169 // On systems where the entire region has to be reserved and committed up
148 _alignment = 0; 181 _alignment = 0;
149 _special = false; 182 _special = false;
150 _noaccess_prefix = 0; 183 _noaccess_prefix = 0;
151 _executable = false; 184 _executable = false;
152 185
153 // Assert that if noaccess_prefix is used, it is the same as prefix_align.
154 assert(noaccess_prefix == 0 ||
155 noaccess_prefix == prefix_align, "noaccess prefix wrong");
156
157 // Optimistically try to reserve the exact size needed. 186 // Optimistically try to reserve the exact size needed.
158 char* addr; 187 char* addr;
159 if (requested_address != 0) { 188 if (requested_address != 0) {
160 addr = os::attempt_reserve_memory_at(size, 189 requested_address -= noaccess_prefix; // adjust address
161 requested_address-noaccess_prefix); 190 assert(requested_address != NULL, "huge noaccess prefix?");
191 addr = os::attempt_reserve_memory_at(size, requested_address);
192 if (failed_to_reserve_as_requested(addr, requested_address, size, false)) {
193 // OS ignored requested address. Try different address.
194 addr = NULL;
195 }
162 } else { 196 } else {
163 addr = os::reserve_memory(size, NULL, prefix_align); 197 addr = os::reserve_memory(size, NULL, prefix_align);
164 } 198 }
165 if (addr == NULL) return; 199 if (addr == NULL) return;
166 200
220 // If OS doesn't support demand paging for large page memory, we need 254 // If OS doesn't support demand paging for large page memory, we need
221 // to use reserve_memory_special() to reserve and pin the entire region. 255 // to use reserve_memory_special() to reserve and pin the entire region.
222 bool special = large && !os::can_commit_large_page_memory(); 256 bool special = large && !os::can_commit_large_page_memory();
223 char* base = NULL; 257 char* base = NULL;
224 258
259 if (requested_address != 0) {
260 requested_address -= noaccess_prefix; // adjust requested address
261 assert(requested_address != NULL, "huge noaccess prefix?");
262 }
263
225 if (special) { 264 if (special) {
226 265
227 base = os::reserve_memory_special(size, requested_address, executable); 266 base = os::reserve_memory_special(size, requested_address, executable);
228 267
229 if (base != NULL) { 268 if (base != NULL) {
269 if (failed_to_reserve_as_requested(base, requested_address, size, true)) {
270 // OS ignored requested address. Try different address.
271 return;
272 }
230 // Check alignment constraints 273 // Check alignment constraints
231 if (alignment > 0) { 274 if (alignment > 0) {
232 assert((uintptr_t) base % alignment == 0, 275 assert((uintptr_t) base % alignment == 0,
233 "Large pages returned a non-aligned address"); 276 "Large pages returned a non-aligned address");
234 } 277 }
235 _special = true; 278 _special = true;
236 } else { 279 } else {
237 // failed; try to reserve regular memory below 280 // failed; try to reserve regular memory below
281 if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
282 !FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
283 if (PrintCompressedOopsMode) {
284 tty->cr();
285 tty->print_cr("Reserve regular memory without large pages.");
286 }
287 }
238 } 288 }
239 } 289 }
240 290
241 if (base == NULL) { 291 if (base == NULL) {
242 // Optimistically assume that the OSes returns an aligned base pointer. 292 // Optimistically assume that the OSes returns an aligned base pointer.
246 // If the memory was requested at a particular address, use 296 // If the memory was requested at a particular address, use
247 // os::attempt_reserve_memory_at() to avoid over mapping something 297 // os::attempt_reserve_memory_at() to avoid over mapping something
248 // important. If available space is not detected, return NULL. 298 // important. If available space is not detected, return NULL.
249 299
250 if (requested_address != 0) { 300 if (requested_address != 0) {
251 base = os::attempt_reserve_memory_at(size, 301 base = os::attempt_reserve_memory_at(size, requested_address);
252 requested_address-noaccess_prefix); 302 if (failed_to_reserve_as_requested(base, requested_address, size, false)) {
303 // OS ignored requested address. Try different address.
304 base = NULL;
305 }
253 } else { 306 } else {
254 base = os::reserve_memory(size, NULL, alignment); 307 base = os::reserve_memory(size, NULL, alignment);
255 } 308 }
256 309
257 if (base == NULL) return; 310 if (base == NULL) return;
363 _executable = false; 416 _executable = false;
364 } 417 }
365 } 418 }
366 419
367 void ReservedSpace::protect_noaccess_prefix(const size_t size) { 420 void ReservedSpace::protect_noaccess_prefix(const size_t size) {
368 // If there is noaccess prefix, return. 421 assert( (_noaccess_prefix != 0) == (UseCompressedOops && _base != NULL &&
422 (size_t(_base + _size) > OopEncodingHeapMax) &&
423 Universe::narrow_oop_use_implicit_null_checks()),
424 "noaccess_prefix should be used only with non zero based compressed oops");
425
426 // If there is no noaccess prefix, return.
369 if (_noaccess_prefix == 0) return; 427 if (_noaccess_prefix == 0) return;
370 428
371 assert(_noaccess_prefix >= (size_t)os::vm_page_size(), 429 assert(_noaccess_prefix >= (size_t)os::vm_page_size(),
372 "must be at least page size big"); 430 "must be at least page size big");
373 431
374 // Protect memory at the base of the allocated region. 432 // Protect memory at the base of the allocated region.
375 // If special, the page was committed (only matters on windows) 433 // If special, the page was committed (only matters on windows)
376 if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE, 434 if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE,
377 _special)) { 435 _special)) {
378 fatal("cannot protect protection page"); 436 fatal("cannot protect protection page");
437 }
438 if (PrintCompressedOopsMode) {
439 tty->cr();
440 tty->print_cr("Protected page at the reserved heap base: " PTR_FORMAT " / " INTX_FORMAT " bytes", _base, _noaccess_prefix);
379 } 441 }
380 442
381 _base += _noaccess_prefix; 443 _base += _noaccess_prefix;
382 _size -= _noaccess_prefix; 444 _size -= _noaccess_prefix;
383 assert((size == _size) && ((uintptr_t)_base % _alignment == 0), 445 assert((size == _size) && ((uintptr_t)_base % _alignment == 0),