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"); |