< prev index next >

src/os/linux/vm/os_linux.cpp

Print this page

        

*** 3084,3094 **** 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); --- 3084,3097 ---- 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);
*** 3539,3548 **** --- 3542,3619 ---- 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) { + + const 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("Failure to create file %s for heap", fullname); + 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.
*** 3729,3739 **** } // 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; --- 3800,3810 ---- } // 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;
*** 3749,3760 **** --- 3820,3833 ---- // 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); }
*** 3797,3806 **** --- 3870,3882 ---- 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 >