예제 #1
0
/**
 * 使用当前JVM的jar包
 */
void FileMapInfo::populate_header(size_t alignment) {
  _header._magic = 0xf00baba2;
  _header._version = _current_version;
  _header._alignment = alignment;

  // The following fields are for sanity checks for whether this archive
  // will function correctly with this JVM and the bootclasspath it's
  // invoked with.

  // JVM version string ... changes on each build.
  const char *vm_version = VM_Version::internal_vm_info_string();
  if (strlen(vm_version) < (JVM_IDENT_MAX-1)) {
    strcpy(_header._jvm_ident, vm_version);
  } else {
    fail_stop("JVM Ident field for shared archive is too long"
              " - truncated to <%s>", _header._jvm_ident);
  }

  // Build checks on classpath and jar files
  _header._num_jars = 0;
  ClassPathEntry *cpe = ClassLoader::classpath_entry(0);
  for ( ; cpe != NULL; cpe = cpe->next()) {

    if (cpe->is_jar_file()) {	//jar包文件
      if (_header._num_jars >= JVM_SHARED_JARS_MAX) {
        fail_stop("Too many jar files to share.", NULL);
      }

      // Jar file - record timestamp and file size.
      struct stat st;
      const char *path = cpe->name();
      if (os::stat(path, &st) != 0) {
        // If we can't access a jar file in the boot path, then we can't
        // make assumptions about where classes get loaded from.
        fail_stop("Unable to open jar file %s.", path);
      }
      _header._jar[_header._num_jars]._timestamp = st.st_mtime;
      _header._jar[_header._num_jars]._filesize = st.st_size;
      _header._num_jars++;
    } else {

      // If directories appear in boot classpath, they must be empty to
      // avoid having to verify each individual class file.
      const char* name = ((ClassPathDirEntry*)cpe)->name();
      if (!os::dir_is_empty(name)) {
        fail_stop("Boot classpath directory %s is not empty.", name);
      }
    }
  }

}
예제 #2
0
void FileMapInfo::unmap_region(int i) {
  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
  size_t used = si->_used;
  size_t size = align_size_up(used, os::vm_allocation_granularity());
  if (!os::unmap_memory(si->_base, size)) {
    fail_stop("Unable to unmap shared space.");
  }
}
예제 #3
0
void FileMapInfo::close() {
  if (_file_open) {
    if (::close(_fd) < 0) {
      fail_stop("Unable to close the shared archive file.");
    }
    _file_open = false;
    _fd = -1;
  }
}
예제 #4
0
void FileMapInfo::write_bytes(const void* buffer, int nbytes) {
  if (_file_open) {
    int n = ::write(_fd, buffer, nbytes);
    if (n != nbytes) {
      // It is dangerous to leave the corrupted shared archive file around,
      // close and remove the file. See bug 6372906.
      close();
      remove(_full_path);
      fail_stop("Unable to write to shared archive file.", NULL);
    }
  }
  _file_offset += nbytes;
}
예제 #5
0
// Unmap mapped regions of shared space.
void FileMapInfo::stop_sharing_and_unmap(const char* msg) {
  FileMapInfo *map_info = FileMapInfo::current_info();
  if (map_info) {
    map_info->fail_continue(msg);
    for (int i = 0; i < MetaspaceShared::n_regions; i++) {
      if (map_info->_header->_space[i]._base != NULL) {
        map_info->unmap_region(i);
        map_info->_header->_space[i]._base = NULL;
      }
    }
  } else if (DumpSharedSpaces) {
    fail_stop(msg, NULL);
  }
}
예제 #6
0
void FileMapInfo::unmap_string_regions() {
  for (int i = MetaspaceShared::first_string;
           i < MetaspaceShared::first_string + MetaspaceShared::max_strings; i++) {
    struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
    size_t used = si->_used;
    if (used > 0) {
      size_t size = align_size_up(used, os::vm_allocation_granularity());
      char* addr = (char*)((void*)oopDesc::decode_heap_oop_not_null(
                                             (narrowOop)si->_addr._offset));
      if (!os::unmap_memory(addr, size)) {
        fail_stop("Unable to unmap shared space.");
      }
    }
  }
}
예제 #7
0
void FileMapInfo::unmap_region(int i) {
  assert(!MetaspaceShared::is_string_region(i), "sanity");
  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
  size_t used = si->_used;
  size_t size = align_size_up(used, os::vm_allocation_granularity());

  if (used == 0) {
    return;
  }

  char* addr = _header->region_addr(i);
  if (!os::unmap_memory(addr, size)) {
    fail_stop("Unable to unmap shared space.");
  }
}
예제 #8
0
void FileMapInfo::align_file_position() {
  long new_file_offset = align_size_up(_file_offset, os::vm_allocation_granularity());
  if (new_file_offset != _file_offset) {
    _file_offset = new_file_offset;
    if (_file_open) {
      // Seek one byte back from the target and write a byte to insure
      // that the written file is the correct length.
      _file_offset -= 1;
      if (lseek(_fd, _file_offset, SEEK_SET) < 0) {
        fail_stop("Unable to seek.", NULL);
      }
      char zero = 0;
      write_bytes(&zero, 1);
    }
  }
}
예제 #9
0
// Unmap mapped regions of shared space.
void FileMapInfo::stop_sharing_and_unmap(const char* msg) {
  FileMapInfo *map_info = FileMapInfo::current_info();
  if (map_info) {
    map_info->fail_continue("%s", msg);
    for (int i = 0; i < MetaspaceShared::num_non_strings; i++) {
      char *addr = map_info->_header->region_addr(i);
      if (addr != NULL && !MetaspaceShared::is_string_region(i)) {
        map_info->unmap_region(i);
        map_info->_header->_space[i]._addr._base = NULL;
      }
    }
    map_info->unmap_string_regions();
  } else if (DumpSharedSpaces) {
    fail_stop("%s", msg);
  }
}
예제 #10
0
void FileMapInfo::open_for_write() {
 _full_path = Arguments::GetSharedArchivePath();
  if (PrintSharedSpaces) {
    tty->print_cr("Dumping shared data to file: ");
    tty->print_cr("   %s", _full_path);
  }

  // Remove the existing file in case another process has it open.
  remove(_full_path);
  int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444);
  if (fd < 0) {
    fail_stop("Unable to create shared archive file %s.", _full_path);
  }
  _fd = fd;
  _file_offset = 0;
  _file_open = true;
}
예제 #11
0
void FileMapInfo::open_for_write() {
 _full_path = Arguments::GetSharedArchivePath();
  if (PrintSharedSpaces) {
    tty->print_cr("Dumping shared data to file: ");
    tty->print_cr("   %s", _full_path);
  }

#ifdef _WINDOWS  // On Windows, need WRITE permission to remove the file.
  chmod(_full_path, _S_IREAD | _S_IWRITE);
#endif

  // Use remove() to delete the existing file because, on Unix, this will
  // allow processes that have it open continued access to the file.
  remove(_full_path);
  int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444);
  if (fd < 0) {
    fail_stop("Unable to create shared archive file %s.", _full_path);
  }
  _fd = fd;
  _file_offset = 0;
  _file_open = true;
}
예제 #12
0
void FileMapInfo::assert_mark(bool check) {
  if (!check) {
    fail_stop("Mark mismatch while restoring from shared file.", NULL);
  }
}