26 #include "incls/_virtualspace.cpp.incl" |
26 #include "incls/_virtualspace.cpp.incl" |
27 |
27 |
28 |
28 |
29 // ReservedSpace |
29 // ReservedSpace |
30 ReservedSpace::ReservedSpace(size_t size) { |
30 ReservedSpace::ReservedSpace(size_t size) { |
31 initialize(size, 0, false, NULL, 0); |
31 initialize(size, 0, false, NULL, 0, false); |
32 } |
32 } |
33 |
33 |
34 ReservedSpace::ReservedSpace(size_t size, size_t alignment, |
34 ReservedSpace::ReservedSpace(size_t size, size_t alignment, |
35 bool large, |
35 bool large, |
36 char* requested_address, |
36 char* requested_address, |
37 const size_t noaccess_prefix) { |
37 const size_t noaccess_prefix) { |
38 initialize(size+noaccess_prefix, alignment, large, requested_address, |
38 initialize(size+noaccess_prefix, alignment, large, requested_address, |
39 noaccess_prefix); |
39 noaccess_prefix, false); |
|
40 } |
|
41 |
|
42 ReservedSpace::ReservedSpace(size_t size, size_t alignment, |
|
43 bool large, |
|
44 bool executable) { |
|
45 initialize(size, alignment, large, NULL, 0, executable); |
40 } |
46 } |
41 |
47 |
42 char * |
48 char * |
43 ReservedSpace::align_reserved_region(char* addr, const size_t len, |
49 ReservedSpace::align_reserved_region(char* addr, const size_t len, |
44 const size_t prefix_size, |
50 const size_t prefix_size, |
130 // On systems where the entire region has to be reserved and committed up |
136 // On systems where the entire region has to be reserved and committed up |
131 // front, the compound alignment normally done by this method is unnecessary. |
137 // front, the compound alignment normally done by this method is unnecessary. |
132 const bool try_reserve_special = UseLargePages && |
138 const bool try_reserve_special = UseLargePages && |
133 prefix_align == os::large_page_size(); |
139 prefix_align == os::large_page_size(); |
134 if (!os::can_commit_large_page_memory() && try_reserve_special) { |
140 if (!os::can_commit_large_page_memory() && try_reserve_special) { |
135 initialize(size, prefix_align, true, requested_address, noaccess_prefix); |
141 initialize(size, prefix_align, true, requested_address, noaccess_prefix, |
|
142 false); |
136 return; |
143 return; |
137 } |
144 } |
138 |
145 |
139 _base = NULL; |
146 _base = NULL; |
140 _size = 0; |
147 _size = 0; |
141 _alignment = 0; |
148 _alignment = 0; |
142 _special = false; |
149 _special = false; |
143 _noaccess_prefix = 0; |
150 _noaccess_prefix = 0; |
|
151 _executable = false; |
144 |
152 |
145 // Assert that if noaccess_prefix is used, it is the same as prefix_align. |
153 // Assert that if noaccess_prefix is used, it is the same as prefix_align. |
146 assert(noaccess_prefix == 0 || |
154 assert(noaccess_prefix == 0 || |
147 noaccess_prefix == prefix_align, "noaccess prefix wrong"); |
155 noaccess_prefix == prefix_align, "noaccess prefix wrong"); |
148 |
156 |
187 _noaccess_prefix = noaccess_prefix; |
195 _noaccess_prefix = noaccess_prefix; |
188 } |
196 } |
189 |
197 |
190 void ReservedSpace::initialize(size_t size, size_t alignment, bool large, |
198 void ReservedSpace::initialize(size_t size, size_t alignment, bool large, |
191 char* requested_address, |
199 char* requested_address, |
192 const size_t noaccess_prefix) { |
200 const size_t noaccess_prefix, |
|
201 bool executable) { |
193 const size_t granularity = os::vm_allocation_granularity(); |
202 const size_t granularity = os::vm_allocation_granularity(); |
194 assert((size & granularity - 1) == 0, |
203 assert((size & granularity - 1) == 0, |
195 "size not aligned to os::vm_allocation_granularity()"); |
204 "size not aligned to os::vm_allocation_granularity()"); |
196 assert((alignment & granularity - 1) == 0, |
205 assert((alignment & granularity - 1) == 0, |
197 "alignment not aligned to os::vm_allocation_granularity()"); |
206 "alignment not aligned to os::vm_allocation_granularity()"); |
282 "area must be distinguisable from marks for mark-sweep"); |
292 "area must be distinguisable from marks for mark-sweep"); |
283 } |
293 } |
284 |
294 |
285 |
295 |
286 ReservedSpace::ReservedSpace(char* base, size_t size, size_t alignment, |
296 ReservedSpace::ReservedSpace(char* base, size_t size, size_t alignment, |
287 bool special) { |
297 bool special, bool executable) { |
288 assert((size % os::vm_allocation_granularity()) == 0, |
298 assert((size % os::vm_allocation_granularity()) == 0, |
289 "size not allocation aligned"); |
299 "size not allocation aligned"); |
290 _base = base; |
300 _base = base; |
291 _size = size; |
301 _size = size; |
292 _alignment = alignment; |
302 _alignment = alignment; |
293 _noaccess_prefix = 0; |
303 _noaccess_prefix = 0; |
294 _special = special; |
304 _special = special; |
|
305 _executable = executable; |
295 } |
306 } |
296 |
307 |
297 |
308 |
298 ReservedSpace ReservedSpace::first_part(size_t partition_size, size_t alignment, |
309 ReservedSpace ReservedSpace::first_part(size_t partition_size, size_t alignment, |
299 bool split, bool realloc) { |
310 bool split, bool realloc) { |
300 assert(partition_size <= size(), "partition failed"); |
311 assert(partition_size <= size(), "partition failed"); |
301 if (split) { |
312 if (split) { |
302 os::split_reserved_memory(_base, _size, partition_size, realloc); |
313 os::split_reserved_memory(base(), size(), partition_size, realloc); |
303 } |
314 } |
304 ReservedSpace result(base(), partition_size, alignment, special()); |
315 ReservedSpace result(base(), partition_size, alignment, special(), |
|
316 executable()); |
305 return result; |
317 return result; |
306 } |
318 } |
307 |
319 |
308 |
320 |
309 ReservedSpace |
321 ReservedSpace |
310 ReservedSpace::last_part(size_t partition_size, size_t alignment) { |
322 ReservedSpace::last_part(size_t partition_size, size_t alignment) { |
311 assert(partition_size <= size(), "partition failed"); |
323 assert(partition_size <= size(), "partition failed"); |
312 ReservedSpace result(base() + partition_size, size() - partition_size, |
324 ReservedSpace result(base() + partition_size, size() - partition_size, |
313 alignment, special()); |
325 alignment, special(), executable()); |
314 return result; |
326 return result; |
315 } |
327 } |
316 |
328 |
317 |
329 |
318 size_t ReservedSpace::page_align_size_up(size_t size) { |
330 size_t ReservedSpace::page_align_size_up(size_t size) { |
392 requested_address, |
405 requested_address, |
393 (UseCompressedOops && (Universe::narrow_oop_base() != NULL) && |
406 (UseCompressedOops && (Universe::narrow_oop_base() != NULL) && |
394 Universe::narrow_oop_use_implicit_null_checks()) ? |
407 Universe::narrow_oop_use_implicit_null_checks()) ? |
395 lcm(os::vm_page_size(), prefix_align) : 0) { |
408 lcm(os::vm_page_size(), prefix_align) : 0) { |
396 protect_noaccess_prefix(prefix_size+suffix_size); |
409 protect_noaccess_prefix(prefix_size+suffix_size); |
|
410 } |
|
411 |
|
412 // Reserve space for code segment. Same as Java heap only we mark this as |
|
413 // executable. |
|
414 ReservedCodeSpace::ReservedCodeSpace(size_t r_size, |
|
415 size_t rs_align, |
|
416 bool large) : |
|
417 ReservedSpace(r_size, rs_align, large, /*executable*/ true) { |
397 } |
418 } |
398 |
419 |
399 // VirtualSpace |
420 // VirtualSpace |
400 |
421 |
401 VirtualSpace::VirtualSpace() { |
422 VirtualSpace::VirtualSpace() { |
411 _upper_high_boundary = NULL; |
432 _upper_high_boundary = NULL; |
412 _lower_alignment = 0; |
433 _lower_alignment = 0; |
413 _middle_alignment = 0; |
434 _middle_alignment = 0; |
414 _upper_alignment = 0; |
435 _upper_alignment = 0; |
415 _special = false; |
436 _special = false; |
|
437 _executable = false; |
416 } |
438 } |
417 |
439 |
418 |
440 |
419 bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) { |
441 bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) { |
420 if(!rs.is_reserved()) return false; // allocation failed. |
442 if(!rs.is_reserved()) return false; // allocation failed. |
424 |
446 |
425 _low = low_boundary(); |
447 _low = low_boundary(); |
426 _high = low(); |
448 _high = low(); |
427 |
449 |
428 _special = rs.special(); |
450 _special = rs.special(); |
|
451 _executable = rs.executable(); |
429 |
452 |
430 // When a VirtualSpace begins life at a large size, make all future expansion |
453 // When a VirtualSpace begins life at a large size, make all future expansion |
431 // and shrinking occur aligned to a granularity of large pages. This avoids |
454 // and shrinking occur aligned to a granularity of large pages. This avoids |
432 // fragmentation of physical addresses that inhibits the use of large pages |
455 // fragmentation of physical addresses that inhibits the use of large pages |
433 // by the OS virtual memory system. Empirically, we see that with a 4MB |
456 // by the OS virtual memory system. Empirically, we see that with a 4MB |
481 _upper_high_boundary = NULL; |
504 _upper_high_boundary = NULL; |
482 _lower_alignment = 0; |
505 _lower_alignment = 0; |
483 _middle_alignment = 0; |
506 _middle_alignment = 0; |
484 _upper_alignment = 0; |
507 _upper_alignment = 0; |
485 _special = false; |
508 _special = false; |
|
509 _executable = false; |
486 } |
510 } |
487 |
511 |
488 |
512 |
489 size_t VirtualSpace::committed_size() const { |
513 size_t VirtualSpace::committed_size() const { |
490 return pointer_delta(high(), low(), sizeof(char)); |
514 return pointer_delta(high(), low(), sizeof(char)); |
590 // Commit regions |
614 // Commit regions |
591 if (lower_needs > 0) { |
615 if (lower_needs > 0) { |
592 assert(low_boundary() <= lower_high() && |
616 assert(low_boundary() <= lower_high() && |
593 lower_high() + lower_needs <= lower_high_boundary(), |
617 lower_high() + lower_needs <= lower_high_boundary(), |
594 "must not expand beyond region"); |
618 "must not expand beyond region"); |
595 if (!os::commit_memory(lower_high(), lower_needs)) { |
619 if (!os::commit_memory(lower_high(), lower_needs, _executable)) { |
596 debug_only(warning("os::commit_memory failed")); |
620 debug_only(warning("os::commit_memory failed")); |
597 return false; |
621 return false; |
598 } else { |
622 } else { |
599 _lower_high += lower_needs; |
623 _lower_high += lower_needs; |
600 } |
624 } |
601 } |
625 } |
602 if (middle_needs > 0) { |
626 if (middle_needs > 0) { |
603 assert(lower_high_boundary() <= middle_high() && |
627 assert(lower_high_boundary() <= middle_high() && |
604 middle_high() + middle_needs <= middle_high_boundary(), |
628 middle_high() + middle_needs <= middle_high_boundary(), |
605 "must not expand beyond region"); |
629 "must not expand beyond region"); |
606 if (!os::commit_memory(middle_high(), middle_needs, middle_alignment())) { |
630 if (!os::commit_memory(middle_high(), middle_needs, middle_alignment(), |
|
631 _executable)) { |
607 debug_only(warning("os::commit_memory failed")); |
632 debug_only(warning("os::commit_memory failed")); |
608 return false; |
633 return false; |
609 } |
634 } |
610 _middle_high += middle_needs; |
635 _middle_high += middle_needs; |
611 } |
636 } |
612 if (upper_needs > 0) { |
637 if (upper_needs > 0) { |
613 assert(middle_high_boundary() <= upper_high() && |
638 assert(middle_high_boundary() <= upper_high() && |
614 upper_high() + upper_needs <= upper_high_boundary(), |
639 upper_high() + upper_needs <= upper_high_boundary(), |
615 "must not expand beyond region"); |
640 "must not expand beyond region"); |
616 if (!os::commit_memory(upper_high(), upper_needs)) { |
641 if (!os::commit_memory(upper_high(), upper_needs, _executable)) { |
617 debug_only(warning("os::commit_memory failed")); |
642 debug_only(warning("os::commit_memory failed")); |
618 return false; |
643 return false; |
619 } else { |
644 } else { |
620 _upper_high += upper_needs; |
645 _upper_high += upper_needs; |
621 } |
646 } |