< prev index next >

src/os/linux/vm/os_linux.cpp

Print this page




3449         ::munmap(start, extra_size);
3450         start = NULL;
3451       }
3452     } else {
3453       char* const start_aligned = (char*) align_ptr_up(start, alignment);
3454       char* const end_aligned = start_aligned + bytes;
3455       char* const end = start + extra_size;
3456       if (start_aligned > start) {
3457         ::munmap(start, start_aligned - start);
3458       }
3459       if (end_aligned < end) {
3460         ::munmap(end_aligned, end - end_aligned);
3461       }
3462       start = start_aligned;
3463     }
3464   }
3465   return start;
3466 
3467 }
3468 


































































3469 // Reserve memory using mmap(MAP_HUGETLB).
3470 //  - bytes shall be a multiple of alignment.
3471 //  - req_addr can be NULL. If not NULL, it must be a multiple of alignment.
3472 //  - alignment sets the alignment at which memory shall be allocated.
3473 //     It must be a multiple of allocation granularity.
3474 // Returns address of memory or NULL. If req_addr was not NULL, will only return
3475 //  req_addr or NULL.
3476 char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes,
3477                                                          size_t alignment,
3478                                                          char* req_addr,
3479                                                          bool exec) {
3480   size_t large_page_size = os::large_page_size();
3481   assert(bytes >= large_page_size, "Shouldn't allocate large pages for small sizes");
3482 
3483   assert(is_ptr_aligned(req_addr, alignment), "Must be");
3484   assert(is_size_aligned(bytes, alignment), "Must be");
3485 
3486   // First reserve - but not commit - the address range in small pages.
3487   char* const start = anon_mmap_aligned(bytes, alignment, req_addr);
3488 




3449         ::munmap(start, extra_size);
3450         start = NULL;
3451       }
3452     } else {
3453       char* const start_aligned = (char*) align_ptr_up(start, alignment);
3454       char* const end_aligned = start_aligned + bytes;
3455       char* const end = start + extra_size;
3456       if (start_aligned > start) {
3457         ::munmap(start, start_aligned - start);
3458       }
3459       if (end_aligned < end) {
3460         ::munmap(end_aligned, end - end_aligned);
3461       }
3462       start = start_aligned;
3463     }
3464   }
3465   return start;
3466 
3467 }
3468 
3469 // Helper function to create a temp file in the given directory
3470 int os::Linux::create_tmpfile(const char* dir, size_t size, bool exec) {
3471 
3472   static char name_template[] = "/jvmheap.XXXXXX";
3473 
3474   char fullname[strlen(dir) + sizeof(name_template)];
3475   (void)strcpy(fullname, dir);
3476   (void)strcat(fullname, name_template);
3477 
3478   sigset_t set, oldset;
3479   sigfillset(&set);
3480 
3481   // block all signals while we do the file operation
3482   (void)sigprocmask(SIG_BLOCK, &set, &oldset);
3483 
3484   // set the file creation mask
3485   mode_t new_mask = exec ? (S_IRUSR | S_IWUSR | S_IXUSR) : (S_IRUSR | S_IWUSR);
3486   mode_t prev_umask = umask(new_mask);
3487 
3488   // create a new file
3489   int fd = mkstemp(fullname);
3490 
3491   // reset the file creation mask
3492   umask(prev_umask);
3493 
3494   if (fd < 0) {
3495     warning("Could not create file for heap");
3496     return -1;
3497   }
3498 
3499   // delete the name from the filesystem. When 'fd' is closed, the file (and space) will be deleted
3500   (void)unlink(fullname);
3501 
3502   // reset the signal mask
3503   (void)sigprocmask(SIG_SETMASK, &oldset, NULL);
3504 
3505   // allocate space for the file
3506   if ((errno = posix_fallocate(fd, 0, (off_t)size)) != 0) {
3507     warning("Could not allocate sufficient disk space for heap");
3508     return -1;
3509   }
3510 
3511   return fd;
3512 }
3513 
3514 // Map the given address range to a temporary file created at the specified directory.
3515 // 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
3516 bool os::map_memory_to_file(char* base, size_t size, const char* backingFileDir) {
3517 
3518   int fd = os::Linux::create_tmpfile(backingFileDir, size, false);
3519   if (fd == -1) {
3520     vm_exit_during_initialization(err_msg("Could not create temporary file in %s for object heap", backingFileDir));
3521     return false;
3522   }
3523   int prot = PROT_READ | PROT_WRITE;
3524   char* addr = (char*)mmap(base, size, prot, MAP_SHARED | MAP_FIXED, fd, 0);
3525 
3526   if (addr == MAP_FAILED || addr != base) {
3527     close(fd);
3528     vm_exit_during_initialization(err_msg("Error in mapping object heap at the given filesystem dir %s", backingFileDir));
3529     return false;
3530   }
3531 
3532   return true;
3533 }
3534 
3535 // Reserve memory using mmap(MAP_HUGETLB).
3536 //  - bytes shall be a multiple of alignment.
3537 //  - req_addr can be NULL. If not NULL, it must be a multiple of alignment.
3538 //  - alignment sets the alignment at which memory shall be allocated.
3539 //     It must be a multiple of allocation granularity.
3540 // Returns address of memory or NULL. If req_addr was not NULL, will only return
3541 //  req_addr or NULL.
3542 char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes,
3543                                                          size_t alignment,
3544                                                          char* req_addr,
3545                                                          bool exec) {
3546   size_t large_page_size = os::large_page_size();
3547   assert(bytes >= large_page_size, "Shouldn't allocate large pages for small sizes");
3548 
3549   assert(is_ptr_aligned(req_addr, alignment), "Must be");
3550   assert(is_size_aligned(bytes, alignment), "Must be");
3551 
3552   // First reserve - but not commit - the address range in small pages.
3553   char* const start = anon_mmap_aligned(bytes, alignment, req_addr);
3554 


< prev index next >