src/share/vm/memory/filemap.cpp

changeset 7089
6e0cb14ce59b
parent 6680
78bbf4d43a14
child 7241
8cb56c8cb30d
     1.1 --- a/src/share/vm/memory/filemap.cpp	Fri Aug 22 12:03:49 2014 -0700
     1.2 +++ b/src/share/vm/memory/filemap.cpp	Thu Aug 21 13:57:51 2014 -0700
     1.3 @@ -24,9 +24,14 @@
     1.4  
     1.5  #include "precompiled.hpp"
     1.6  #include "classfile/classLoader.hpp"
     1.7 +#include "classfile/sharedClassUtil.hpp"
     1.8  #include "classfile/symbolTable.hpp"
     1.9 +#include "classfile/systemDictionaryShared.hpp"
    1.10  #include "classfile/altHashing.hpp"
    1.11  #include "memory/filemap.hpp"
    1.12 +#include "memory/metadataFactory.hpp"
    1.13 +#include "memory/oopFactory.hpp"
    1.14 +#include "oops/objArrayOop.hpp"
    1.15  #include "runtime/arguments.hpp"
    1.16  #include "runtime/java.hpp"
    1.17  #include "runtime/os.hpp"
    1.18 @@ -41,7 +46,6 @@
    1.19  #endif
    1.20  
    1.21  PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
    1.22 -
    1.23  extern address JVM_FunctionAtStart();
    1.24  extern address JVM_FunctionAtEnd();
    1.25  
    1.26 @@ -77,12 +81,27 @@
    1.27  void FileMapInfo::fail_continue(const char *msg, ...) {
    1.28    va_list ap;
    1.29    va_start(ap, msg);
    1.30 -  if (RequireSharedSpaces) {
    1.31 -    fail(msg, ap);
    1.32 +  MetaspaceShared::set_archive_loading_failed();
    1.33 +  if (PrintSharedArchiveAndExit && _validating_classpath_entry_table) {
    1.34 +    // If we are doing PrintSharedArchiveAndExit and some of the classpath entries
    1.35 +    // do not validate, we can still continue "limping" to validate the remaining
    1.36 +    // entries. No need to quit.
    1.37 +    tty->print("[");
    1.38 +    tty->vprint(msg, ap);
    1.39 +    tty->print_cr("]");
    1.40 +  } else {
    1.41 +    if (RequireSharedSpaces) {
    1.42 +      fail(msg, ap);
    1.43 +    } else {
    1.44 +      if (PrintSharedSpaces) {
    1.45 +        tty->print_cr("UseSharedSpaces: %s", msg);
    1.46 +      }
    1.47 +    }
    1.48    }
    1.49    va_end(ap);
    1.50    UseSharedSpaces = false;
    1.51 -  close();
    1.52 +  assert(current_info() != NULL, "singleton must be registered");
    1.53 +  current_info()->close();
    1.54  }
    1.55  
    1.56  // Fill in the fileMapInfo structure with data about this VM instance.
    1.57 @@ -117,67 +136,201 @@
    1.58    }
    1.59  }
    1.60  
    1.61 +FileMapInfo::FileMapInfo() {
    1.62 +  assert(_current_info == NULL, "must be singleton"); // not thread safe
    1.63 +  _current_info = this;
    1.64 +  memset(this, 0, sizeof(FileMapInfo));
    1.65 +  _file_offset = 0;
    1.66 +  _file_open = false;
    1.67 +  _header = SharedClassUtil::allocate_file_map_header();
    1.68 +  _header->_version = _invalid_version;
    1.69 +}
    1.70 +
    1.71 +FileMapInfo::~FileMapInfo() {
    1.72 +  assert(_current_info == this, "must be singleton"); // not thread safe
    1.73 +  _current_info = NULL;
    1.74 +}
    1.75 +
    1.76  void FileMapInfo::populate_header(size_t alignment) {
    1.77 -  _header._magic = 0xf00baba2;
    1.78 -  _header._version = _current_version;
    1.79 -  _header._alignment = alignment;
    1.80 -  _header._obj_alignment = ObjectAlignmentInBytes;
    1.81 +  _header->populate(this, alignment);
    1.82 +}
    1.83 +
    1.84 +size_t FileMapInfo::FileMapHeader::data_size() {
    1.85 +  return SharedClassUtil::file_map_header_size() - sizeof(FileMapInfo::FileMapHeaderBase);
    1.86 +}
    1.87 +
    1.88 +void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) {
    1.89 +  _magic = 0xf00baba2;
    1.90 +  _version = _current_version;
    1.91 +  _alignment = alignment;
    1.92 +  _obj_alignment = ObjectAlignmentInBytes;
    1.93 +  _classpath_entry_table_size = mapinfo->_classpath_entry_table_size;
    1.94 +  _classpath_entry_table = mapinfo->_classpath_entry_table;
    1.95 +  _classpath_entry_size = mapinfo->_classpath_entry_size;
    1.96  
    1.97    // The following fields are for sanity checks for whether this archive
    1.98    // will function correctly with this JVM and the bootclasspath it's
    1.99    // invoked with.
   1.100  
   1.101    // JVM version string ... changes on each build.
   1.102 -  get_header_version(_header._jvm_ident);
   1.103 +  get_header_version(_jvm_ident);
   1.104 +}
   1.105  
   1.106 -  // Build checks on classpath and jar files
   1.107 -  _header._num_jars = 0;
   1.108 -  ClassPathEntry *cpe = ClassLoader::classpath_entry(0);
   1.109 -  for ( ; cpe != NULL; cpe = cpe->next()) {
   1.110 +void FileMapInfo::allocate_classpath_entry_table() {
   1.111 +  int bytes = 0;
   1.112 +  int count = 0;
   1.113 +  char* strptr = NULL;
   1.114 +  char* strptr_max = NULL;
   1.115 +  Thread* THREAD = Thread::current();
   1.116  
   1.117 -    if (cpe->is_jar_file()) {
   1.118 -      if (_header._num_jars >= JVM_SHARED_JARS_MAX) {
   1.119 -        fail_stop("Too many jar files to share.", NULL);
   1.120 +  ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
   1.121 +  size_t entry_size = SharedClassUtil::shared_class_path_entry_size();
   1.122 +
   1.123 +  for (int pass=0; pass<2; pass++) {
   1.124 +    ClassPathEntry *cpe = ClassLoader::classpath_entry(0);
   1.125 +
   1.126 +    for (int cur_entry = 0 ; cpe != NULL; cpe = cpe->next(), cur_entry++) {
   1.127 +      const char *name = cpe->name();
   1.128 +      int name_bytes = (int)(strlen(name) + 1);
   1.129 +
   1.130 +      if (pass == 0) {
   1.131 +        count ++;
   1.132 +        bytes += (int)entry_size;
   1.133 +        bytes += name_bytes;
   1.134 +        if (TraceClassPaths || (TraceClassLoading && Verbose)) {
   1.135 +          tty->print_cr("[Add main shared path (%s) %s]", (cpe->is_jar_file() ? "jar" : "dir"), name);
   1.136 +        }
   1.137 +      } else {
   1.138 +        SharedClassPathEntry* ent = shared_classpath(cur_entry);
   1.139 +        if (cpe->is_jar_file()) {
   1.140 +          struct stat st;
   1.141 +          if (os::stat(name, &st) != 0) {
   1.142 +            // The file/dir must exist, or it would not have been added
   1.143 +            // into ClassLoader::classpath_entry().
   1.144 +            //
   1.145 +            // If we can't access a jar file in the boot path, then we can't
   1.146 +            // make assumptions about where classes get loaded from.
   1.147 +            FileMapInfo::fail_stop("Unable to open jar file %s.", name);
   1.148 +          }
   1.149 +
   1.150 +          EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
   1.151 +          SharedClassUtil::update_shared_classpath(cpe, ent, st.st_mtime, st.st_size, THREAD);
   1.152 +        } else {
   1.153 +          ent->_filesize  = -1;
   1.154 +          if (!os::dir_is_empty(name)) {
   1.155 +            ClassLoader::exit_with_path_failure("Cannot have non-empty directory in archived classpaths", name);
   1.156 +          }
   1.157 +        }
   1.158 +        ent->_name = strptr;
   1.159 +        if (strptr + name_bytes <= strptr_max) {
   1.160 +          strncpy(strptr, name, (size_t)name_bytes); // name_bytes includes trailing 0.
   1.161 +          strptr += name_bytes;
   1.162 +        } else {
   1.163 +          assert(0, "miscalculated buffer size");
   1.164 +        }
   1.165        }
   1.166 +    }
   1.167  
   1.168 -      // Jar file - record timestamp and file size.
   1.169 -      struct stat st;
   1.170 -      const char *path = cpe->name();
   1.171 -      if (os::stat(path, &st) != 0) {
   1.172 -        // If we can't access a jar file in the boot path, then we can't
   1.173 -        // make assumptions about where classes get loaded from.
   1.174 -        fail_stop("Unable to open jar file %s.", path);
   1.175 -      }
   1.176 -      _header._jar[_header._num_jars]._timestamp = st.st_mtime;
   1.177 -      _header._jar[_header._num_jars]._filesize = st.st_size;
   1.178 -      _header._num_jars++;
   1.179 -    } else {
   1.180 +    if (pass == 0) {
   1.181 +      EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
   1.182 +      Array<u8>* arr = MetadataFactory::new_array<u8>(loader_data, (bytes + 7)/8, THREAD);
   1.183 +      strptr = (char*)(arr->data());
   1.184 +      strptr_max = strptr + bytes;
   1.185 +      SharedClassPathEntry* table = (SharedClassPathEntry*)strptr;
   1.186 +      strptr += entry_size * count;
   1.187  
   1.188 -      // If directories appear in boot classpath, they must be empty to
   1.189 -      // avoid having to verify each individual class file.
   1.190 -      const char* name = ((ClassPathDirEntry*)cpe)->name();
   1.191 -      if (!os::dir_is_empty(name)) {
   1.192 -        fail_stop("Boot classpath directory %s is not empty.", name);
   1.193 -      }
   1.194 +      _classpath_entry_table_size = count;
   1.195 +      _classpath_entry_table = table;
   1.196 +      _classpath_entry_size = entry_size;
   1.197      }
   1.198    }
   1.199  }
   1.200  
   1.201 +bool FileMapInfo::validate_classpath_entry_table() {
   1.202 +  _validating_classpath_entry_table = true;
   1.203 +
   1.204 +  int count = _header->_classpath_entry_table_size;
   1.205 +
   1.206 +  _classpath_entry_table = _header->_classpath_entry_table;
   1.207 +  _classpath_entry_size = _header->_classpath_entry_size;
   1.208 +
   1.209 +  for (int i=0; i<count; i++) {
   1.210 +    SharedClassPathEntry* ent = shared_classpath(i);
   1.211 +    struct stat st;
   1.212 +    const char* name = ent->_name;
   1.213 +    bool ok = true;
   1.214 +    if (TraceClassPaths || (TraceClassLoading && Verbose)) {
   1.215 +      tty->print_cr("[Checking shared classpath entry: %s]", name);
   1.216 +    }
   1.217 +    if (os::stat(name, &st) != 0) {
   1.218 +      fail_continue("Required classpath entry does not exist: %s", name);
   1.219 +      ok = false;
   1.220 +    } else if (ent->is_dir()) {
   1.221 +      if (!os::dir_is_empty(name)) {
   1.222 +        fail_continue("directory is not empty: %s", name);
   1.223 +        ok = false;
   1.224 +      }
   1.225 +    } else {
   1.226 +      if (ent->_timestamp != st.st_mtime ||
   1.227 +          ent->_filesize != st.st_size) {
   1.228 +        ok = false;
   1.229 +        if (PrintSharedArchiveAndExit) {
   1.230 +          fail_continue(ent->_timestamp != st.st_mtime ?
   1.231 +                        "Timestamp mismatch" :
   1.232 +                        "File size mismatch");
   1.233 +        } else {
   1.234 +          fail_continue("A jar file is not the one used while building"
   1.235 +                        " the shared archive file: %s", name);
   1.236 +        }
   1.237 +      }
   1.238 +    }
   1.239 +    if (ok) {
   1.240 +      if (TraceClassPaths || (TraceClassLoading && Verbose)) {
   1.241 +        tty->print_cr("[ok]");
   1.242 +      }
   1.243 +    } else if (!PrintSharedArchiveAndExit) {
   1.244 +      _validating_classpath_entry_table = false;
   1.245 +      return false;
   1.246 +    }
   1.247 +  }
   1.248 +
   1.249 +  _classpath_entry_table_size = _header->_classpath_entry_table_size;
   1.250 +  _validating_classpath_entry_table = false;
   1.251 +  return true;
   1.252 +}
   1.253 +
   1.254  
   1.255  // Read the FileMapInfo information from the file.
   1.256  
   1.257  bool FileMapInfo::init_from_file(int fd) {
   1.258 -
   1.259 -  size_t n = read(fd, &_header, sizeof(struct FileMapHeader));
   1.260 -  if (n != sizeof(struct FileMapHeader)) {
   1.261 +  size_t sz = _header->data_size();
   1.262 +  char* addr = _header->data();
   1.263 +  size_t n = os::read(fd, addr, (unsigned int)sz);
   1.264 +  if (n != sz) {
   1.265      fail_continue("Unable to read the file header.");
   1.266      return false;
   1.267    }
   1.268 -  if (_header._version != current_version()) {
   1.269 +  if (_header->_version != current_version()) {
   1.270      fail_continue("The shared archive file has the wrong version.");
   1.271      return false;
   1.272    }
   1.273    _file_offset = (long)n;
   1.274 +
   1.275 +  size_t info_size = _header->_paths_misc_info_size;
   1.276 +  _paths_misc_info = NEW_C_HEAP_ARRAY_RETURN_NULL(char, info_size, mtClass);
   1.277 +  if (_paths_misc_info == NULL) {
   1.278 +    fail_continue("Unable to read the file header.");
   1.279 +    return false;
   1.280 +  }
   1.281 +  n = os::read(fd, _paths_misc_info, (unsigned int)info_size);
   1.282 +  if (n != info_size) {
   1.283 +    fail_continue("Unable to read the shared path info header.");
   1.284 +    FREE_C_HEAP_ARRAY(char, _paths_misc_info, mtClass);
   1.285 +    _paths_misc_info = NULL;
   1.286 +    return false;
   1.287 +  }
   1.288 +
   1.289 +  _file_offset += (long)n;
   1.290    return true;
   1.291  }
   1.292  
   1.293 @@ -232,7 +385,16 @@
   1.294  // Write the header to the file, seek to the next allocation boundary.
   1.295  
   1.296  void FileMapInfo::write_header() {
   1.297 -  write_bytes_aligned(&_header, sizeof(FileMapHeader));
   1.298 +  int info_size = ClassLoader::get_shared_paths_misc_info_size();
   1.299 +
   1.300 +  _header->_paths_misc_info_size = info_size;
   1.301 +
   1.302 +  align_file_position();
   1.303 +  size_t sz = _header->data_size();
   1.304 +  char* addr = _header->data();
   1.305 +  write_bytes(addr, (int)sz); // skip the C++ vtable
   1.306 +  write_bytes(ClassLoader::get_shared_paths_misc_info(), info_size);
   1.307 +  align_file_position();
   1.308  }
   1.309  
   1.310  
   1.311 @@ -242,7 +404,7 @@
   1.312    align_file_position();
   1.313    size_t used = space->used_bytes_slow(Metaspace::NonClassType);
   1.314    size_t capacity = space->capacity_bytes_slow(Metaspace::NonClassType);
   1.315 -  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
   1.316 +  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
   1.317    write_region(i, (char*)space->bottom(), used, capacity, read_only, false);
   1.318  }
   1.319  
   1.320 @@ -252,7 +414,7 @@
   1.321  void FileMapInfo::write_region(int region, char* base, size_t size,
   1.322                                 size_t capacity, bool read_only,
   1.323                                 bool allow_exec) {
   1.324 -  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[region];
   1.325 +  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[region];
   1.326  
   1.327    if (_file_open) {
   1.328      guarantee(si->_file_offset == _file_offset, "file offset mismatch.");
   1.329 @@ -334,7 +496,7 @@
   1.330  // JVM/TI RedefineClasses() support:
   1.331  // Remap the shared readonly space to shared readwrite, private.
   1.332  bool FileMapInfo::remap_shared_readonly_as_readwrite() {
   1.333 -  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0];
   1.334 +  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[0];
   1.335    if (!si->_read_only) {
   1.336      // the space is already readwrite so we are done
   1.337      return true;
   1.338 @@ -362,7 +524,7 @@
   1.339  
   1.340  // Map the whole region at once, assumed to be allocated contiguously.
   1.341  ReservedSpace FileMapInfo::reserve_shared_memory() {
   1.342 -  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0];
   1.343 +  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[0];
   1.344    char* requested_addr = si->_base;
   1.345  
   1.346    size_t size = FileMapInfo::shared_spaces_size();
   1.347 @@ -384,7 +546,7 @@
   1.348  static const char* shared_region_name[] = { "ReadOnly", "ReadWrite", "MiscData", "MiscCode"};
   1.349  
   1.350  char* FileMapInfo::map_region(int i) {
   1.351 -  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
   1.352 +  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
   1.353    size_t used = si->_used;
   1.354    size_t alignment = os::vm_allocation_granularity();
   1.355    size_t size = align_size_up(used, alignment);
   1.356 @@ -410,7 +572,7 @@
   1.357  // Unmap a memory region in the address space.
   1.358  
   1.359  void FileMapInfo::unmap_region(int i) {
   1.360 -  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
   1.361 +  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
   1.362    size_t used = si->_used;
   1.363    size_t size = align_size_up(used, os::vm_allocation_granularity());
   1.364    if (!os::unmap_memory(si->_base, size)) {
   1.365 @@ -427,12 +589,21 @@
   1.366  
   1.367  
   1.368  FileMapInfo* FileMapInfo::_current_info = NULL;
   1.369 -
   1.370 +SharedClassPathEntry* FileMapInfo::_classpath_entry_table = NULL;
   1.371 +int FileMapInfo::_classpath_entry_table_size = 0;
   1.372 +size_t FileMapInfo::_classpath_entry_size = 0x1234baad;
   1.373 +bool FileMapInfo::_validating_classpath_entry_table = false;
   1.374  
   1.375  // Open the shared archive file, read and validate the header
   1.376  // information (version, boot classpath, etc.).  If initialization
   1.377  // fails, shared spaces are disabled and the file is closed. [See
   1.378  // fail_continue.]
   1.379 +//
   1.380 +// Validation of the archive is done in two steps:
   1.381 +//
   1.382 +// [1] validate_header() - done here. This checks the header, including _paths_misc_info.
   1.383 +// [2] validate_classpath_entry_table - this is done later, because the table is in the RW
   1.384 +//     region of the archive, which is not mapped yet.
   1.385  bool FileMapInfo::initialize() {
   1.386    assert(UseSharedSpaces, "UseSharedSpaces expected.");
   1.387  
   1.388 @@ -446,92 +617,66 @@
   1.389    }
   1.390  
   1.391    init_from_file(_fd);
   1.392 -  if (!validate()) {
   1.393 +  if (!validate_header()) {
   1.394      return false;
   1.395    }
   1.396  
   1.397 -  SharedReadOnlySize =  _header._space[0]._capacity;
   1.398 -  SharedReadWriteSize = _header._space[1]._capacity;
   1.399 -  SharedMiscDataSize =  _header._space[2]._capacity;
   1.400 -  SharedMiscCodeSize =  _header._space[3]._capacity;
   1.401 +  SharedReadOnlySize =  _header->_space[0]._capacity;
   1.402 +  SharedReadWriteSize = _header->_space[1]._capacity;
   1.403 +  SharedMiscDataSize =  _header->_space[2]._capacity;
   1.404 +  SharedMiscCodeSize =  _header->_space[3]._capacity;
   1.405    return true;
   1.406  }
   1.407  
   1.408 -
   1.409 -bool FileMapInfo::validate() {
   1.410 -  if (_header._version != current_version()) {
   1.411 -    fail_continue("The shared archive file is the wrong version.");
   1.412 +bool FileMapInfo::FileMapHeader::validate() {
   1.413 +  if (_version != current_version()) {
   1.414 +    FileMapInfo::fail_continue("The shared archive file is the wrong version.");
   1.415      return false;
   1.416    }
   1.417 -  if (_header._magic != (int)0xf00baba2) {
   1.418 -    fail_continue("The shared archive file has a bad magic number.");
   1.419 +  if (_magic != (int)0xf00baba2) {
   1.420 +    FileMapInfo::fail_continue("The shared archive file has a bad magic number.");
   1.421      return false;
   1.422    }
   1.423    char header_version[JVM_IDENT_MAX];
   1.424    get_header_version(header_version);
   1.425 -  if (strncmp(_header._jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
   1.426 -    fail_continue("The shared archive file was created by a different"
   1.427 -                  " version or build of HotSpot.");
   1.428 +  if (strncmp(_jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
   1.429 +    if (TraceClassPaths) {
   1.430 +      tty->print_cr("Expected: %s", header_version);
   1.431 +      tty->print_cr("Actual:   %s", _jvm_ident);
   1.432 +    }
   1.433 +    FileMapInfo::fail_continue("The shared archive file was created by a different"
   1.434 +                  " version or build of HotSpot");
   1.435      return false;
   1.436    }
   1.437 -  if (_header._obj_alignment != ObjectAlignmentInBytes) {
   1.438 -    fail_continue("The shared archive file's ObjectAlignmentInBytes of %d"
   1.439 +  if (_obj_alignment != ObjectAlignmentInBytes) {
   1.440 +    FileMapInfo::fail_continue("The shared archive file's ObjectAlignmentInBytes of %d"
   1.441                    " does not equal the current ObjectAlignmentInBytes of %d.",
   1.442 -                  _header._obj_alignment, ObjectAlignmentInBytes);
   1.443 -    return false;
   1.444 -  }
   1.445 -
   1.446 -  // Cannot verify interpreter yet, as it can only be created after the GC
   1.447 -  // heap has been initialized.
   1.448 -
   1.449 -  if (_header._num_jars >= JVM_SHARED_JARS_MAX) {
   1.450 -    fail_continue("Too many jar files to share.");
   1.451 -    return false;
   1.452 -  }
   1.453 -
   1.454 -  // Build checks on classpath and jar files
   1.455 -  int num_jars_now = 0;
   1.456 -  ClassPathEntry *cpe = ClassLoader::classpath_entry(0);
   1.457 -  for ( ; cpe != NULL; cpe = cpe->next()) {
   1.458 -
   1.459 -    if (cpe->is_jar_file()) {
   1.460 -      if (num_jars_now < _header._num_jars) {
   1.461 -
   1.462 -        // Jar file - verify timestamp and file size.
   1.463 -        struct stat st;
   1.464 -        const char *path = cpe->name();
   1.465 -        if (os::stat(path, &st) != 0) {
   1.466 -          fail_continue("Unable to open jar file %s.", path);
   1.467 -          return false;
   1.468 -        }
   1.469 -        if (_header._jar[num_jars_now]._timestamp != st.st_mtime ||
   1.470 -            _header._jar[num_jars_now]._filesize != st.st_size) {
   1.471 -          fail_continue("A jar file is not the one used while building"
   1.472 -                        " the shared archive file.");
   1.473 -          return false;
   1.474 -        }
   1.475 -      }
   1.476 -      ++num_jars_now;
   1.477 -    } else {
   1.478 -
   1.479 -      // If directories appear in boot classpath, they must be empty to
   1.480 -      // avoid having to verify each individual class file.
   1.481 -      const char* name = ((ClassPathDirEntry*)cpe)->name();
   1.482 -      if (!os::dir_is_empty(name)) {
   1.483 -        fail_continue("Boot classpath directory %s is not empty.", name);
   1.484 -        return false;
   1.485 -      }
   1.486 -    }
   1.487 -  }
   1.488 -  if (num_jars_now < _header._num_jars) {
   1.489 -    fail_continue("The number of jar files in the boot classpath is"
   1.490 -                  " less than the number the shared archive was created with.");
   1.491 +                  _obj_alignment, ObjectAlignmentInBytes);
   1.492      return false;
   1.493    }
   1.494  
   1.495    return true;
   1.496  }
   1.497  
   1.498 +bool FileMapInfo::validate_header() {
   1.499 +  bool status = _header->validate();
   1.500 +
   1.501 +  if (status) {
   1.502 +    if (!ClassLoader::check_shared_paths_misc_info(_paths_misc_info, _header->_paths_misc_info_size)) {
   1.503 +      if (!PrintSharedArchiveAndExit) {
   1.504 +        fail_continue("shared class paths mismatch (hint: enable -XX:+TraceClassPaths to diagnose the failure)");
   1.505 +        status = false;
   1.506 +      }
   1.507 +    }
   1.508 +  }
   1.509 +
   1.510 +  if (_paths_misc_info != NULL) {
   1.511 +    FREE_C_HEAP_ARRAY(char, _paths_misc_info, mtClass);
   1.512 +    _paths_misc_info = NULL;
   1.513 +  }
   1.514 +  return status;
   1.515 +}
   1.516 +
   1.517  // The following method is provided to see whether a given pointer
   1.518  // falls in the mapped shared space.
   1.519  // Param:
   1.520 @@ -540,8 +685,8 @@
   1.521  // True if the p is within the mapped shared space, otherwise, false.
   1.522  bool FileMapInfo::is_in_shared_space(const void* p) {
   1.523    for (int i = 0; i < MetaspaceShared::n_regions; i++) {
   1.524 -    if (p >= _header._space[i]._base &&
   1.525 -        p < _header._space[i]._base + _header._space[i]._used) {
   1.526 +    if (p >= _header->_space[i]._base &&
   1.527 +        p < _header->_space[i]._base + _header->_space[i]._used) {
   1.528        return true;
   1.529      }
   1.530    }
   1.531 @@ -552,7 +697,7 @@
   1.532  void FileMapInfo::print_shared_spaces() {
   1.533    gclog_or_tty->print_cr("Shared Spaces:");
   1.534    for (int i = 0; i < MetaspaceShared::n_regions; i++) {
   1.535 -    struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
   1.536 +    struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
   1.537      gclog_or_tty->print("  %s " INTPTR_FORMAT "-" INTPTR_FORMAT,
   1.538                          shared_region_name[i],
   1.539                          si->_base, si->_base + si->_used);
   1.540 @@ -565,9 +710,9 @@
   1.541    if (map_info) {
   1.542      map_info->fail_continue(msg);
   1.543      for (int i = 0; i < MetaspaceShared::n_regions; i++) {
   1.544 -      if (map_info->_header._space[i]._base != NULL) {
   1.545 +      if (map_info->_header->_space[i]._base != NULL) {
   1.546          map_info->unmap_region(i);
   1.547 -        map_info->_header._space[i]._base = NULL;
   1.548 +        map_info->_header->_space[i]._base = NULL;
   1.549        }
   1.550      }
   1.551    } else if (DumpSharedSpaces) {

mercurial