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), |