mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 06:14:49 +02:00
8067785: Using AlwaysPreTouch does not always touch all pages
Reviewed-by: pliden, drwhite
This commit is contained in:
parent
7ced38a6b5
commit
66777c3399
1 changed files with 51 additions and 60 deletions
|
@ -751,6 +751,29 @@ bool VirtualSpace::contains(const void* p) const {
|
|||
return low() <= (const char*) p && (const char*) p < high();
|
||||
}
|
||||
|
||||
static void pretouch_expanded_memory(void* start, void* end) {
|
||||
assert(is_ptr_aligned(start, os::vm_page_size()), "Unexpected alignment");
|
||||
assert(is_ptr_aligned(end, os::vm_page_size()), "Unexpected alignment");
|
||||
|
||||
os::pretouch_memory(start, end);
|
||||
}
|
||||
|
||||
static bool commit_expanded(char* start, size_t size, size_t alignment, bool pre_touch, bool executable) {
|
||||
if (os::commit_memory(start, size, alignment, executable)) {
|
||||
if (pre_touch || AlwaysPreTouch) {
|
||||
pretouch_expanded_memory(start, start + size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
debug_only(warning(
|
||||
"INFO: os::commit_memory(" PTR_FORMAT ", " PTR_FORMAT
|
||||
" size=" SIZE_FORMAT ", executable=%d) failed",
|
||||
p2i(start), p2i(start + size), size, executable);)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
First we need to determine if a particular virtual space is using large
|
||||
pages. This is done at the initialize function and only virtual spaces
|
||||
|
@ -764,7 +787,9 @@ bool VirtualSpace::contains(const void* p) const {
|
|||
allocated with default pages.
|
||||
*/
|
||||
bool VirtualSpace::expand_by(size_t bytes, bool pre_touch) {
|
||||
if (uncommitted_size() < bytes) return false;
|
||||
if (uncommitted_size() < bytes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (special()) {
|
||||
// don't commit memory if the entire space is pinned in memory
|
||||
|
@ -774,30 +799,23 @@ bool VirtualSpace::expand_by(size_t bytes, bool pre_touch) {
|
|||
|
||||
char* previous_high = high();
|
||||
char* unaligned_new_high = high() + bytes;
|
||||
assert(unaligned_new_high <= high_boundary(),
|
||||
"cannot expand by more than upper boundary");
|
||||
assert(unaligned_new_high <= high_boundary(), "cannot expand by more than upper boundary");
|
||||
|
||||
// Calculate where the new high for each of the regions should be. If
|
||||
// the low_boundary() and high_boundary() are LargePageSizeInBytes aligned
|
||||
// then the unaligned lower and upper new highs would be the
|
||||
// lower_high() and upper_high() respectively.
|
||||
char* unaligned_lower_new_high =
|
||||
MIN2(unaligned_new_high, lower_high_boundary());
|
||||
char* unaligned_middle_new_high =
|
||||
MIN2(unaligned_new_high, middle_high_boundary());
|
||||
char* unaligned_upper_new_high =
|
||||
MIN2(unaligned_new_high, upper_high_boundary());
|
||||
char* unaligned_lower_new_high = MIN2(unaligned_new_high, lower_high_boundary());
|
||||
char* unaligned_middle_new_high = MIN2(unaligned_new_high, middle_high_boundary());
|
||||
char* unaligned_upper_new_high = MIN2(unaligned_new_high, upper_high_boundary());
|
||||
|
||||
// Align the new highs based on the regions alignment. lower and upper
|
||||
// alignment will always be default page size. middle alignment will be
|
||||
// LargePageSizeInBytes if the actual size of the virtual space is in
|
||||
// fact larger than LargePageSizeInBytes.
|
||||
char* aligned_lower_new_high =
|
||||
(char*) round_to((intptr_t) unaligned_lower_new_high, lower_alignment());
|
||||
char* aligned_middle_new_high =
|
||||
(char*) round_to((intptr_t) unaligned_middle_new_high, middle_alignment());
|
||||
char* aligned_upper_new_high =
|
||||
(char*) round_to((intptr_t) unaligned_upper_new_high, upper_alignment());
|
||||
char* aligned_lower_new_high = (char*) round_to((intptr_t) unaligned_lower_new_high, lower_alignment());
|
||||
char* aligned_middle_new_high = (char*) round_to((intptr_t) unaligned_middle_new_high, middle_alignment());
|
||||
char* aligned_upper_new_high = (char*) round_to((intptr_t) unaligned_upper_new_high, upper_alignment());
|
||||
|
||||
// Determine which regions need to grow in this expand_by call.
|
||||
// If you are growing in the lower region, high() must be in that
|
||||
|
@ -808,75 +826,48 @@ bool VirtualSpace::expand_by(size_t bytes, bool pre_touch) {
|
|||
// is an intra or inter region growth.
|
||||
size_t lower_needs = 0;
|
||||
if (aligned_lower_new_high > lower_high()) {
|
||||
lower_needs =
|
||||
pointer_delta(aligned_lower_new_high, lower_high(), sizeof(char));
|
||||
lower_needs = pointer_delta(aligned_lower_new_high, lower_high(), sizeof(char));
|
||||
}
|
||||
size_t middle_needs = 0;
|
||||
if (aligned_middle_new_high > middle_high()) {
|
||||
middle_needs =
|
||||
pointer_delta(aligned_middle_new_high, middle_high(), sizeof(char));
|
||||
middle_needs = pointer_delta(aligned_middle_new_high, middle_high(), sizeof(char));
|
||||
}
|
||||
size_t upper_needs = 0;
|
||||
if (aligned_upper_new_high > upper_high()) {
|
||||
upper_needs =
|
||||
pointer_delta(aligned_upper_new_high, upper_high(), sizeof(char));
|
||||
upper_needs = pointer_delta(aligned_upper_new_high, upper_high(), sizeof(char));
|
||||
}
|
||||
|
||||
// Check contiguity.
|
||||
assert(low_boundary() <= lower_high() &&
|
||||
lower_high() <= lower_high_boundary(),
|
||||
assert(low_boundary() <= lower_high() && lower_high() <= lower_high_boundary(),
|
||||
"high address must be contained within the region");
|
||||
assert(lower_high_boundary() <= middle_high() &&
|
||||
middle_high() <= middle_high_boundary(),
|
||||
assert(lower_high_boundary() <= middle_high() && middle_high() <= middle_high_boundary(),
|
||||
"high address must be contained within the region");
|
||||
assert(middle_high_boundary() <= upper_high() &&
|
||||
upper_high() <= upper_high_boundary(),
|
||||
assert(middle_high_boundary() <= upper_high() && upper_high() <= upper_high_boundary(),
|
||||
"high address must be contained within the region");
|
||||
|
||||
// Commit regions
|
||||
if (lower_needs > 0) {
|
||||
assert(low_boundary() <= lower_high() &&
|
||||
lower_high() + lower_needs <= lower_high_boundary(),
|
||||
"must not expand beyond region");
|
||||
if (!os::commit_memory(lower_high(), lower_needs, _executable)) {
|
||||
debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
|
||||
", lower_needs=" SIZE_FORMAT ", %d) failed",
|
||||
p2i(lower_high()), lower_needs, _executable);)
|
||||
assert(lower_high() + lower_needs <= lower_high_boundary(), "must not expand beyond region");
|
||||
if (!commit_expanded(lower_high(), lower_needs, _lower_alignment, pre_touch, _executable)) {
|
||||
return false;
|
||||
} else {
|
||||
_lower_high += lower_needs;
|
||||
}
|
||||
_lower_high += lower_needs;
|
||||
}
|
||||
|
||||
if (middle_needs > 0) {
|
||||
assert(lower_high_boundary() <= middle_high() &&
|
||||
middle_high() + middle_needs <= middle_high_boundary(),
|
||||
"must not expand beyond region");
|
||||
if (!os::commit_memory(middle_high(), middle_needs, middle_alignment(),
|
||||
_executable)) {
|
||||
debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
|
||||
", middle_needs=" SIZE_FORMAT ", " SIZE_FORMAT
|
||||
", %d) failed", p2i(middle_high()), middle_needs,
|
||||
middle_alignment(), _executable);)
|
||||
assert(middle_high() + middle_needs <= middle_high_boundary(), "must not expand beyond region");
|
||||
if (!commit_expanded(middle_high(), middle_needs, _middle_alignment, pre_touch, _executable)) {
|
||||
return false;
|
||||
}
|
||||
_middle_high += middle_needs;
|
||||
}
|
||||
if (upper_needs > 0) {
|
||||
assert(middle_high_boundary() <= upper_high() &&
|
||||
upper_high() + upper_needs <= upper_high_boundary(),
|
||||
"must not expand beyond region");
|
||||
if (!os::commit_memory(upper_high(), upper_needs, _executable)) {
|
||||
debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
|
||||
", upper_needs=" SIZE_FORMAT ", %d) failed",
|
||||
p2i(upper_high()), upper_needs, _executable);)
|
||||
return false;
|
||||
} else {
|
||||
_upper_high += upper_needs;
|
||||
}
|
||||
}
|
||||
|
||||
if (pre_touch || AlwaysPreTouch) {
|
||||
os::pretouch_memory(previous_high, unaligned_new_high);
|
||||
if (upper_needs > 0) {
|
||||
assert(upper_high() + upper_needs <= upper_high_boundary(), "must not expand beyond region");
|
||||
if (!commit_expanded(upper_high(), upper_needs, _upper_alignment, pre_touch, _executable)) {
|
||||
return false;
|
||||
}
|
||||
_upper_high += upper_needs;
|
||||
}
|
||||
|
||||
_high += bytes;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue