< prev index next >

src/os/linux/vm/os_linux.cpp

Print this page




3541                                                         bool exec) {
3542   assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages");
3543   assert(is_size_aligned(bytes, os::large_page_size()), "Unaligned size");
3544   assert(is_ptr_aligned(req_addr, os::large_page_size()), "Unaligned address");
3545 
3546   int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
3547   char* addr = (char*)::mmap(req_addr, bytes, prot,
3548                              MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB,
3549                              -1, 0);
3550 
3551   if (addr == MAP_FAILED) {
3552     warn_on_large_pages_failure(req_addr, bytes, errno);
3553     return NULL;
3554   }
3555 
3556   assert(is_ptr_aligned(addr, os::large_page_size()), "Must be");
3557 
3558   return addr;
3559 }
3560 


































































3561 // Reserve memory using mmap(MAP_HUGETLB).
3562 //  - bytes shall be a multiple of alignment.
3563 //  - req_addr can be NULL. If not NULL, it must be a multiple of alignment.
3564 //  - alignment sets the alignment at which memory shall be allocated.
3565 //     It must be a multiple of allocation granularity.
3566 // Returns address of memory or NULL. If req_addr was not NULL, will only return
3567 //  req_addr or NULL.
3568 char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes,
3569                                                          size_t alignment,
3570                                                          char* req_addr,
3571                                                          bool exec) {
3572   size_t large_page_size = os::large_page_size();
3573   assert(bytes >= large_page_size, "Shouldn't allocate large pages for small sizes");
3574 
3575   assert(is_ptr_aligned(req_addr, alignment), "Must be");
3576   assert(is_size_aligned(bytes, alignment), "Must be");
3577 
3578   // First reserve - but not commit - the address range in small pages.
3579   char* const start = anon_mmap_aligned(bytes, alignment, req_addr);
3580 




3541                                                         bool exec) {
3542   assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages");
3543   assert(is_size_aligned(bytes, os::large_page_size()), "Unaligned size");
3544   assert(is_ptr_aligned(req_addr, os::large_page_size()), "Unaligned address");
3545 
3546   int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
3547   char* addr = (char*)::mmap(req_addr, bytes, prot,
3548                              MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB,
3549                              -1, 0);
3550 
3551   if (addr == MAP_FAILED) {
3552     warn_on_large_pages_failure(req_addr, bytes, errno);
3553     return NULL;
3554   }
3555 
3556   assert(is_ptr_aligned(addr, os::large_page_size()), "Must be");
3557 
3558   return addr;
3559 }
3560 
3561 // Helper function to create a temp file in the given directory
3562 int os::create_tmpfile(const char* dir, size_t size, bool exec) {
3563 
3564   char name_template[] = "/jvmheap.XXXXXX";
3565 
3566   char *fullname = (char*)alloca(strlen(dir) + sizeof(name_template));
3567   (void)strcpy(fullname, dir);
3568   (void)strcat(fullname, name_template);
3569 
3570   sigset_t set, oldset;
3571   sigfillset(&set);
3572 
3573   // block all signals while we do the file operation
3574   (void)sigprocmask(SIG_BLOCK, &set, &oldset);
3575 
3576   // set the file creation mask
3577   mode_t new_mask = exec ? (S_IRUSR | S_IWUSR | S_IXUSR) : (S_IRUSR | S_IWUSR);
3578   mode_t prev_umask = umask(new_mask);
3579 
3580   // create a new file
3581   int fd = mkstemp(fullname);
3582 
3583   // reset the file creation mask
3584   umask(prev_umask);
3585 
3586   if (fd < 0) {
3587     warning("Could not create file for heap");
3588     return -1;
3589   }
3590 
3591   // delete the name from the filesystem. When 'fd' is closed, the file (and space) will be deleted
3592   (void)unlink(fullname);
3593 
3594   // reset the signal mask
3595   (void)sigprocmask(SIG_SETMASK, &oldset, NULL);
3596 
3597   // allocate space for the file
3598   if ((errno = posix_fallocate(fd, 0, (off_t)size)) != 0) {
3599     warning("Could not allocate sufficient disk space for heap");
3600     return -1;
3601   }
3602 
3603   return fd;
3604 }
3605 
3606 // Map the given address range to a temporary file created at the specified directory.
3607 // 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
3608 bool os::map_memory_to_file(char* base, size_t size, const char* backingFileDir) {
3609 
3610   int fd = os::create_tmpfile(backingFileDir, size, false);
3611   if (fd == -1) {
3612     vm_exit_during_initialization(err_msg("Could not create temporary file in %s for object heap", backingFileDir));
3613     return false;
3614   }
3615   int prot = PROT_READ | PROT_WRITE;
3616   char* addr = (char*)mmap(base, size, prot, MAP_SHARED | MAP_FIXED, fd, 0);
3617 
3618   if (addr == MAP_FAILED || addr != base) {
3619     close(fd);
3620     vm_exit_during_initialization(err_msg("Error in mapping object heap at the given filesystem dir %s", backingFileDir));
3621     return false;
3622   }
3623 
3624   return true;
3625 }
3626 
3627 // Reserve memory using mmap(MAP_HUGETLB).
3628 //  - bytes shall be a multiple of alignment.
3629 //  - req_addr can be NULL. If not NULL, it must be a multiple of alignment.
3630 //  - alignment sets the alignment at which memory shall be allocated.
3631 //     It must be a multiple of allocation granularity.
3632 // Returns address of memory or NULL. If req_addr was not NULL, will only return
3633 //  req_addr or NULL.
3634 char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes,
3635                                                          size_t alignment,
3636                                                          char* req_addr,
3637                                                          bool exec) {
3638   size_t large_page_size = os::large_page_size();
3639   assert(bytes >= large_page_size, "Shouldn't allocate large pages for small sizes");
3640 
3641   assert(is_ptr_aligned(req_addr, alignment), "Must be");
3642   assert(is_size_aligned(bytes, alignment), "Must be");
3643 
3644   // First reserve - but not commit - the address range in small pages.
3645   char* const start = anon_mmap_aligned(bytes, alignment, req_addr);
3646 


< prev index next >