652 return resolve_method(link_info, code, THREAD);
653 } else if (!resolved_klass->is_interface()) {
654 return resolve_method(link_info, code, THREAD);
655 } else {
656 return resolve_interface_method(link_info, code, THREAD);
657 }
658 }
659
660 // Check and print a loader constraint violation message for method or interface method
661 void LinkResolver::check_method_loader_constraints(const LinkInfo& link_info,
662 const methodHandle& resolved_method,
663 const char* method_type, TRAPS) {
664 Handle current_loader(THREAD, link_info.current_klass()->class_loader());
665 Handle resolved_loader(THREAD, resolved_method->method_holder()->class_loader());
666
667 ResourceMark rm(THREAD);
668 Symbol* failed_type_symbol =
669 SystemDictionary::check_signature_loaders(link_info.signature(), current_loader,
670 resolved_loader, true, CHECK);
671 if (failed_type_symbol != NULL) {
672 const char* msg = "loader constraint violation: when resolving %s"
673 " \"%s\" the class loader %s of the current class, %s,"
674 " and the class loader %s for the method's defining class, %s, have"
675 " different Class objects for the type %s used in the signature";
676 char* sig = link_info.method_string();
677 const char* loader1_name = java_lang_ClassLoader::describe_external(current_loader());
678 char* current = link_info.current_klass()->name()->as_C_string();
679 const char* loader2_name = java_lang_ClassLoader::describe_external(resolved_loader());
680 char* target = resolved_method->method_holder()->name()->as_C_string();
681 char* failed_type_name = failed_type_symbol->as_C_string();
682 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1_name) +
683 strlen(current) + strlen(loader2_name) + strlen(target) +
684 strlen(failed_type_name) + strlen(method_type) + 1;
685 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
686 jio_snprintf(buf, buflen, msg, method_type, sig, loader1_name, current, loader2_name,
687 target, failed_type_name);
688 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
689 }
690 }
691
692 void LinkResolver::check_field_loader_constraints(Symbol* field, Symbol* sig,
693 Klass* current_klass,
694 Klass* sel_klass, TRAPS) {
695 Handle ref_loader(THREAD, current_klass->class_loader());
696 Handle sel_loader(THREAD, sel_klass->class_loader());
697
698 ResourceMark rm(THREAD); // needed for check_signature_loaders
699 Symbol* failed_type_symbol =
700 SystemDictionary::check_signature_loaders(sig,
701 ref_loader, sel_loader,
702 false,
703 CHECK);
704 if (failed_type_symbol != NULL) {
705 const char* msg = "loader constraint violation: when resolving field"
706 " \"%s\" of type %s, the class loader %s of the current class, "
707 "%s, and the class loader %s for the field's defining "
708 "type, %s, have different Class objects for type %s";
709 const char* field_name = field->as_C_string();
710 const char* loader1_name = java_lang_ClassLoader::describe_external(ref_loader());
711 const char* sel = sel_klass->external_name();
712 const char* loader2_name = java_lang_ClassLoader::describe_external(sel_loader());
713 const char* failed_type_name = failed_type_symbol->as_klass_external_name();
714 const char* curr_klass_name = current_klass->external_name();
715 size_t buflen = strlen(msg) + strlen(field_name) + 2 * strlen(failed_type_name) +
716 strlen(loader1_name) + strlen(curr_klass_name) +
717 strlen(loader2_name) + strlen(sel) + 1;
718 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
719 jio_snprintf(buf, buflen, msg, field_name, failed_type_name, loader1_name,
720 curr_klass_name, loader2_name, sel, failed_type_name);
721 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
722 }
723 }
724
725 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
726 Bytecodes::Code code, TRAPS) {
727
728 Handle nested_exception;
729 Klass* resolved_klass = link_info.resolved_klass();
730
731 // 1. For invokevirtual, cannot call an interface method
732 if (code == Bytecodes::_invokevirtual && resolved_klass->is_interface()) {
733 ResourceMark rm(THREAD);
734 char buf[200];
735 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
736 resolved_klass->external_name());
737 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
738 }
739
740 // 2. check constant pool tag for called method - must be JVM_CONSTANT_Methodref
741 if (!link_info.tag().is_invalid() && !link_info.tag().is_method()) {
|
652 return resolve_method(link_info, code, THREAD);
653 } else if (!resolved_klass->is_interface()) {
654 return resolve_method(link_info, code, THREAD);
655 } else {
656 return resolve_interface_method(link_info, code, THREAD);
657 }
658 }
659
660 // Check and print a loader constraint violation message for method or interface method
661 void LinkResolver::check_method_loader_constraints(const LinkInfo& link_info,
662 const methodHandle& resolved_method,
663 const char* method_type, TRAPS) {
664 Handle current_loader(THREAD, link_info.current_klass()->class_loader());
665 Handle resolved_loader(THREAD, resolved_method->method_holder()->class_loader());
666
667 ResourceMark rm(THREAD);
668 Symbol* failed_type_symbol =
669 SystemDictionary::check_signature_loaders(link_info.signature(), current_loader,
670 resolved_loader, true, CHECK);
671 if (failed_type_symbol != NULL) {
672 Klass* current_class = link_info.current_klass();
673 ClassLoaderData* current_loader_data = current_class->class_loader_data();
674 assert(current_loader_data != NULL, "current class has no class loader data");
675 Klass* resolved_method_class = resolved_method->method_holder();
676 ClassLoaderData* target_loader_data = resolved_method_class->class_loader_data();
677 assert(target_loader_data != NULL, "resolved method's class has no class loader data");
678
679 stringStream ss;
680 ss.print("loader constraint violation: when resolving %s"
681 " \"%s\" the class loader %s of the current class, %s,"
682 " and the class loader %s for the method's defining class, %s, have"
683 " different Class objects for the type %s used in the signature (%s; %s)",
684 method_type,
685 link_info.method_string(),
686 current_loader_data->loader_name_and_id(),
687 current_class->name()->as_C_string(),
688 target_loader_data->loader_name_and_id(),
689 resolved_method_class->name()->as_C_string(),
690 failed_type_symbol->as_C_string(),
691 current_class->class_in_module_of_loader(false, true),
692 resolved_method_class->class_in_module_of_loader(false, true));
693 THROW_MSG(vmSymbols::java_lang_LinkageError(), ss.as_string());
694 }
695 }
696
697 void LinkResolver::check_field_loader_constraints(Symbol* field, Symbol* sig,
698 Klass* current_klass,
699 Klass* sel_klass, TRAPS) {
700 Handle ref_loader(THREAD, current_klass->class_loader());
701 Handle sel_loader(THREAD, sel_klass->class_loader());
702
703 ResourceMark rm(THREAD); // needed for check_signature_loaders
704 Symbol* failed_type_symbol =
705 SystemDictionary::check_signature_loaders(sig,
706 ref_loader, sel_loader,
707 false,
708 CHECK);
709 if (failed_type_symbol != NULL) {
710 stringStream ss;
711 const char* failed_type_name = failed_type_symbol->as_klass_external_name();
712
713 ss.print("loader constraint violation: when resolving field"
714 " \"%s\" of type %s, the class loader %s of the current class, "
715 "%s, and the class loader %s for the field's defining "
716 "type, %s, have different Class objects for type %s (%s; %s)",
717 field->as_C_string(),
718 failed_type_name,
719 current_klass->class_loader_data()->loader_name_and_id(),
720 current_klass->external_name(),
721 sel_klass->class_loader_data()->loader_name_and_id(),
722 sel_klass->external_name(),
723 failed_type_name,
724 current_klass->class_in_module_of_loader(false, true),
725 sel_klass->class_in_module_of_loader(false, true));
726 THROW_MSG(vmSymbols::java_lang_LinkageError(), ss.as_string());
727 }
728 }
729
730 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
731 Bytecodes::Code code, TRAPS) {
732
733 Handle nested_exception;
734 Klass* resolved_klass = link_info.resolved_klass();
735
736 // 1. For invokevirtual, cannot call an interface method
737 if (code == Bytecodes::_invokevirtual && resolved_klass->is_interface()) {
738 ResourceMark rm(THREAD);
739 char buf[200];
740 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
741 resolved_klass->external_name());
742 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
743 }
744
745 // 2. check constant pool tag for called method - must be JVM_CONSTANT_Methodref
746 if (!link_info.tag().is_invalid() && !link_info.tag().is_method()) {
|