< prev index next >

src/hotspot/share/cds/aotClassLocation.cpp

Print this page

  30 #include "cds/metaspaceShared.hpp"
  31 #include "cds/serializeClosure.hpp"
  32 #include "classfile/classLoader.hpp"
  33 #include "classfile/classLoaderData.hpp"
  34 #include "classfile/javaClasses.hpp"
  35 #include "logging/log.hpp"
  36 #include "logging/logStream.hpp"
  37 #include "memory/metadataFactory.hpp"
  38 #include "memory/metaspaceClosure.hpp"
  39 #include "memory/resourceArea.hpp"
  40 #include "oops/array.hpp"
  41 #include "oops/objArrayKlass.hpp"
  42 #include "runtime/arguments.hpp"
  43 #include "utilities/classpathStream.hpp"
  44 #include "utilities/formatBuffer.hpp"
  45 #include "utilities/stringUtils.hpp"
  46 
  47 #include <sys/stat.h>
  48 #include <errno.h>
  49 

  50 AOTClassLocationConfig* AOTClassLocationConfig::_dumptime_instance = nullptr;
  51 const AOTClassLocationConfig* AOTClassLocationConfig::_runtime_instance = nullptr;
  52 
  53 // A ClassLocationStream represents a list of code locations, which can be iterated using
  54 // start() and has_next().
  55 class ClassLocationStream {
  56 protected:
  57   GrowableArray<const char*> _array;
  58   int _current;
  59 
  60   // Add one path to this stream.
  61   void add_one_path(const char* path) {
  62     _array.append(path);
  63   }
  64 
  65   // Add all paths specified in cp; cp must be from -classpath or -Xbootclasspath/a.
  66   void add_paths_in_classpath(const char* cp) {
  67     ClasspathStream cp_stream(cp);
  68     while (cp_stream.has_next()) {
  69       add_one_path(cp_stream.get_next());

 462   AOTClassLocation* jrt = AOTClassLocation::allocate(THREAD, ClassLoader::get_jrt_entry()->name(),
 463                                                0, Group::MODULES_IMAGE,
 464                                                /*from_cpattr*/false, /*is_jrt*/true);
 465   tmp_array.append(jrt);
 466 
 467   parse(THREAD, tmp_array, all_css.boot_cp(), Group::BOOT_CLASSPATH, /*parse_manifest*/true);
 468   _boot_classpath_end = tmp_array.length();
 469 
 470   parse(THREAD, tmp_array, all_css.app_cp(), Group::APP_CLASSPATH, /*parse_manifest*/true);
 471   _app_classpath_end = tmp_array.length();
 472 
 473   parse(THREAD, tmp_array, all_css.module_path(), Group::MODULE_PATH, /*parse_manifest*/false);
 474   _module_end = tmp_array.length();
 475 
 476   _class_locations =  MetadataFactory::new_array<AOTClassLocation*>(ClassLoaderData::the_null_class_loader_data(),
 477                                                                tmp_array.length(), CHECK);
 478   for (int i = 0; i < tmp_array.length(); i++) {
 479     _class_locations->at_put(i, tmp_array.at(i));
 480   }
 481 







 482   const char* lcp = find_lcp(all_css.boot_and_app_cp(), _dumptime_lcp_len);
 483   if (_dumptime_lcp_len > 0) {
 484     os::free((void*)lcp);
 485     log_info(class, path)("Longest common prefix = %s (%zu chars)", lcp, _dumptime_lcp_len);
 486   } else {
 487     assert(_dumptime_lcp_len == 0, "sanity");
 488     log_info(class, path)("Longest common prefix = <none> (0 chars)");
 489   }
 490 
 491   _has_non_jar_modules = all_css.module_path().has_non_jar_modules();
 492   _has_platform_classes = false;
 493   _has_app_classes = false;
 494   _max_used_index = 0;
 495 }
 496 
 497 // Find the longest common prefix of two paths, up to max_lcp_len.
 498 // E.g.   p1 = "/a/b/foo"
 499 //        p2 = "/a/b/bar"
 500 //        max_lcp_len = 3
 501 // -> returns 3

 623           if (strcmp(tmp_array.at(i)->path(), libname) == 0) {
 624             found_duplicate = true;
 625             break;
 626           }
 627         }
 628         if (!found_duplicate) {
 629           add_class_location(current, tmp_array, libname, group, parse_manifest, /*from_cpattr*/true);
 630         }
 631       }
 632 
 633       file_start = file_end;
 634     }
 635   }
 636 }
 637 
 638 AOTClassLocation const* AOTClassLocationConfig::class_location_at(int index) const {
 639   return _class_locations->at(index);
 640 }
 641 
 642 int AOTClassLocationConfig::get_module_shared_path_index(Symbol* location) const {




 643   if (location->starts_with("jrt:", 4)) {
 644     assert(class_location_at(0)->is_modules_image(), "sanity");
 645     return 0;
 646   }
 647 
 648   if (num_module_paths() == 0) {
 649     // The archive(s) were created without --module-path option
 650     return -1;
 651   }
 652 
 653   if (!location->starts_with("file:", 5)) {
 654     return -1;
 655   }
 656 
 657   // skip_uri_protocol was also called during dump time -- see ClassLoaderExt::process_module_table()
 658   ResourceMark rm;
 659   const char* file = ClassLoader::uri_to_path(location->as_C_string());
 660   for (int i = module_path_start_index(); i < module_path_end_index(); i++) {
 661     const AOTClassLocation* cs = class_location_at(i);
 662     assert(!cs->has_unnamed_module(), "must be");

 676 
 677   bool has_nonempty_dir = false;
 678   dumptime_iterate([&](AOTClassLocation* cs) {
 679     if (cs->index() > _max_used_index) {
 680       return false; // stop iterating
 681     }
 682     if (cs->is_dir()) {
 683       if (!os::dir_is_empty(cs->path())) {
 684         log_error(cds)("Error: non-empty directory '%s'", cs->path());
 685         has_nonempty_dir = true;
 686       }
 687     }
 688     return true; // keep iterating
 689   });
 690 
 691   if (has_nonempty_dir) {
 692     vm_exit_during_cds_dumping("Cannot have non-empty directory in paths", nullptr);
 693   }
 694 }
 695 





















 696 AOTClassLocationConfig* AOTClassLocationConfig::write_to_archive() const {
 697   Array<AOTClassLocation*>* archived_copy = ArchiveBuilder::new_ro_array<AOTClassLocation*>(_class_locations->length());
 698   for (int i = 0; i < _class_locations->length(); i++) {
 699     archived_copy->at_put(i, _class_locations->at(i)->write_to_archive());
 700     ArchivePtrMarker::mark_pointer((address*)archived_copy->adr_at(i));
 701   }
 702 
 703   AOTClassLocationConfig* dumped = (AOTClassLocationConfig*)ArchiveBuilder::ro_region_alloc(sizeof(AOTClassLocationConfig));
 704   memcpy(dumped, this, sizeof(AOTClassLocationConfig));
 705   dumped->_class_locations = archived_copy;
 706   ArchivePtrMarker::mark_pointer(&dumped->_class_locations);
 707 
 708   return dumped;
 709 }
 710 
 711 bool AOTClassLocationConfig::check_classpaths(bool is_boot_classpath, bool has_aot_linked_classes,
 712                                               int index_start, int index_end,
 713                                               ClassLocationStream& runtime_css,
 714                                               bool use_lcp_match, const char* runtime_lcp,
 715                                               size_t runtime_lcp_len) const {

  30 #include "cds/metaspaceShared.hpp"
  31 #include "cds/serializeClosure.hpp"
  32 #include "classfile/classLoader.hpp"
  33 #include "classfile/classLoaderData.hpp"
  34 #include "classfile/javaClasses.hpp"
  35 #include "logging/log.hpp"
  36 #include "logging/logStream.hpp"
  37 #include "memory/metadataFactory.hpp"
  38 #include "memory/metaspaceClosure.hpp"
  39 #include "memory/resourceArea.hpp"
  40 #include "oops/array.hpp"
  41 #include "oops/objArrayKlass.hpp"
  42 #include "runtime/arguments.hpp"
  43 #include "utilities/classpathStream.hpp"
  44 #include "utilities/formatBuffer.hpp"
  45 #include "utilities/stringUtils.hpp"
  46 
  47 #include <sys/stat.h>
  48 #include <errno.h>
  49 
  50 Array<ClassPathZipEntry*>* AOTClassLocationConfig::_dumptime_jar_files = nullptr;
  51 AOTClassLocationConfig* AOTClassLocationConfig::_dumptime_instance = nullptr;
  52 const AOTClassLocationConfig* AOTClassLocationConfig::_runtime_instance = nullptr;
  53 
  54 // A ClassLocationStream represents a list of code locations, which can be iterated using
  55 // start() and has_next().
  56 class ClassLocationStream {
  57 protected:
  58   GrowableArray<const char*> _array;
  59   int _current;
  60 
  61   // Add one path to this stream.
  62   void add_one_path(const char* path) {
  63     _array.append(path);
  64   }
  65 
  66   // Add all paths specified in cp; cp must be from -classpath or -Xbootclasspath/a.
  67   void add_paths_in_classpath(const char* cp) {
  68     ClasspathStream cp_stream(cp);
  69     while (cp_stream.has_next()) {
  70       add_one_path(cp_stream.get_next());

 463   AOTClassLocation* jrt = AOTClassLocation::allocate(THREAD, ClassLoader::get_jrt_entry()->name(),
 464                                                0, Group::MODULES_IMAGE,
 465                                                /*from_cpattr*/false, /*is_jrt*/true);
 466   tmp_array.append(jrt);
 467 
 468   parse(THREAD, tmp_array, all_css.boot_cp(), Group::BOOT_CLASSPATH, /*parse_manifest*/true);
 469   _boot_classpath_end = tmp_array.length();
 470 
 471   parse(THREAD, tmp_array, all_css.app_cp(), Group::APP_CLASSPATH, /*parse_manifest*/true);
 472   _app_classpath_end = tmp_array.length();
 473 
 474   parse(THREAD, tmp_array, all_css.module_path(), Group::MODULE_PATH, /*parse_manifest*/false);
 475   _module_end = tmp_array.length();
 476 
 477   _class_locations =  MetadataFactory::new_array<AOTClassLocation*>(ClassLoaderData::the_null_class_loader_data(),
 478                                                                tmp_array.length(), CHECK);
 479   for (int i = 0; i < tmp_array.length(); i++) {
 480     _class_locations->at_put(i, tmp_array.at(i));
 481   }
 482 
 483   _dumptime_jar_files = MetadataFactory::new_array<ClassPathZipEntry*>(ClassLoaderData::the_null_class_loader_data(),
 484                                                                        tmp_array.length(), CHECK);
 485   for (int i = 1; i < tmp_array.length(); i++) {
 486     ClassPathZipEntry* jar_file = ClassLoader::create_class_path_zip_entry(tmp_array.at(i)->path());
 487     _dumptime_jar_files->at_put(i, jar_file); // may be null if the path is not a valid JAR file
 488   }
 489 
 490   const char* lcp = find_lcp(all_css.boot_and_app_cp(), _dumptime_lcp_len);
 491   if (_dumptime_lcp_len > 0) {
 492     os::free((void*)lcp);
 493     log_info(class, path)("Longest common prefix = %s (%zu chars)", lcp, _dumptime_lcp_len);
 494   } else {
 495     assert(_dumptime_lcp_len == 0, "sanity");
 496     log_info(class, path)("Longest common prefix = <none> (0 chars)");
 497   }
 498 
 499   _has_non_jar_modules = all_css.module_path().has_non_jar_modules();
 500   _has_platform_classes = false;
 501   _has_app_classes = false;
 502   _max_used_index = 0;
 503 }
 504 
 505 // Find the longest common prefix of two paths, up to max_lcp_len.
 506 // E.g.   p1 = "/a/b/foo"
 507 //        p2 = "/a/b/bar"
 508 //        max_lcp_len = 3
 509 // -> returns 3

 631           if (strcmp(tmp_array.at(i)->path(), libname) == 0) {
 632             found_duplicate = true;
 633             break;
 634           }
 635         }
 636         if (!found_duplicate) {
 637           add_class_location(current, tmp_array, libname, group, parse_manifest, /*from_cpattr*/true);
 638         }
 639       }
 640 
 641       file_start = file_end;
 642     }
 643   }
 644 }
 645 
 646 AOTClassLocation const* AOTClassLocationConfig::class_location_at(int index) const {
 647   return _class_locations->at(index);
 648 }
 649 
 650 int AOTClassLocationConfig::get_module_shared_path_index(Symbol* location) const {
 651   if (location == nullptr) {
 652     return 0; // Used by java/lang/reflect/Proxy$ProxyBuilder
 653   }
 654 
 655   if (location->starts_with("jrt:", 4)) {
 656     assert(class_location_at(0)->is_modules_image(), "sanity");
 657     return 0;
 658   }
 659 
 660   if (num_module_paths() == 0) {
 661     // The archive(s) were created without --module-path option
 662     return -1;
 663   }
 664 
 665   if (!location->starts_with("file:", 5)) {
 666     return -1;
 667   }
 668 
 669   // skip_uri_protocol was also called during dump time -- see ClassLoaderExt::process_module_table()
 670   ResourceMark rm;
 671   const char* file = ClassLoader::uri_to_path(location->as_C_string());
 672   for (int i = module_path_start_index(); i < module_path_end_index(); i++) {
 673     const AOTClassLocation* cs = class_location_at(i);
 674     assert(!cs->has_unnamed_module(), "must be");

 688 
 689   bool has_nonempty_dir = false;
 690   dumptime_iterate([&](AOTClassLocation* cs) {
 691     if (cs->index() > _max_used_index) {
 692       return false; // stop iterating
 693     }
 694     if (cs->is_dir()) {
 695       if (!os::dir_is_empty(cs->path())) {
 696         log_error(cds)("Error: non-empty directory '%s'", cs->path());
 697         has_nonempty_dir = true;
 698       }
 699     }
 700     return true; // keep iterating
 701   });
 702 
 703   if (has_nonempty_dir) {
 704     vm_exit_during_cds_dumping("Cannot have non-empty directory in paths", nullptr);
 705   }
 706 }
 707 
 708 // It's possible to use reflection+setAccessible to call into ClassLoader::defineClass() to
 709 // pretend that a dynamically generated class comes from a JAR file in the classpath.
 710 // Detect such classes and exclude them from the archive.
 711 void AOTClassLocationConfig::check_invalid_classpath_index(int classpath_index, InstanceKlass* ik) {
 712   if (1 <= classpath_index && classpath_index < length()) {
 713     ClassPathZipEntry *zip = _dumptime_jar_files->at(classpath_index);
 714     if (zip != nullptr) {
 715       JavaThread* current = JavaThread::current();
 716       ResourceMark rm(current);
 717       const char* const class_name = ik->name()->as_C_string();
 718       const char* const file_name = ClassLoader::file_name_for_class_name(class_name,
 719                                                                           ik->name()->utf8_length());
 720       if (!zip->has_entry(current, file_name)) {
 721         log_warning(cds)("class %s cannot be archived because it was not define from %s as claimed",
 722                          class_name, zip->name());
 723         ik->set_shared_classpath_index(-1);
 724       }
 725     }
 726   }
 727 }
 728 
 729 AOTClassLocationConfig* AOTClassLocationConfig::write_to_archive() const {
 730   Array<AOTClassLocation*>* archived_copy = ArchiveBuilder::new_ro_array<AOTClassLocation*>(_class_locations->length());
 731   for (int i = 0; i < _class_locations->length(); i++) {
 732     archived_copy->at_put(i, _class_locations->at(i)->write_to_archive());
 733     ArchivePtrMarker::mark_pointer((address*)archived_copy->adr_at(i));
 734   }
 735 
 736   AOTClassLocationConfig* dumped = (AOTClassLocationConfig*)ArchiveBuilder::ro_region_alloc(sizeof(AOTClassLocationConfig));
 737   memcpy(dumped, this, sizeof(AOTClassLocationConfig));
 738   dumped->_class_locations = archived_copy;
 739   ArchivePtrMarker::mark_pointer(&dumped->_class_locations);
 740 
 741   return dumped;
 742 }
 743 
 744 bool AOTClassLocationConfig::check_classpaths(bool is_boot_classpath, bool has_aot_linked_classes,
 745                                               int index_start, int index_end,
 746                                               ClassLocationStream& runtime_css,
 747                                               bool use_lcp_match, const char* runtime_lcp,
 748                                               size_t runtime_lcp_len) const {
< prev index next >