233 if (!os::release_memory(base, size)) fatal("os::release_memory failed"); |
233 if (!os::release_memory(base, size)) fatal("os::release_memory failed"); |
234 // Reserve size large enough to do manual alignment and |
234 // Reserve size large enough to do manual alignment and |
235 // increase size to a multiple of the desired alignment |
235 // increase size to a multiple of the desired alignment |
236 size = align_size_up(size, alignment); |
236 size = align_size_up(size, alignment); |
237 size_t extra_size = size + alignment; |
237 size_t extra_size = size + alignment; |
238 char* extra_base = os::reserve_memory(extra_size, NULL, alignment); |
238 do { |
239 if (extra_base == NULL) return; |
239 char* extra_base = os::reserve_memory(extra_size, NULL, alignment); |
240 // Do manual alignement |
240 if (extra_base == NULL) return; |
241 base = (char*) align_size_up((uintptr_t) extra_base, alignment); |
241 // Do manual alignement |
242 assert(base >= extra_base, "just checking"); |
242 base = (char*) align_size_up((uintptr_t) extra_base, alignment); |
243 // Release unused areas |
243 assert(base >= extra_base, "just checking"); |
244 size_t unused_bottom_size = base - extra_base; |
244 // Re-reserve the region at the aligned base address. |
245 size_t unused_top_size = extra_size - size - unused_bottom_size; |
245 os::release_memory(extra_base, extra_size); |
246 assert(unused_bottom_size % os::vm_allocation_granularity() == 0, |
246 base = os::reserve_memory(size, base); |
247 "size not allocation aligned"); |
247 } while (base == NULL); |
248 assert(unused_top_size % os::vm_allocation_granularity() == 0, |
|
249 "size not allocation aligned"); |
|
250 if (unused_bottom_size > 0) { |
|
251 os::release_memory(extra_base, unused_bottom_size); |
|
252 } |
|
253 if (unused_top_size > 0) { |
|
254 os::release_memory(base + size, unused_top_size); |
|
255 } |
|
256 } |
248 } |
257 } |
249 } |
258 // Done |
250 // Done |
259 _base = base; |
251 _base = base; |
260 _size = size; |
252 _size = size; |