comparison src/share/vm/runtime/virtualspace.cpp @ 3824:6aa4feb8a366

7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking Summary: Align the reserved size of the heap and perm to the heap region size to get a preferred heap base that is aligned to the region size, and call the correct heap reservation constructor. Also add a check in the heap reservation code that the reserved space starts at the requested address (if any). Reviewed-by: kvn, ysr
author johnc
date Tue, 02 Aug 2011 12:13:13 -0700
parents f95d63e2154a
children f08d439fab8c
comparison
equal deleted inserted replaced
3823:14a2fd14c0db 3824:6aa4feb8a366
1 /* 1 /*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
66 assert(addr != NULL, "sanity"); 66 assert(addr != NULL, "sanity");
67 const size_t required_size = prefix_size + suffix_size; 67 const size_t required_size = prefix_size + suffix_size;
68 assert(len >= required_size, "len too small"); 68 assert(len >= required_size, "len too small");
69 69
70 const size_t s = size_t(addr); 70 const size_t s = size_t(addr);
71 const size_t beg_ofs = s + prefix_size & suffix_align - 1; 71 const size_t beg_ofs = (s + prefix_size) & (suffix_align - 1);
72 const size_t beg_delta = beg_ofs == 0 ? 0 : suffix_align - beg_ofs; 72 const size_t beg_delta = beg_ofs == 0 ? 0 : suffix_align - beg_ofs;
73 73
74 if (len < beg_delta + required_size) { 74 if (len < beg_delta + required_size) {
75 return NULL; // Cannot do proper alignment. 75 return NULL; // Cannot do proper alignment.
76 } 76 }
111 const size_t raw = size_t(raw_addr); 111 const size_t raw = size_t(raw_addr);
112 const size_t res = size_t(result); 112 const size_t res = size_t(result);
113 assert(res >= raw, "alignment decreased start addr"); 113 assert(res >= raw, "alignment decreased start addr");
114 assert(res + prefix_size + suffix_size <= raw + reserve_size, 114 assert(res + prefix_size + suffix_size <= raw + reserve_size,
115 "alignment increased end addr"); 115 "alignment increased end addr");
116 assert((res & prefix_align - 1) == 0, "bad alignment of prefix"); 116 assert((res & (prefix_align - 1)) == 0, "bad alignment of prefix");
117 assert((res + prefix_size & suffix_align - 1) == 0, 117 assert(((res + prefix_size) & (suffix_align - 1)) == 0,
118 "bad alignment of suffix"); 118 "bad alignment of suffix");
119 } 119 }
120 #endif 120 #endif
121 121
122 return result; 122 return result;
133 // Different reserve address may be acceptable in other cases 133 // Different reserve address may be acceptable in other cases
134 // but for compressed oops heap should be at requested address. 134 // but for compressed oops heap should be at requested address.
135 assert(UseCompressedOops, "currently requested address used only for compressed oops"); 135 assert(UseCompressedOops, "currently requested address used only for compressed oops");
136 if (PrintCompressedOopsMode) { 136 if (PrintCompressedOopsMode) {
137 tty->cr(); 137 tty->cr();
138 tty->print_cr("Reserved memory at not requested address: " PTR_FORMAT " vs " PTR_FORMAT, base, requested_address); 138 tty->print_cr("Reserved memory not at requested address: " PTR_FORMAT " vs " PTR_FORMAT, base, requested_address);
139 } 139 }
140 // OS ignored requested address. Try different address. 140 // OS ignored requested address. Try different address.
141 if (special) { 141 if (special) {
142 if (!os::release_memory_special(base, size)) { 142 if (!os::release_memory_special(base, size)) {
143 fatal("os::release_memory_special failed"); 143 fatal("os::release_memory_special failed");
160 { 160 {
161 assert(prefix_size != 0, "sanity"); 161 assert(prefix_size != 0, "sanity");
162 assert(prefix_align != 0, "sanity"); 162 assert(prefix_align != 0, "sanity");
163 assert(suffix_size != 0, "sanity"); 163 assert(suffix_size != 0, "sanity");
164 assert(suffix_align != 0, "sanity"); 164 assert(suffix_align != 0, "sanity");
165 assert((prefix_size & prefix_align - 1) == 0, 165 assert((prefix_size & (prefix_align - 1)) == 0,
166 "prefix_size not divisible by prefix_align"); 166 "prefix_size not divisible by prefix_align");
167 assert((suffix_size & suffix_align - 1) == 0, 167 assert((suffix_size & (suffix_align - 1)) == 0,
168 "suffix_size not divisible by suffix_align"); 168 "suffix_size not divisible by suffix_align");
169 assert((suffix_align & prefix_align - 1) == 0, 169 assert((suffix_align & (prefix_align - 1)) == 0,
170 "suffix_align not divisible by prefix_align"); 170 "suffix_align not divisible by prefix_align");
171 171
172 // Assert that if noaccess_prefix is used, it is the same as prefix_align. 172 // Assert that if noaccess_prefix is used, it is the same as prefix_align.
173 assert(noaccess_prefix == 0 || 173 assert(noaccess_prefix == 0 ||
174 noaccess_prefix == prefix_align, "noaccess prefix wrong"); 174 noaccess_prefix == prefix_align, "noaccess prefix wrong");
208 addr = os::reserve_memory(size, NULL, prefix_align); 208 addr = os::reserve_memory(size, NULL, prefix_align);
209 } 209 }
210 if (addr == NULL) return; 210 if (addr == NULL) return;
211 211
212 // Check whether the result has the needed alignment (unlikely unless 212 // Check whether the result has the needed alignment (unlikely unless
213 // prefix_align == suffix_align). 213 // prefix_align < suffix_align).
214 const size_t ofs = size_t(addr) + adjusted_prefix_size & suffix_align - 1; 214 const size_t ofs = (size_t(addr) + adjusted_prefix_size) & (suffix_align - 1);
215 if (ofs != 0) { 215 if (ofs != 0) {
216 // Wrong alignment. Release, allocate more space and do manual alignment. 216 // Wrong alignment. Release, allocate more space and do manual alignment.
217 // 217 //
218 // On most operating systems, another allocation with a somewhat larger size 218 // On most operating systems, another allocation with a somewhat larger size
219 // will return an address "close to" that of the previous allocation. The 219 // will return an address "close to" that of the previous allocation. The
230 if (addr == NULL) { 230 if (addr == NULL) {
231 // Try an even larger region. If this fails, address space is exhausted. 231 // Try an even larger region. If this fails, address space is exhausted.
232 addr = reserve_and_align(size + suffix_align, adjusted_prefix_size, 232 addr = reserve_and_align(size + suffix_align, adjusted_prefix_size,
233 prefix_align, suffix_size, suffix_align); 233 prefix_align, suffix_size, suffix_align);
234 } 234 }
235
236 if (requested_address != 0 &&
237 failed_to_reserve_as_requested(addr, requested_address, size, false)) {
238 // As a result of the alignment constraints, the allocated addr differs
239 // from the requested address. Return back to the caller who can
240 // take remedial action (like try again without a requested address).
241 assert(_base == NULL, "should be");
242 return;
243 }
235 } 244 }
236 245
237 _base = addr; 246 _base = addr;
238 _size = size; 247 _size = size;
239 _alignment = prefix_align; 248 _alignment = prefix_align;
243 void ReservedSpace::initialize(size_t size, size_t alignment, bool large, 252 void ReservedSpace::initialize(size_t size, size_t alignment, bool large,
244 char* requested_address, 253 char* requested_address,
245 const size_t noaccess_prefix, 254 const size_t noaccess_prefix,
246 bool executable) { 255 bool executable) {
247 const size_t granularity = os::vm_allocation_granularity(); 256 const size_t granularity = os::vm_allocation_granularity();
248 assert((size & granularity - 1) == 0, 257 assert((size & (granularity - 1)) == 0,
249 "size not aligned to os::vm_allocation_granularity()"); 258 "size not aligned to os::vm_allocation_granularity()");
250 assert((alignment & granularity - 1) == 0, 259 assert((alignment & (granularity - 1)) == 0,
251 "alignment not aligned to os::vm_allocation_granularity()"); 260 "alignment not aligned to os::vm_allocation_granularity()");
252 assert(alignment == 0 || is_power_of_2((intptr_t)alignment), 261 assert(alignment == 0 || is_power_of_2((intptr_t)alignment),
253 "not a power of 2"); 262 "not a power of 2");
263
264 alignment = MAX2(alignment, (size_t)os::vm_page_size());
265
266 // Assert that if noaccess_prefix is used, it is the same as alignment.
267 assert(noaccess_prefix == 0 ||
268 noaccess_prefix == alignment, "noaccess prefix wrong");
254 269
255 _base = NULL; 270 _base = NULL;
256 _size = 0; 271 _size = 0;
257 _special = false; 272 _special = false;
258 _executable = executable; 273 _executable = executable;
280 if (failed_to_reserve_as_requested(base, requested_address, size, true)) { 295 if (failed_to_reserve_as_requested(base, requested_address, size, true)) {
281 // OS ignored requested address. Try different address. 296 // OS ignored requested address. Try different address.
282 return; 297 return;
283 } 298 }
284 // Check alignment constraints 299 // Check alignment constraints
285 if (alignment > 0) { 300 assert((uintptr_t) base % alignment == 0,
286 assert((uintptr_t) base % alignment == 0, 301 "Large pages returned a non-aligned address");
287 "Large pages returned a non-aligned address");
288 }
289 _special = true; 302 _special = true;
290 } else { 303 } else {
291 // failed; try to reserve regular memory below 304 // failed; try to reserve regular memory below
292 if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) || 305 if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
293 !FLAG_IS_DEFAULT(LargePageSizeInBytes))) { 306 !FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
319 } 332 }
320 333
321 if (base == NULL) return; 334 if (base == NULL) return;
322 335
323 // Check alignment constraints 336 // Check alignment constraints
324 if (alignment > 0 && ((size_t)base & alignment - 1) != 0) { 337 if ((((size_t)base + noaccess_prefix) & (alignment - 1)) != 0) {
325 // Base not aligned, retry 338 // Base not aligned, retry
326 if (!os::release_memory(base, size)) fatal("os::release_memory failed"); 339 if (!os::release_memory(base, size)) fatal("os::release_memory failed");
327 // Reserve size large enough to do manual alignment and 340 // Reserve size large enough to do manual alignment and
328 // increase size to a multiple of the desired alignment 341 // increase size to a multiple of the desired alignment
329 size = align_size_up(size, alignment); 342 size = align_size_up(size, alignment);
336 assert(base >= extra_base, "just checking"); 349 assert(base >= extra_base, "just checking");
337 // Re-reserve the region at the aligned base address. 350 // Re-reserve the region at the aligned base address.
338 os::release_memory(extra_base, extra_size); 351 os::release_memory(extra_base, extra_size);
339 base = os::reserve_memory(size, base); 352 base = os::reserve_memory(size, base);
340 } while (base == NULL); 353 } while (base == NULL);
354
355 if (requested_address != 0 &&
356 failed_to_reserve_as_requested(base, requested_address, size, false)) {
357 // As a result of the alignment constraints, the allocated base differs
358 // from the requested address. Return back to the caller who can
359 // take remedial action (like try again without a requested address).
360 assert(_base == NULL, "should be");
361 return;
362 }
341 } 363 }
342 } 364 }
343 // Done 365 // Done
344 _base = base; 366 _base = base;
345 _size = size; 367 _size = size;
346 _alignment = MAX2(alignment, (size_t) os::vm_page_size()); 368 _alignment = alignment;
347 _noaccess_prefix = noaccess_prefix; 369 _noaccess_prefix = noaccess_prefix;
348 370
349 // Assert that if noaccess_prefix is used, it is the same as alignment. 371 // Assert that if noaccess_prefix is used, it is the same as alignment.
350 assert(noaccess_prefix == 0 || 372 assert(noaccess_prefix == 0 ||
351 noaccess_prefix == _alignment, "noaccess prefix wrong"); 373 noaccess_prefix == _alignment, "noaccess prefix wrong");