< prev index next >

src/os/linux/vm/os_linux.cpp

Print this page

        

@@ -3464,10 +3464,76 @@
   }
   return start;
 
 }
 
+// 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.
 //  - alignment sets the alignment at which memory shall be allocated.
 //     It must be a multiple of allocation granularity.
< prev index next >