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 {
|