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 |