src/hotspot/share/memory/filemap.cpp
changeset 55524 b279ae9843b8
parent 55296 357c9dcb6eb9
child 55717 2b4e14968afd
equal deleted inserted replaced
55523:52ef2c940423 55524:b279ae9843b8
    73 
    73 
    74 // Complain and stop. All error conditions occurring during the writing of
    74 // Complain and stop. All error conditions occurring during the writing of
    75 // an archive file should stop the process.  Unrecoverable errors during
    75 // an archive file should stop the process.  Unrecoverable errors during
    76 // the reading of the archive file should stop the process.
    76 // the reading of the archive file should stop the process.
    77 
    77 
    78 static void fail(const char *msg, va_list ap) {
    78 static void fail_exit(const char *msg, va_list ap) {
    79   // This occurs very early during initialization: tty is not initialized.
    79   // This occurs very early during initialization: tty is not initialized.
    80   jio_fprintf(defaultStream::error_stream(),
    80   jio_fprintf(defaultStream::error_stream(),
    81               "An error has occurred while processing the"
    81               "An error has occurred while processing the"
    82               " shared archive file.\n");
    82               " shared archive file.\n");
    83   jio_vfprintf(defaultStream::error_stream(), msg, ap);
    83   jio_vfprintf(defaultStream::error_stream(), msg, ap);
    88 
    88 
    89 
    89 
    90 void FileMapInfo::fail_stop(const char *msg, ...) {
    90 void FileMapInfo::fail_stop(const char *msg, ...) {
    91         va_list ap;
    91         va_list ap;
    92   va_start(ap, msg);
    92   va_start(ap, msg);
    93   fail(msg, ap);        // Never returns.
    93   fail_exit(msg, ap);   // Never returns.
    94   va_end(ap);           // for completeness.
    94   va_end(ap);           // for completeness.
    95 }
    95 }
    96 
    96 
    97 
    97 
    98 // Complain and continue.  Recoverable errors during the reading of the
    98 // Complain and continue.  Recoverable errors during the reading of the
   116     tty->print("[");
   116     tty->print("[");
   117     tty->vprint(msg, ap);
   117     tty->vprint(msg, ap);
   118     tty->print_cr("]");
   118     tty->print_cr("]");
   119   } else {
   119   } else {
   120     if (RequireSharedSpaces) {
   120     if (RequireSharedSpaces) {
   121       fail(msg, ap);
   121       fail_exit(msg, ap);
   122     } else {
   122     } else {
   123       if (log_is_enabled(Info, cds)) {
   123       if (log_is_enabled(Info, cds)) {
   124         ResourceMark rm;
   124         ResourceMark rm;
   125         LogStream ls(Log(cds)::info());
   125         LogStream ls(Log(cds)::info());
   126         ls.print("UseSharedSpaces: ");
   126         ls.print("UseSharedSpaces: ");
   250   // the following 2 fields will be set in write_header for dynamic archive header
   250   // the following 2 fields will be set in write_header for dynamic archive header
   251   _base_archive_name_size = 0;
   251   _base_archive_name_size = 0;
   252   _base_archive_is_default = false;
   252   _base_archive_is_default = false;
   253 }
   253 }
   254 
   254 
   255 void SharedClassPathEntry::init(const char* name, bool is_modules_image, TRAPS) {
   255 void SharedClassPathEntry::init(bool is_modules_image,
       
   256                                 ClassPathEntry* cpe, TRAPS) {
   256   assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
   257   assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
   257   _timestamp = 0;
   258   _timestamp = 0;
   258   _filesize  = 0;
   259   _filesize  = 0;
       
   260   _from_class_path_attr = false;
   259 
   261 
   260   struct stat st;
   262   struct stat st;
   261   if (os::stat(name, &st) == 0) {
   263   if (os::stat(cpe->name(), &st) == 0) {
   262     if ((st.st_mode & S_IFMT) == S_IFDIR) {
   264     if ((st.st_mode & S_IFMT) == S_IFDIR) {
   263       _type = dir_entry;
   265       _type = dir_entry;
   264     } else {
   266     } else {
   265       // The timestamp of the modules_image is not checked at runtime.
   267       // The timestamp of the modules_image is not checked at runtime.
   266       if (is_modules_image) {
   268       if (is_modules_image) {
   267         _type = modules_image_entry;
   269         _type = modules_image_entry;
   268       } else {
   270       } else {
   269         _type = jar_entry;
   271         _type = jar_entry;
   270         _timestamp = st.st_mtime;
   272         _timestamp = st.st_mtime;
       
   273         _from_class_path_attr = cpe->from_class_path_attr();
   271       }
   274       }
   272       _filesize = st.st_size;
   275       _filesize = st.st_size;
   273     }
   276     }
   274   } else {
   277   } else {
   275     // The file/dir must exist, or it would not have been added
   278     // The file/dir must exist, or it would not have been added
   276     // into ClassLoader::classpath_entry().
   279     // into ClassLoader::classpath_entry().
   277     //
   280     //
   278     // If we can't access a jar file in the boot path, then we can't
   281     // If we can't access a jar file in the boot path, then we can't
   279     // make assumptions about where classes get loaded from.
   282     // make assumptions about where classes get loaded from.
   280     FileMapInfo::fail_stop("Unable to open file %s.", name);
   283     FileMapInfo::fail_stop("Unable to open file %s.", cpe->name());
   281   }
   284   }
   282 
   285 
   283   size_t len = strlen(name) + 1;
   286   size_t len = strlen(cpe->name()) + 1;
   284   _name = MetadataFactory::new_array<char>(ClassLoaderData::the_null_class_loader_data(), (int)len, THREAD);
   287   _name = MetadataFactory::new_array<char>(ClassLoaderData::the_null_class_loader_data(), (int)len, THREAD);
   285   strcpy(_name->data(), name);
   288   strcpy(_name->data(), cpe->name());
   286 }
   289 }
   287 
   290 
   288 bool SharedClassPathEntry::validate(bool is_class_path) {
   291 bool SharedClassPathEntry::validate(bool is_class_path) {
   289   assert(UseSharedSpaces, "runtime only");
   292   assert(UseSharedSpaces, "runtime only");
   290 
   293 
   379   while (cpe != NULL) {
   382   while (cpe != NULL) {
   380     bool is_jrt = (cpe == jrt);
   383     bool is_jrt = (cpe == jrt);
   381     const char* type = (is_jrt ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir"));
   384     const char* type = (is_jrt ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir"));
   382     log_info(class, path)("add main shared path (%s) %s", type, cpe->name());
   385     log_info(class, path)("add main shared path (%s) %s", type, cpe->name());
   383     SharedClassPathEntry* ent = shared_path(i);
   386     SharedClassPathEntry* ent = shared_path(i);
   384     ent->init(cpe->name(), is_jrt, THREAD);
   387     ent->init(is_jrt, cpe, THREAD);
   385     if (!is_jrt) {    // No need to do the modules image.
   388     if (!is_jrt) {    // No need to do the modules image.
   386       EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
   389       EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
   387       update_shared_classpath(cpe, ent, THREAD);
   390       update_shared_classpath(cpe, ent, THREAD);
   388     }
   391     }
   389     cpe = ClassLoader::get_next_boot_classpath_entry(cpe);
   392     cpe = ClassLoader::get_next_boot_classpath_entry(cpe);
   395   // 2. app class path
   398   // 2. app class path
   396   ClassPathEntry *acpe = ClassLoader::app_classpath_entries();
   399   ClassPathEntry *acpe = ClassLoader::app_classpath_entries();
   397   while (acpe != NULL) {
   400   while (acpe != NULL) {
   398     log_info(class, path)("add app shared path %s", acpe->name());
   401     log_info(class, path)("add app shared path %s", acpe->name());
   399     SharedClassPathEntry* ent = shared_path(i);
   402     SharedClassPathEntry* ent = shared_path(i);
   400     ent->init(acpe->name(), false, THREAD);
   403     ent->init(false, acpe, THREAD);
   401     EXCEPTION_MARK;
   404     EXCEPTION_MARK;
   402     update_shared_classpath(acpe, ent, THREAD);
   405     update_shared_classpath(acpe, ent, THREAD);
   403     acpe = acpe->next();
   406     acpe = acpe->next();
   404     i++;
   407     i++;
   405   }
   408   }
   407   // 3. module path
   410   // 3. module path
   408   ClassPathEntry *mpe = ClassLoader::module_path_entries();
   411   ClassPathEntry *mpe = ClassLoader::module_path_entries();
   409   while (mpe != NULL) {
   412   while (mpe != NULL) {
   410     log_info(class, path)("add module path %s",mpe->name());
   413     log_info(class, path)("add module path %s",mpe->name());
   411     SharedClassPathEntry* ent = shared_path(i);
   414     SharedClassPathEntry* ent = shared_path(i);
   412     ent->init(mpe->name(), false, THREAD);
   415     ent->init(false, mpe, THREAD);
   413     EXCEPTION_MARK;
   416     EXCEPTION_MARK;
   414     update_shared_classpath(mpe, ent, THREAD);
   417     update_shared_classpath(mpe, ent, THREAD);
   415     mpe = mpe->next();
   418     mpe = mpe->next();
   416     i++;
   419     i++;
   417   }
   420   }
   518       }
   521       }
   519     }
   522     }
   520   }
   523   }
   521 }
   524 }
   522 
   525 
       
   526 char* FileMapInfo::skip_first_path_entry(const char* path) {
       
   527   size_t path_sep_len = strlen(os::path_separator());
       
   528   char* p = strstr((char*)path, os::path_separator());
       
   529   if (p != NULL) {
       
   530     debug_only( {
       
   531       size_t image_name_len = strlen(MODULES_IMAGE_NAME);
       
   532       assert(strncmp(p - image_name_len, MODULES_IMAGE_NAME, image_name_len) == 0,
       
   533              "first entry must be the modules image");
       
   534     } );
       
   535     p += path_sep_len;
       
   536   } else {
       
   537     debug_only( {
       
   538       assert(ClassLoader::string_ends_with(path, MODULES_IMAGE_NAME),
       
   539              "first entry must be the modules image");
       
   540     } );
       
   541   }
       
   542   return p;
       
   543 }
       
   544 
       
   545 int FileMapInfo::num_paths(const char* path) {
       
   546   if (path == NULL) {
       
   547     return 0;
       
   548   }
       
   549   int npaths = 1;
       
   550   char* p = (char*)path;
       
   551   while (p != NULL) {
       
   552     char* prev = p;
       
   553     p = strstr((char*)p, os::path_separator());
       
   554     if (p != NULL) {
       
   555       p++;
       
   556       // don't count empty path
       
   557       if ((p - prev) > 1) {
       
   558        npaths++;
       
   559       }
       
   560     }
       
   561   }
       
   562   return npaths;
       
   563 }
       
   564 
       
   565 GrowableArray<char*>* FileMapInfo::create_path_array(const char* path) {
       
   566   GrowableArray<char*>* path_array =  new(ResourceObj::RESOURCE_AREA, mtInternal)
       
   567       GrowableArray<char*>(10);
       
   568   char* begin_ptr = (char*)path;
       
   569   char* end_ptr = strchr((char*)path, os::path_separator()[0]);
       
   570   if (end_ptr == NULL) {
       
   571     end_ptr = strchr((char*)path, '\0');
       
   572   }
       
   573   while (end_ptr != NULL) {
       
   574     if ((end_ptr - begin_ptr) > 1) {
       
   575       struct stat st;
       
   576       char* temp_name = NEW_RESOURCE_ARRAY(char, (size_t)(end_ptr - begin_ptr + 1));
       
   577       strncpy(temp_name, begin_ptr, end_ptr - begin_ptr);
       
   578       temp_name[end_ptr - begin_ptr] = '\0';
       
   579       if (os::stat(temp_name, &st) == 0) {
       
   580         path_array->append(temp_name);
       
   581       }
       
   582     }
       
   583     if (end_ptr < (path + strlen(path))) {
       
   584       begin_ptr = ++end_ptr;
       
   585       end_ptr = strchr(begin_ptr, os::path_separator()[0]);
       
   586       if (end_ptr == NULL) {
       
   587         end_ptr = strchr(begin_ptr, '\0');
       
   588       }
       
   589     } else {
       
   590       break;
       
   591     }
       
   592   }
       
   593   return path_array;
       
   594 }
       
   595 
       
   596 bool FileMapInfo::fail(const char* msg, const char* name) {
       
   597   ClassLoader::trace_class_path(msg, name);
       
   598   MetaspaceShared::set_archive_loading_failed();
       
   599   return false;
       
   600 }
       
   601 
       
   602 bool FileMapInfo::check_paths(int shared_path_start_idx, int num_paths, GrowableArray<char*>* rp_array) {
       
   603   int i = 0;
       
   604   int j = shared_path_start_idx;
       
   605   bool mismatch = false;
       
   606   while (i < num_paths && !mismatch) {
       
   607     while (shared_path(j)->from_class_path_attr()) {
       
   608       // shared_path(j) was expanded from the JAR file attribute "Class-Path:"
       
   609       // during dump time. It's not included in the -classpath VM argument.
       
   610       j++;
       
   611     }
       
   612     if (!os::same_files(shared_path(j)->name(), rp_array->at(i))) {
       
   613       mismatch = true;
       
   614     }
       
   615     i++;
       
   616     j++;
       
   617   }
       
   618   return mismatch;
       
   619 }
       
   620 
       
   621 bool FileMapInfo::validate_boot_class_paths() {
       
   622   //
       
   623   // - Archive contains boot classes only - relaxed boot path check:
       
   624   //   Extra path elements appended to the boot path at runtime are allowed.
       
   625   //
       
   626   // - Archive contains application or platform classes - strict boot path check:
       
   627   //   Validate the entire runtime boot path, which must be compatible
       
   628   //   with the dump time boot path. Appending boot path at runtime is not
       
   629   //   allowed.
       
   630   //
       
   631 
       
   632   // The first entry in boot path is the modules_image (guaranteed by
       
   633   // ClassLoader::setup_boot_search_path()). Skip the first entry. The
       
   634   // path of the runtime modules_image may be different from the dump
       
   635   // time path (e.g. the JDK image is copied to a different location
       
   636   // after generating the shared archive), which is acceptable. For most
       
   637   // common cases, the dump time boot path might contain modules_image only.
       
   638   char* runtime_boot_path = Arguments::get_sysclasspath();
       
   639   char* rp = skip_first_path_entry(runtime_boot_path);
       
   640   assert(shared_path(0)->is_modules_image(), "first shared_path must be the modules image");
       
   641   int dp_len = _header->_app_class_paths_start_index - 1; // ignore the first path to the module image
       
   642   bool mismatch = false;
       
   643 
       
   644   bool relaxed_check = !header()->has_platform_or_app_classes();
       
   645   if (dp_len == 0 && rp == NULL) {
       
   646     return true;   // ok, both runtime and dump time boot paths have modules_images only
       
   647   } else if (dp_len == 0 && rp != NULL) {
       
   648     if (relaxed_check) {
       
   649       return true;   // ok, relaxed check, runtime has extra boot append path entries
       
   650     } else {
       
   651       mismatch = true;
       
   652     }
       
   653   } else if (dp_len > 0 && rp != NULL) {
       
   654     int num;
       
   655     ResourceMark rm;
       
   656     GrowableArray<char*>* rp_array = create_path_array(rp);
       
   657     int rp_len = rp_array->length();
       
   658     if (rp_len >= dp_len) {
       
   659       if (relaxed_check) {
       
   660         // only check the leading entries in the runtime boot path, up to
       
   661         // the length of the dump time boot path
       
   662         num = dp_len;
       
   663       } else {
       
   664         // check the full runtime boot path, must match with dump time
       
   665         num = rp_len;
       
   666       }
       
   667       mismatch = check_paths(1, num, rp_array);
       
   668     }
       
   669   }
       
   670 
       
   671   if (mismatch) {
       
   672     // The paths are different
       
   673     return fail("[BOOT classpath mismatch, actual =", runtime_boot_path);
       
   674   }
       
   675   return true;
       
   676 }
       
   677 
       
   678 bool FileMapInfo::validate_app_class_paths(int shared_app_paths_len) {
       
   679   const char *appcp = Arguments::get_appclasspath();
       
   680   assert(appcp != NULL, "NULL app classpath");
       
   681   int rp_len = num_paths(appcp);
       
   682   bool mismatch = false;
       
   683   if (rp_len < shared_app_paths_len) {
       
   684     return fail("Run time APP classpath is shorter than the one at dump time: ", appcp);
       
   685   }
       
   686   if (shared_app_paths_len != 0 && rp_len != 0) {
       
   687     // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar.
       
   688     ResourceMark rm;
       
   689     GrowableArray<char*>* rp_array = create_path_array(appcp);
       
   690     if (rp_array->length() == 0) {
       
   691       // None of the jar file specified in the runtime -cp exists.
       
   692       return fail("None of the jar file specified in the runtime -cp exists: -Djava.class.path=", appcp);
       
   693     }
       
   694     int j = _header->_app_class_paths_start_index;
       
   695     mismatch = check_paths(j, shared_app_paths_len, rp_array);
       
   696     if (mismatch) {
       
   697       return fail("[APP classpath mismatch, actual: -Djava.class.path=", appcp);
       
   698     }
       
   699   }
       
   700   return true;
       
   701 }
   523 
   702 
   524 bool FileMapInfo::validate_shared_path_table() {
   703 bool FileMapInfo::validate_shared_path_table() {
   525   assert(UseSharedSpaces, "runtime only");
   704   assert(UseSharedSpaces, "runtime only");
   526 
   705 
   527   _validating_shared_path_table = true;
   706   _validating_shared_path_table = true;
   548         "Dynamic archiving is disabled because base layer archive has module path");
   727         "Dynamic archiving is disabled because base layer archive has module path");
   549     }
   728     }
   550   }
   729   }
   551 
   730 
   552   int module_paths_start_index = _header->_app_module_paths_start_index;
   731   int module_paths_start_index = _header->_app_module_paths_start_index;
       
   732   int shared_app_paths_len = 0;
   553 
   733 
   554   // validate the path entries up to the _max_used_path_index
   734   // validate the path entries up to the _max_used_path_index
   555   for (int i=0; i < _header->_max_used_path_index + 1; i++) {
   735   for (int i=0; i < _header->_max_used_path_index + 1; i++) {
   556     if (i < module_paths_start_index) {
   736     if (i < module_paths_start_index) {
   557       if (shared_path(i)->validate()) {
   737       if (shared_path(i)->validate()) {
       
   738         // Only count the app class paths not from the "Class-path" attribute of a jar manifest.
       
   739         if (!shared_path(i)->from_class_path_attr() && i >= _header->_app_class_paths_start_index) {
       
   740           shared_app_paths_len++;
       
   741         }
   558         log_info(class, path)("ok");
   742         log_info(class, path)("ok");
   559       } else {
   743       } else {
   560         if (_dynamic_archive_info != NULL && _dynamic_archive_info->_is_static) {
   744         if (_dynamic_archive_info != NULL && _dynamic_archive_info->_is_static) {
   561           assert(!UseSharedSpaces, "UseSharedSpaces should be disabled");
   745           assert(!UseSharedSpaces, "UseSharedSpaces should be disabled");
   562         }
   746         }
   572         return false;
   756         return false;
   573       }
   757       }
   574     }
   758     }
   575   }
   759   }
   576 
   760 
       
   761   if (_header->_max_used_path_index == 0) {
       
   762     // default archive only contains the module image in the bootclasspath
       
   763     assert(shared_path(0)->is_modules_image(), "first shared_path must be the modules image");
       
   764   } else {
       
   765     if (!validate_boot_class_paths() || !validate_app_class_paths(shared_app_paths_len)) {
       
   766       fail_continue("shared class paths mismatch (hint: enable -Xlog:class+path=info to diagnose the failure)");
       
   767       return false;
       
   768     }
       
   769   }
       
   770 
   577   _validating_shared_path_table = false;
   771   _validating_shared_path_table = false;
   578 
   772 
   579 #if INCLUDE_JVMTI
   773 #if INCLUDE_JVMTI
   580   if (_classpath_entries_for_jvmti != NULL) {
   774   if (_classpath_entries_for_jvmti != NULL) {
   581     os::free(_classpath_entries_for_jvmti);
   775     os::free(_classpath_entries_for_jvmti);
   584   _classpath_entries_for_jvmti = (ClassPathEntry**)os::malloc(sz, mtClass);
   778   _classpath_entries_for_jvmti = (ClassPathEntry**)os::malloc(sz, mtClass);
   585   memset((void*)_classpath_entries_for_jvmti, 0, sz);
   779   memset((void*)_classpath_entries_for_jvmti, 0, sz);
   586 #endif
   780 #endif
   587 
   781 
   588   return true;
   782   return true;
   589 }
       
   590 
       
   591 bool FileMapInfo::same_files(const char* file1, const char* file2) {
       
   592   if (strcmp(file1, file2) == 0) {
       
   593     return true;
       
   594   }
       
   595 
       
   596   bool is_same = false;
       
   597   // if the two paths diff only in case
       
   598   struct stat st1;
       
   599   struct stat st2;
       
   600   int ret1;
       
   601   int ret2;
       
   602   ret1 = os::stat(file1, &st1);
       
   603   ret2 = os::stat(file2, &st2);
       
   604   if (ret1 < 0 || ret2 < 0) {
       
   605     // one of the files is invalid. So they are not the same.
       
   606     is_same = false;
       
   607   } else if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) {
       
   608     // different files
       
   609     is_same = false;
       
   610 #ifndef _WINDOWS
       
   611   } else if (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino) {
       
   612     // same files
       
   613     is_same = true;
       
   614 #else
       
   615   } else if ((st1.st_size == st2.st_size) && (st1.st_ctime == st2.st_ctime) &&
       
   616              (st1.st_mtime == st2.st_mtime)) {
       
   617     // same files
       
   618     is_same = true;
       
   619 #endif
       
   620   }
       
   621   return is_same;
       
   622 }
   783 }
   623 
   784 
   624 bool FileMapInfo::check_archive(const char* archive_name, bool is_static) {
   785 bool FileMapInfo::check_archive(const char* archive_name, bool is_static) {
   625   int fd = os::open(archive_name, O_RDONLY | O_BINARY, 0);
   786   int fd = os::open(archive_name, O_RDONLY | O_BINARY, 0);
   626   if (fd < 0) {
   787   if (fd < 0) {
  1747       if (os::stat(path, &st) != 0) {
  1908       if (os::stat(path, &st) != 0) {
  1748         char *msg = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, strlen(path) + 128); ;
  1909         char *msg = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, strlen(path) + 128); ;
  1749         jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path);
  1910         jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path);
  1750         THROW_MSG_(vmSymbols::java_io_IOException(), msg, NULL);
  1911         THROW_MSG_(vmSymbols::java_io_IOException(), msg, NULL);
  1751       } else {
  1912       } else {
  1752         ent = ClassLoader::create_class_path_entry(path, &st, /*throw_exception=*/true, false, CHECK_NULL);
  1913         ent = ClassLoader::create_class_path_entry(path, &st, /*throw_exception=*/true, false, false, CHECK_NULL);
  1753       }
  1914       }
  1754     }
  1915     }
  1755 
  1916 
  1756     MutexLocker mu(CDSClassFileStream_lock, THREAD);
  1917     MutexLocker mu(CDSClassFileStream_lock, THREAD);
  1757     if (_classpath_entries_for_jvmti[i] == NULL) {
  1918     if (_classpath_entries_for_jvmti[i] == NULL) {