< prev index next >
src/os/linux/vm/os_linux.cpp
Print this page
*** 3109,3119 ****
static int anon_munmap(char * addr, size_t size) {
return ::munmap(addr, size) == 0;
}
char* os::pd_reserve_memory(size_t bytes, char* requested_addr,
! size_t alignment_hint) {
return anon_mmap(requested_addr, bytes, (requested_addr != NULL));
}
bool os::pd_release_memory(char* addr, size_t size) {
return anon_munmap(addr, size);
--- 3109,3122 ----
static int anon_munmap(char * addr, size_t size) {
return ::munmap(addr, size) == 0;
}
char* os::pd_reserve_memory(size_t bytes, char* requested_addr,
! size_t alignment_hint, int file_desc) {
! if (file_desc != -1) {
! return map_memory_to_file(requested_addr, bytes, file_desc);
! }
return anon_mmap(requested_addr, bytes, (requested_addr != NULL));
}
bool os::pd_release_memory(char* addr, size_t size) {
return anon_munmap(addr, size);
*** 3557,3566 ****
--- 3560,3637 ----
assert(is_ptr_aligned(addr, os::large_page_size()), "Must be");
return addr;
}
+ // Helper function to create a temp file in the given directory
+ int os::create_file_for_heap(const char* dir, size_t size) {
+
+ char name_template[] = "/jvmheap.XXXXXX";
+
+ char *fullname = (char*)alloca(strlen(dir) + sizeof(name_template));
+ (void)strcpy(fullname, dir);
+ (void)strcat(fullname, name_template);
+
+ sigset_t set, oldset;
+ sigfillset(&set);
+
+ // block all signals while we do the file operation
+ (void)sigprocmask(SIG_BLOCK, &set, &oldset);
+
+ // set the file creation mask
+ mode_t new_mask = S_IRUSR | S_IWUSR;
+ mode_t prev_umask = umask(new_mask);
+
+ // create a new file
+ int fd = mkstemp(fullname);
+
+ // reset the file creation mask
+ umask(prev_umask);
+
+ if (fd < 0) {
+ warning("Could not create file for heap");
+ return -1;
+ }
+
+ // delete the name from the filesystem. When 'fd' is closed, the file (and space) will be deleted
+ (void)unlink(fullname);
+
+ // reset the signal mask
+ (void)sigprocmask(SIG_SETMASK, &oldset, NULL);
+
+ return fd;
+ }
+
+ // Map the given address range to the provided file descriptor
+ char* os::map_memory_to_file(char* base, size_t size, int fd) {
+ assert(fd != -1, "File descriptor is not valid");
+
+ // allocate space for the file
+ if ((errno = posix_fallocate(fd, 0, (off_t)size)) != 0) {
+ vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
+ return NULL;
+ }
+
+ int prot = PROT_READ | PROT_WRITE;
+ int flags = MAP_SHARED;
+ if( base != NULL) {
+ flags |= MAP_FIXED;
+ }
+ char* addr = (char*)mmap(base, size, prot, flags, fd, 0);
+
+ if (addr == MAP_FAILED || (base != NULL && addr != base)) {
+ if (addr != MAP_FAILED) {
+ if (!pd_release_memory(addr, size)) {
+ warning("Could not release memory on unsuccessful file mapping");
+ }
+ }
+ return NULL;
+ }
+
+ return addr;
+ }
+
// Reserve memory using mmap(MAP_HUGETLB).
// - bytes shall be a multiple of alignment.
// - req_addr can be NULL. If not NULL, it must be a multiple of alignment.
// - alignment sets the alignment at which memory shall be allocated.
// It must be a multiple of allocation granularity.
*** 3747,3757 ****
}
// Reserve memory at an arbitrary address, only if that area is
// available (and not reserved for something else).
! char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
const int max_tries = 10;
char* base[max_tries];
size_t size[max_tries];
const size_t gap = 0x000000;
--- 3818,3828 ----
}
// Reserve memory at an arbitrary address, only if that area is
// available (and not reserved for something else).
! char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr, int file_desc) {
const int max_tries = 10;
char* base[max_tries];
size_t size[max_tries];
const size_t gap = 0x000000;
*** 3767,3778 ****
--- 3838,3851 ----
// Linux mmap allows caller to pass an address as hint; give it a try first,
// if kernel honors the hint then we can return immediately.
char * addr = anon_mmap(requested_addr, bytes, false);
if (addr == requested_addr) {
+ if (file_desc == -1 || map_memory_to_file(requested_addr, bytes, file_desc) != NULL) {
return requested_addr;
}
+ }
if (addr != NULL) {
// mmap() is successful but it fails to reserve at the requested address
anon_munmap(addr, bytes);
}
*** 3815,3824 ****
--- 3888,3900 ----
unmap_memory(base[j], size[j]);
}
}
if (i < max_tries) {
+ if (file_desc != -1 && map_memory_to_file(requested_addr, bytes, file_desc) == NULL) {
+ vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
+ }
return requested_addr;
} else {
return NULL;
}
}
< prev index next >