Mercurial > hg > truffle
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"); |