-
Notifications
You must be signed in to change notification settings - Fork 18
Hotspot should support multiple large page sizes on Windows #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3123,7 +3123,7 @@ class NUMANodeListHolder { | |
|
|
||
| static size_t _large_page_size = 0; | ||
|
|
||
| static bool request_lock_memory_privilege() { | ||
| bool os::win32::request_lock_memory_privilege() { | ||
| HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, | ||
| os::current_process_id()); | ||
|
|
||
|
|
@@ -3307,14 +3307,15 @@ static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags, | |
| return p_buf; | ||
| } | ||
|
|
||
| static size_t large_page_init_decide_size() { | ||
| size_t os::win32::large_page_init_decide_size() { | ||
| // print a warning if any large page related flag is specified on command line | ||
| bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) || | ||
| !FLAG_IS_DEFAULT(LargePageSizeInBytes); | ||
|
|
||
| #define WARN(msg) if (warn_on_failure) { warning(msg); } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. make the macro to allow variable parameters There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i made this change in upstream PR openjdk#20758 |
||
| #define WARN1(msg,p) if (warn_on_failure) { warning(msg,p); } | ||
|
|
||
| if (!request_lock_memory_privilege()) { | ||
| if (!os::win32::request_lock_memory_privilege()) { | ||
| WARN("JVM cannot use large page memory because it does not have enough privilege to lock pages in memory."); | ||
| return 0; | ||
| } | ||
|
|
@@ -3324,19 +3325,35 @@ static size_t large_page_init_decide_size() { | |
| WARN("Large page is not supported by the processor."); | ||
| return 0; | ||
| } | ||
|
|
||
| #if defined(IA32) || defined(AMD64) | ||
| if (size > 4*M || LargePageSizeInBytes > 4*M) { | ||
| WARN("JVM cannot use large pages bigger than 4mb."); | ||
| return 0; | ||
| } | ||
| #if defined(IA32) | ||
| if (size > 4 * M || LargePageSizeInBytes > 4 * M) { | ||
| WARN("JVM cannot use large pages bigger than 4mb."); | ||
| return 0; | ||
| } | ||
| #elif defined(AMD64) | ||
| if (!EnableAllLargePageSizesForWindows) { | ||
| if (size > 4 * M || LargePageSizeInBytes > 4 * M) { | ||
| WARN("JVM cannot use large pages bigger than 4mb."); | ||
| return 0; | ||
| } | ||
| } | ||
| #endif | ||
|
|
||
| if (LargePageSizeInBytes > 0 && LargePageSizeInBytes % size == 0) { | ||
| size = LargePageSizeInBytes; | ||
| if (LargePageSizeInBytes > 0) { | ||
| if (LargePageSizeInBytes % size == 0) { | ||
| size = LargePageSizeInBytes; | ||
| } else { | ||
| char buffer[256]; | ||
| snprintf(buffer, sizeof(buffer), "The specified large page size (%d) is not a multiple of the minimum large page size (%d), defaulting to minimum page size.", LargePageSizeInBytes, size); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use macro WARN after making it to accept variable parameters. |
||
| WARN1("%s", buffer); | ||
| } | ||
| } else { | ||
| char buffer[256]; | ||
| snprintf(buffer, sizeof(buffer), "The JVM cannot use large pages because the large page size setting is not configured, defaulting to minimum page size (%d).", size); | ||
| WARN1("%s", buffer); | ||
| } | ||
|
|
||
| #undef WARN | ||
| #undef WARN1 | ||
|
|
||
| return size; | ||
| } | ||
|
|
@@ -3346,12 +3363,23 @@ void os::large_page_init() { | |
| return; | ||
| } | ||
|
|
||
| _large_page_size = large_page_init_decide_size(); | ||
| _large_page_size = os::win32::large_page_init_decide_size(); | ||
| const size_t default_page_size = os::vm_page_size(); | ||
| if (_large_page_size > default_page_size) { | ||
| #if !defined(IA32) | ||
| if (EnableAllLargePageSizesForWindows) { | ||
| size_t min_size = GetLargePageMinimum(); | ||
|
|
||
| // Populate _page_sizes with large page sizes less than or equal to _large_page_size, ensuring each page size is double the size of the previous one. | ||
| for (size_t page_size = min_size; page_size < _large_page_size; page_size *= 2) { | ||
| _page_sizes.add(page_size); | ||
| } | ||
| } | ||
| #endif | ||
|
|
||
| _page_sizes.add(_large_page_size); | ||
| } | ||
|
|
||
| // Set UseLargePages based on whether a large page size was successfully determined | ||
| UseLargePages = _large_page_size != 0; | ||
| } | ||
|
|
||
|
|
@@ -3612,10 +3640,8 @@ static char* reserve_large_pages_aligned(size_t size, size_t alignment, bool exe | |
| return nullptr; | ||
| } | ||
|
|
||
| char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_size, char* addr, | ||
| bool exec) { | ||
| char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_size, char* addr, bool exec) { | ||
| assert(UseLargePages, "only for large pages"); | ||
| assert(page_size == os::large_page_size(), "Currently only support one large page size on Windows"); | ||
| assert(is_aligned(addr, alignment), "Must be"); | ||
| assert(is_aligned(addr, page_size), "Must be"); | ||
|
|
||
|
|
@@ -3624,11 +3650,17 @@ char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_ | |
| return nullptr; | ||
| } | ||
|
|
||
| // Ensure GetLargePageMinimum() returns a valid positive value | ||
| size_t large_page_min = GetLargePageMinimum(); | ||
| if (large_page_min <= 0) { | ||
| return nullptr; | ||
| } | ||
|
|
||
| // The requested alignment can be larger than the page size, for example with G1 | ||
| // the alignment is bound to the heap region size. So this reservation needs to | ||
| // ensure that the requested alignment is met. When there is a requested address | ||
| // this solves it self, since it must be properly aligned already. | ||
| if (addr == nullptr && alignment > page_size) { | ||
| if (addr == nullptr && alignment > large_page_min) { | ||
| return reserve_large_pages_aligned(bytes, alignment, exec); | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.