提交 1040a8b7 编写于 作者: Y ysr

Merge

...@@ -29,13 +29,19 @@ ...@@ -29,13 +29,19 @@
// Defines Linux specific flags. They are not available on other platforms. // Defines Linux specific flags. They are not available on other platforms.
// //
#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \ #define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
product(bool, UseOprofile, false, \ product(bool, UseOprofile, false, \
"enable support for Oprofile profiler") \ "enable support for Oprofile profiler") \
\ \
product(bool, UseLinuxPosixThreadCPUClocks, true, \ product(bool, UseLinuxPosixThreadCPUClocks, true, \
"enable fast Linux Posix clocks where available") "enable fast Linux Posix clocks where available") \
// NB: The default value of UseLinuxPosixThreadCPUClocks may be /* NB: The default value of UseLinuxPosixThreadCPUClocks may be \
// overridden in Arguments::parse_each_vm_init_arg. overridden in Arguments::parse_each_vm_init_arg. */ \
\
product(bool, UseHugeTLBFS, false, \
"Use MAP_HUGETLB for large pages") \
\
product(bool, UseSHM, false, \
"Use SYSV shared memory for large pages")
// //
// Defines Linux-specific default values. The flags are available on all // Defines Linux-specific default values. The flags are available on all
......
...@@ -2465,16 +2465,40 @@ bool os::commit_memory(char* addr, size_t size, bool exec) { ...@@ -2465,16 +2465,40 @@ bool os::commit_memory(char* addr, size_t size, bool exec) {
return res != (uintptr_t) MAP_FAILED; return res != (uintptr_t) MAP_FAILED;
} }
// Define MAP_HUGETLB here so we can build HotSpot on old systems.
#ifndef MAP_HUGETLB
#define MAP_HUGETLB 0x40000
#endif
// Define MADV_HUGEPAGE here so we can build HotSpot on old systems.
#ifndef MADV_HUGEPAGE
#define MADV_HUGEPAGE 14
#endif
bool os::commit_memory(char* addr, size_t size, size_t alignment_hint, bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
bool exec) { bool exec) {
if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
uintptr_t res =
(uintptr_t) ::mmap(addr, size, prot,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB,
-1, 0);
return res != (uintptr_t) MAP_FAILED;
}
return commit_memory(addr, size, exec); return commit_memory(addr, size, exec);
} }
void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { } void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
// We don't check the return value: madvise(MADV_HUGEPAGE) may not
// be supported or the memory may already be backed by huge pages.
::madvise(addr, bytes, MADV_HUGEPAGE);
}
}
void os::free_memory(char *addr, size_t bytes) { void os::free_memory(char *addr, size_t bytes) {
::mmap(addr, bytes, PROT_READ | PROT_WRITE, ::madvise(addr, bytes, MADV_DONTNEED);
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
} }
void os::numa_make_global(char *addr, size_t bytes) { void os::numa_make_global(char *addr, size_t bytes) {
...@@ -2818,6 +2842,43 @@ bool os::unguard_memory(char* addr, size_t size) { ...@@ -2818,6 +2842,43 @@ bool os::unguard_memory(char* addr, size_t size) {
return linux_mprotect(addr, size, PROT_READ|PROT_WRITE); return linux_mprotect(addr, size, PROT_READ|PROT_WRITE);
} }
bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
bool result = false;
void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE,
MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
-1, 0);
if (p != (void *) -1) {
// We don't know if this really is a huge page or not.
FILE *fp = fopen("/proc/self/maps", "r");
if (fp) {
while (!feof(fp)) {
char chars[257];
long x = 0;
if (fgets(chars, sizeof(chars), fp)) {
if (sscanf(chars, "%lx-%*lx", &x) == 1
&& x == (long)p) {
if (strstr (chars, "hugepage")) {
result = true;
break;
}
}
}
}
fclose(fp);
}
munmap (p, page_size);
if (result)
return true;
}
if (warn) {
warning("HugeTLBFS is not supported by the operating system.");
}
return result;
}
/* /*
* Set the coredump_filter bits to include largepages in core dump (bit 6) * Set the coredump_filter bits to include largepages in core dump (bit 6)
* *
...@@ -2860,7 +2921,16 @@ static void set_coredump_filter(void) { ...@@ -2860,7 +2921,16 @@ static void set_coredump_filter(void) {
static size_t _large_page_size = 0; static size_t _large_page_size = 0;
bool os::large_page_init() { bool os::large_page_init() {
if (!UseLargePages) return false; if (!UseLargePages) {
UseHugeTLBFS = false;
UseSHM = false;
return false;
}
if (FLAG_IS_DEFAULT(UseHugeTLBFS) && FLAG_IS_DEFAULT(UseSHM)) {
// Our user has not expressed a preference, so we'll try both.
UseHugeTLBFS = UseSHM = true;
}
if (LargePageSizeInBytes) { if (LargePageSizeInBytes) {
_large_page_size = LargePageSizeInBytes; _large_page_size = LargePageSizeInBytes;
...@@ -2905,6 +2975,9 @@ bool os::large_page_init() { ...@@ -2905,6 +2975,9 @@ bool os::large_page_init() {
} }
} }
// print a warning if any large page related flag is specified on command line
bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
const size_t default_page_size = (size_t)Linux::page_size(); const size_t default_page_size = (size_t)Linux::page_size();
if (_large_page_size > default_page_size) { if (_large_page_size > default_page_size) {
_page_sizes[0] = _large_page_size; _page_sizes[0] = _large_page_size;
...@@ -2912,6 +2985,14 @@ bool os::large_page_init() { ...@@ -2912,6 +2985,14 @@ bool os::large_page_init() {
_page_sizes[2] = 0; _page_sizes[2] = 0;
} }
UseHugeTLBFS = UseHugeTLBFS &&
Linux::hugetlbfs_sanity_check(warn_on_failure, _large_page_size);
if (UseHugeTLBFS)
UseSHM = false;
UseLargePages = UseHugeTLBFS || UseSHM;
set_coredump_filter(); set_coredump_filter();
// Large page support is available on 2.6 or newer kernel, some vendors // Large page support is available on 2.6 or newer kernel, some vendors
...@@ -2928,7 +3009,7 @@ bool os::large_page_init() { ...@@ -2928,7 +3009,7 @@ bool os::large_page_init() {
char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) { char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
// "exec" is passed in but not used. Creating the shared image for // "exec" is passed in but not used. Creating the shared image for
// the code cache doesn't have an SHM_X executable permission to check. // the code cache doesn't have an SHM_X executable permission to check.
assert(UseLargePages, "only for large pages"); assert(UseLargePages && UseSHM, "only for SHM large pages");
key_t key = IPC_PRIVATE; key_t key = IPC_PRIVATE;
char *addr; char *addr;
...@@ -2995,16 +3076,15 @@ size_t os::large_page_size() { ...@@ -2995,16 +3076,15 @@ size_t os::large_page_size() {
return _large_page_size; return _large_page_size;
} }
// Linux does not support anonymous mmap with large page memory. The only way // HugeTLBFS allows application to commit large page memory on demand;
// to reserve large page memory without file backing is through SysV shared // with SysV SHM the entire memory region must be allocated as shared
// memory API. The entire memory region is committed and pinned upfront. // memory.
// Hopefully this will change in the future...
bool os::can_commit_large_page_memory() { bool os::can_commit_large_page_memory() {
return false; return UseHugeTLBFS;
} }
bool os::can_execute_large_page_memory() { bool os::can_execute_large_page_memory() {
return false; return UseHugeTLBFS;
} }
// Reserve memory at an arbitrary address, only if that area is // Reserve memory at an arbitrary address, only if that area is
......
...@@ -86,6 +86,9 @@ class Linux { ...@@ -86,6 +86,9 @@ class Linux {
static void rebuild_cpu_to_node_map(); static void rebuild_cpu_to_node_map();
static GrowableArray<int>* cpu_to_node() { return _cpu_to_node; } static GrowableArray<int>* cpu_to_node() { return _cpu_to_node; }
static bool hugetlbfs_sanity_check(bool warn, size_t page_size);
public: public:
static void init_thread_fpu_state(); static void init_thread_fpu_state();
static int get_fpu_control_word(); static int get_fpu_control_word();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册