src/hotspot/share/memory/filemap.cpp
changeset 49739 00805b129186
parent 49592 77fb0be7d19f
child 49931 840e26123940
--- a/src/hotspot/share/memory/filemap.cpp	Tue Apr 10 10:06:42 2018 -0400
+++ b/src/hotspot/share/memory/filemap.cpp	Tue Apr 10 11:43:40 2018 -0700
@@ -96,7 +96,7 @@
   va_list ap;
   va_start(ap, msg);
   MetaspaceShared::set_archive_loading_failed();
-  if (PrintSharedArchiveAndExit && _validating_classpath_entry_table) {
+  if (PrintSharedArchiveAndExit && _validating_shared_path_table) {
     // If we are doing PrintSharedArchiveAndExit and some of the classpath entries
     // do not validate, we can still continue "limping" to validate the remaining
     // entries. No need to quit.
@@ -188,9 +188,9 @@
   _max_heap_size = MaxHeapSize;
   _narrow_klass_base = Universe::narrow_klass_base();
   _narrow_klass_shift = Universe::narrow_klass_shift();
-  _classpath_entry_table_size = mapinfo->_classpath_entry_table_size;
-  _classpath_entry_table = mapinfo->_classpath_entry_table;
-  _classpath_entry_size = mapinfo->_classpath_entry_size;
+  _shared_path_table_size = mapinfo->_shared_path_table_size;
+  _shared_path_table = mapinfo->_shared_path_table;
+  _shared_path_entry_size = mapinfo->_shared_path_entry_size;
 
   // The following fields are for sanity checks for whether this archive
   // will function correctly with this JVM and the bootclasspath it's
@@ -231,12 +231,16 @@
   strcpy(_name->data(), name);
 }
 
-bool SharedClassPathEntry::validate() {
+bool SharedClassPathEntry::validate(bool is_class_path) {
   struct stat st;
   const char* name = this->name();
   bool ok = true;
   log_info(class, path)("checking shared classpath entry: %s", name);
-  if (os::stat(name, &st) != 0) {
+  if (os::stat(name, &st) != 0 && is_class_path) {
+    // If the archived module path entry does not exist at runtime, it is not fatal
+    // (no need to invalid the shared archive) because the shared runtime visibility check
+    // filters out any archived module classes that do not have a matching runtime
+    // module path location.
     FileMapInfo::fail_continue("Required classpath entry does not exist: %s", name);
     ok = false;
   } else if (is_dir()) {
@@ -266,7 +270,7 @@
   it->push(&_manifest);
 }
 
-void FileMapInfo::allocate_classpath_entry_table() {
+void FileMapInfo::allocate_shared_path_table() {
   assert(DumpSharedSpaces, "Sanity");
 
   Thread* THREAD = Thread::current();
@@ -279,12 +283,13 @@
   size_t entry_size = SharedClassUtil::shared_class_path_entry_size(); // assert ( should be 8 byte aligned??)
   int num_boot_classpath_entries = ClassLoader::num_boot_classpath_entries();
   int num_app_classpath_entries = ClassLoader::num_app_classpath_entries();
-  int num_entries = num_boot_classpath_entries + num_app_classpath_entries;
+  int num_module_path_entries = ClassLoader::num_module_path_entries();
+  int num_entries = num_boot_classpath_entries + num_app_classpath_entries + num_module_path_entries;
   size_t bytes = entry_size * num_entries;
 
-  _classpath_entry_table = MetadataFactory::new_array<u8>(loader_data, (int)(bytes + 7 / 8), THREAD);
-  _classpath_entry_table_size = num_entries;
-  _classpath_entry_size = entry_size;
+  _shared_path_table = MetadataFactory::new_array<u8>(loader_data, (int)(bytes + 7 / 8), THREAD);
+  _shared_path_table_size = num_entries;
+  _shared_path_entry_size = entry_size;
 
   // 1. boot class path
   int i = 0;
@@ -292,7 +297,7 @@
   while (cpe != NULL) {
     const char* type = ((cpe == jrt) ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir"));
     log_info(class, path)("add main shared path (%s) %s", type, cpe->name());
-    SharedClassPathEntry* ent = shared_classpath(i);
+    SharedClassPathEntry* ent = shared_path(i);
     ent->init(cpe->name(), THREAD);
     if (cpe != jrt) { // No need to do jimage.
       EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
@@ -308,41 +313,66 @@
   ClassPathEntry *acpe = ClassLoader::app_classpath_entries();
   while (acpe != NULL) {
     log_info(class, path)("add app shared path %s", acpe->name());
-    SharedClassPathEntry* ent = shared_classpath(i);
+    SharedClassPathEntry* ent = shared_path(i);
     ent->init(acpe->name(), THREAD);
     EXCEPTION_MARK;
     SharedClassUtil::update_shared_classpath(acpe, ent, THREAD);
     acpe = acpe->next();
-    i ++;
+    i++;
   }
-  assert(i == num_entries, "number of app class path entry mismatch");
+
+  // 3. module path
+  ClassPathEntry *mpe = ClassLoader::module_path_entries();
+  while (mpe != NULL) {
+    log_info(class, path)("add module path %s",mpe->name());
+    SharedClassPathEntry* ent = shared_path(i);
+    ent->init(mpe->name(), THREAD);
+    EXCEPTION_MARK;
+    SharedClassUtil::update_shared_classpath(mpe, ent, THREAD);
+    mpe = mpe->next();
+    i++;
+  }
+  assert(i == num_entries, "number of shared path entry mismatch");
 }
 
-bool FileMapInfo::validate_classpath_entry_table() {
-  _validating_classpath_entry_table = true;
+// This function should only be called during run time with UseSharedSpaces enabled.
+bool FileMapInfo::validate_shared_path_table() {
+  _validating_shared_path_table = true;
+
+  _shared_path_table = _header->_shared_path_table;
+  _shared_path_entry_size = _header->_shared_path_entry_size;
+  _shared_path_table_size = _header->_shared_path_table_size;
 
-  int count = _header->_classpath_entry_table_size;
+  // Note: _app_module_paths_start_index may not have a valid value if the UseAppCDS flag
+  // wasn't enabled during dump time. Therefore, we need to use the smaller of
+  // _shared_path_table_size and _app_module_paths_start_index for the _app_module_paths_start_index.
+  FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
+  int module_paths_start_index = (header->_app_module_paths_start_index >= _shared_path_table_size) ?
+                                  _shared_path_table_size : header->_app_module_paths_start_index;
 
-  _classpath_entry_table = _header->_classpath_entry_table;
-  _classpath_entry_size = _header->_classpath_entry_size;
-  _classpath_entry_table_size = _header->_classpath_entry_table_size;
+  int count = _shared_path_table_size;
 
   for (int i=0; i<count; i++) {
-    if (shared_classpath(i)->validate()) {
-      log_info(class, path)("ok");
+    if (i < module_paths_start_index) {
+      if (shared_path(i)->validate()) {
+        log_info(class, path)("ok");
+      }
+    } else if (i >= module_paths_start_index) {
+      if (shared_path(i)->validate(false /* not a class path entry */)) {
+        log_info(class, path)("ok");
+      }
     } else if (!PrintSharedArchiveAndExit) {
-      _validating_classpath_entry_table = false;
-      _classpath_entry_table = NULL;
-      _classpath_entry_table_size = 0;
+      _validating_shared_path_table = false;
+      _shared_path_table = NULL;
+      _shared_path_table_size = 0;
       return false;
     }
   }
 
-  _validating_classpath_entry_table = false;
+  _validating_shared_path_table = false;
   return true;
 }
 
-
 // Read the FileMapInfo information from the file.
 
 bool FileMapInfo::init_from_file(int fd) {
@@ -925,18 +955,18 @@
 }
 
 void FileMapInfo::metaspace_pointers_do(MetaspaceClosure* it) {
-  it->push(&_classpath_entry_table);
-  for (int i=0; i<_classpath_entry_table_size; i++) {
-    shared_classpath(i)->metaspace_pointers_do(it);
+  it->push(&_shared_path_table);
+  for (int i=0; i<_shared_path_table_size; i++) {
+    shared_path(i)->metaspace_pointers_do(it);
   }
 }
 
 
 FileMapInfo* FileMapInfo::_current_info = NULL;
-Array<u8>* FileMapInfo::_classpath_entry_table = NULL;
-int FileMapInfo::_classpath_entry_table_size = 0;
-size_t FileMapInfo::_classpath_entry_size = 0x1234baad;
-bool FileMapInfo::_validating_classpath_entry_table = false;
+Array<u8>* FileMapInfo::_shared_path_table = NULL;
+int FileMapInfo::_shared_path_table_size = 0;
+size_t FileMapInfo::_shared_path_entry_size = 0x1234baad;
+bool FileMapInfo::_validating_shared_path_table = false;
 
 // Open the shared archive file, read and validate the header
 // information (version, boot classpath, etc.).  If initialization
@@ -946,7 +976,7 @@
 // Validation of the archive is done in two steps:
 //
 // [1] validate_header() - done here. This checks the header, including _paths_misc_info.
-// [2] validate_classpath_entry_table - this is done later, because the table is in the RW
+// [2] validate_shared_path_table - this is done later, because the table is in the RW
 //     region of the archive, which is not mapped yet.
 bool FileMapInfo::initialize() {
   assert(UseSharedSpaces, "UseSharedSpaces expected.");
@@ -980,6 +1010,7 @@
   return crc;
 }
 
+// This function should only be called during run time with UseSharedSpaces enabled.
 bool FileMapInfo::FileMapHeader::validate() {
   if (VerifySharedSpaces && compute_crc() != _crc) {
     fail_continue("Header checksum verification failed.");