--- old/src/os/linux/vm/os_linux.cpp 2016-05-24 12:11:19.370088500 -0700 +++ new/src/os/linux/vm/os_linux.cpp 2016-05-24 12:11:19.171560800 -0700 @@ -3466,6 +3466,72 @@ } +// Helper function to create a temp file in the given directory +int os::Linux::create_tmpfile(const char* dir, size_t size, bool exec) { + + static char name_template[] = "/jvmheap.XXXXXX"; + + char fullname[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 = exec ? (S_IRUSR | S_IWUSR | S_IXUSR) : (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); + + // allocate space for the file + if ((errno = posix_fallocate(fd, 0, (off_t)size)) != 0) { + warning("Could not allocate sufficient disk space for heap"); + return -1; + } + + return fd; +} + +// Map the given address range to a temporary file created at the specified directory. +// The address range must already be reserved for guaranteed success. If it not reserved, their could be an error while mapping leading to JVM shutdown +bool os::map_memory_to_file(char* base, size_t size, const char* backingFileDir) { + + int fd = os::Linux::create_tmpfile(backingFileDir, size, false); + if (fd == -1) { + vm_exit_during_initialization(err_msg("Could not create temporary file in %s for object heap", backingFileDir)); + return false; + } + int prot = PROT_READ | PROT_WRITE; + char* addr = (char*)mmap(base, size, prot, MAP_SHARED | MAP_FIXED, fd, 0); + + if (addr == MAP_FAILED || addr != base) { + close(fd); + vm_exit_during_initialization(err_msg("Error in mapping object heap at the given filesystem dir %s", backingFileDir)); + return false; + } + + return true; +} + // 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.