527 } |
537 } |
528 // Obtain java.lang.Module, if available |
538 // Obtain java.lang.Module, if available |
529 Handle module_handle(THREAD, ((module_entry != NULL) ? module_entry->module() : (oop)NULL)); |
539 Handle module_handle(THREAD, ((module_entry != NULL) ? module_entry->module() : (oop)NULL)); |
530 |
540 |
531 if (this->has_raw_archived_mirror()) { |
541 if (this->has_raw_archived_mirror()) { |
|
542 ResourceMark rm; |
532 log_debug(cds, mirror)("%s has raw archived mirror", external_name()); |
543 log_debug(cds, mirror)("%s has raw archived mirror", external_name()); |
533 if (MetaspaceShared::open_archive_heap_region_mapped()) { |
544 if (MetaspaceShared::open_archive_heap_region_mapped()) { |
534 oop m = archived_java_mirror(); |
545 bool present = java_lang_Class::restore_archived_mirror(this, loader, module_handle, |
535 log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m)); |
546 protection_domain, |
536 if (m != NULL) { |
547 CHECK); |
537 // mirror is archived, restore |
548 if (present) { |
538 assert(MetaspaceShared::is_archive_object(m), "must be archived mirror object"); |
|
539 Handle m_h(THREAD, m); |
|
540 java_lang_Class::restore_archived_mirror(this, m_h, loader, module_handle, protection_domain, CHECK); |
|
541 return; |
549 return; |
542 } |
550 } |
543 } |
551 } |
544 |
552 |
545 // No archived mirror data |
553 // No archived mirror data |
|
554 log_debug(cds, mirror)("No archived mirror data for %s", external_name()); |
546 _java_mirror = NULL; |
555 _java_mirror = NULL; |
547 this->clear_has_raw_archived_mirror(); |
556 this->clear_has_raw_archived_mirror(); |
548 } |
557 } |
549 |
558 |
550 // Only recreate it if not present. A previous attempt to restore may have |
559 // Only recreate it if not present. A previous attempt to restore may have |
762 int limit = vtable_length()/vtableEntry::size(); |
768 int limit = vtable_length()/vtableEntry::size(); |
763 assert(i >= 0 && i < limit, "index %d out of bounds %d", i, limit); |
769 assert(i >= 0 && i < limit, "index %d out of bounds %d", i, limit); |
764 return true; |
770 return true; |
765 } |
771 } |
766 |
772 |
767 bool Klass::verify_itable_index(int i) { |
|
768 assert(is_instance_klass(), ""); |
|
769 int method_count = klassItable::method_count_for_interface(this); |
|
770 assert(i >= 0 && i < method_count, "index out of bounds"); |
|
771 return true; |
|
772 } |
|
773 |
|
774 #endif // PRODUCT |
773 #endif // PRODUCT |
775 |
774 |
776 // The caller of class_loader_and_module_name() (or one of its callers) |
775 // Caller needs ResourceMark |
777 // must use a ResourceMark in order to correctly free the result. |
776 // joint_in_module_of_loader provides an optimization if 2 classes are in |
778 const char* Klass::class_loader_and_module_name() const { |
777 // the same module to succinctly print out relevant information about their |
779 const char* delim = "/"; |
778 // module name and class loader's name_and_id for error messages. |
780 size_t delim_len = strlen(delim); |
779 // Format: |
781 |
780 // <fully-qualified-external-class-name1> and <fully-qualified-external-class-name2> |
782 const char* fqn = external_name(); |
781 // are in module <module-name>[@<version>] |
783 // Length of message to return; always include FQN |
782 // of loader <loader-name_and_id>[, parent loader <parent-loader-name_and_id>] |
784 size_t msglen = strlen(fqn) + 1; |
783 const char* Klass::joint_in_module_of_loader(const Klass* class2, bool include_parent_loader) const { |
785 |
784 assert(module() == class2->module(), "classes do not have the same module"); |
786 bool has_cl_name = false; |
785 const char* class1_name = external_name(); |
787 bool has_mod_name = false; |
786 size_t len = strlen(class1_name) + 1; |
788 bool has_version = false; |
787 |
789 |
788 const char* class2_description = class2->class_in_module_of_loader(true, include_parent_loader); |
790 // Use class loader name, if exists and not builtin |
789 len += strlen(class2_description); |
791 const char* class_loader_name = ""; |
790 |
792 ClassLoaderData* cld = class_loader_data(); |
791 len += strlen(" and "); |
793 assert(cld != NULL, "class_loader_data should not be NULL"); |
792 |
794 if (!cld->is_builtin_class_loader_data()) { |
793 char* joint_description = NEW_RESOURCE_ARRAY_RETURN_NULL(char, len); |
795 // If not builtin, look for name |
794 |
796 oop loader = class_loader(); |
795 // Just return the FQN if error when allocating string |
797 if (loader != NULL) { |
796 if (joint_description == NULL) { |
798 oop class_loader_name_oop = java_lang_ClassLoader::name(loader); |
797 return class1_name; |
799 if (class_loader_name_oop != NULL) { |
798 } |
800 class_loader_name = java_lang_String::as_utf8_string(class_loader_name_oop); |
799 |
801 if (class_loader_name != NULL && class_loader_name[0] != '\0') { |
800 jio_snprintf(joint_description, len, "%s and %s", |
802 has_cl_name = true; |
801 class1_name, |
803 msglen += strlen(class_loader_name) + delim_len; |
802 class2_description); |
804 } |
803 |
805 } |
804 return joint_description; |
806 } |
805 } |
807 } |
806 |
808 |
807 // Caller needs ResourceMark |
|
808 // class_in_module_of_loader provides a standard way to include |
|
809 // relevant information about a class, such as its module name as |
|
810 // well as its class loader's name_and_id, in error messages and logging. |
|
811 // Format: |
|
812 // <fully-qualified-external-class-name> is in module <module-name>[@<version>] |
|
813 // of loader <loader-name_and_id>[, parent loader <parent-loader-name_and_id>] |
|
814 const char* Klass::class_in_module_of_loader(bool use_are, bool include_parent_loader) const { |
|
815 // 1. fully qualified external name of class |
|
816 const char* klass_name = external_name(); |
|
817 size_t len = strlen(klass_name) + 1; |
|
818 |
|
819 // 2. module name + @version |
809 const char* module_name = ""; |
820 const char* module_name = ""; |
810 const char* version = ""; |
821 const char* version = ""; |
|
822 bool has_version = false; |
|
823 bool module_is_named = false; |
|
824 const char* module_name_phrase = ""; |
811 const Klass* bottom_klass = is_objArray_klass() ? |
825 const Klass* bottom_klass = is_objArray_klass() ? |
812 ObjArrayKlass::cast(this)->bottom_klass() : this; |
826 ObjArrayKlass::cast(this)->bottom_klass() : this; |
813 if (bottom_klass->is_instance_klass()) { |
827 if (bottom_klass->is_instance_klass()) { |
814 ModuleEntry* module = InstanceKlass::cast(bottom_klass)->module(); |
828 ModuleEntry* module = InstanceKlass::cast(bottom_klass)->module(); |
815 // Use module name, if exists |
|
816 if (module->is_named()) { |
829 if (module->is_named()) { |
817 has_mod_name = true; |
830 module_is_named = true; |
|
831 module_name_phrase = "module "; |
818 module_name = module->name()->as_C_string(); |
832 module_name = module->name()->as_C_string(); |
819 msglen += strlen(module_name); |
833 len += strlen(module_name); |
820 // Use version if exists and is not a jdk module |
834 // Use version if exists and is not a jdk module |
821 if (module->is_non_jdk_module() && module->version() != NULL) { |
835 if (module->should_show_version()) { |
822 has_version = true; |
836 has_version = true; |
823 version = module->version()->as_C_string(); |
837 version = module->version()->as_C_string(); |
824 msglen += strlen("@") + strlen(version); |
838 // Include stlen(version) + 1 for the "@" |
|
839 len += strlen(version) + 1; |
825 } |
840 } |
|
841 } else { |
|
842 module_name = UNNAMED_MODULE; |
|
843 len += UNNAMED_MODULE_LEN; |
826 } |
844 } |
827 } else { |
845 } else { |
828 // klass is an array of primitives, so its module is java.base |
846 // klass is an array of primitives, module is java.base |
|
847 module_is_named = true; |
|
848 module_name_phrase = "module "; |
829 module_name = JAVA_BASE_NAME; |
849 module_name = JAVA_BASE_NAME; |
830 } |
850 len += JAVA_BASE_NAME_LEN; |
831 |
851 } |
832 if (has_cl_name || has_mod_name) { |
852 |
833 msglen += delim_len; |
853 // 3. class loader's name_and_id |
834 } |
854 ClassLoaderData* cld = class_loader_data(); |
835 |
855 assert(cld != NULL, "class_loader_data should not be null"); |
836 char* message = NEW_RESOURCE_ARRAY_RETURN_NULL(char, msglen); |
856 const char* loader_name_and_id = cld->loader_name_and_id(); |
837 |
857 len += strlen(loader_name_and_id); |
838 // Just return the FQN if error in allocating string |
858 |
839 if (message == NULL) { |
859 // 4. include parent loader information |
840 return fqn; |
860 const char* parent_loader_phrase = ""; |
841 } |
861 const char* parent_loader_name_and_id = ""; |
842 |
862 if (include_parent_loader && |
843 jio_snprintf(message, msglen, "%s%s%s%s%s%s%s", |
863 !cld->is_builtin_class_loader_data()) { |
844 class_loader_name, |
864 oop parent_loader = java_lang_ClassLoader::parent(class_loader()); |
845 (has_cl_name) ? delim : "", |
865 ClassLoaderData *parent_cld = ClassLoaderData::class_loader_data(parent_loader); |
846 (has_mod_name) ? module_name : "", |
866 assert(parent_cld != NULL, "parent's class loader data should not be null"); |
|
867 parent_loader_name_and_id = parent_cld->loader_name_and_id(); |
|
868 parent_loader_phrase = ", parent loader "; |
|
869 len += strlen(parent_loader_phrase) + strlen(parent_loader_name_and_id); |
|
870 } |
|
871 |
|
872 // Start to construct final full class description string |
|
873 len += ((use_are) ? strlen(" are in ") : strlen(" is in ")); |
|
874 len += strlen(module_name_phrase) + strlen(" of loader "); |
|
875 |
|
876 char* class_description = NEW_RESOURCE_ARRAY_RETURN_NULL(char, len); |
|
877 |
|
878 // Just return the FQN if error when allocating string |
|
879 if (class_description == NULL) { |
|
880 return klass_name; |
|
881 } |
|
882 |
|
883 jio_snprintf(class_description, len, "%s %s in %s%s%s%s of loader %s%s%s", |
|
884 klass_name, |
|
885 (use_are) ? "are" : "is", |
|
886 module_name_phrase, |
|
887 module_name, |
847 (has_version) ? "@" : "", |
888 (has_version) ? "@" : "", |
848 (has_version) ? version : "", |
889 (has_version) ? version : "", |
849 (has_cl_name || has_mod_name) ? delim : "", |
890 loader_name_and_id, |
850 fqn); |
891 parent_loader_phrase, |
851 return message; |
892 parent_loader_name_and_id); |
852 } |
893 |
|
894 return class_description; |
|
895 } |