638 } else if (!resolved_klass->is_interface()) {
639 return resolve_method(link_info, code, THREAD);
640 } else {
641 return resolve_interface_method(link_info, code, THREAD);
642 }
643 }
644
645 // Check and print a loader constraint violation message for method or interface method
646 void LinkResolver::check_method_loader_constraints(const LinkInfo& link_info,
647 const methodHandle& resolved_method,
648 const char* method_type, TRAPS) {
649 Handle current_loader(THREAD, link_info.current_klass()->class_loader());
650 Handle resolved_loader(THREAD, resolved_method->method_holder()->class_loader());
651
652 ResourceMark rm(THREAD);
653 Symbol* failed_type_symbol =
654 SystemDictionary::check_signature_loaders(link_info.signature(), current_loader,
655 resolved_loader, true, CHECK);
656 if (failed_type_symbol != NULL) {
657 const char* msg = "loader constraint violation: when resolving %s"
658 " \"%s\" the class loader (instance of %s) of the current class, %s,"
659 " and the class loader (instance of %s) for the method's defining class, %s, have"
660 " different Class objects for the type %s used in the signature";
661 char* sig = link_info.method_string();
662 const char* loader1_name = SystemDictionary::loader_name(current_loader());
663 char* current = link_info.current_klass()->name()->as_C_string();
664 const char* loader2_name = SystemDictionary::loader_name(resolved_loader());
665 char* target = resolved_method->method_holder()->name()->as_C_string();
666 char* failed_type_name = failed_type_symbol->as_C_string();
667 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1_name) +
668 strlen(current) + strlen(loader2_name) + strlen(target) +
669 strlen(failed_type_name) + strlen(method_type) + 1;
670 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
671 jio_snprintf(buf, buflen, msg, method_type, sig, loader1_name, current, loader2_name,
672 target, failed_type_name);
673 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
674 }
675 }
676
677 void LinkResolver::check_field_loader_constraints(Symbol* field, Symbol* sig,
678 Klass* current_klass,
679 Klass* sel_klass, TRAPS) {
680 Handle ref_loader(THREAD, current_klass->class_loader());
681 Handle sel_loader(THREAD, sel_klass->class_loader());
682
683 ResourceMark rm(THREAD); // needed for check_signature_loaders
684 Symbol* failed_type_symbol =
685 SystemDictionary::check_signature_loaders(sig,
686 ref_loader, sel_loader,
687 false,
688 CHECK);
689 if (failed_type_symbol != NULL) {
690 const char* msg = "loader constraint violation: when resolving field"
691 " \"%s\" the class loader (instance of %s) of the referring class, "
692 "%s, and the class loader (instance of %s) for the field's resolved "
693 "type, %s, have different Class objects for that type";
694 char* field_name = field->as_C_string();
695 const char* loader1_name = SystemDictionary::loader_name(ref_loader());
696 char* sel = sel_klass->name()->as_C_string();
697 const char* loader2_name = SystemDictionary::loader_name(sel_loader());
698 char* failed_type_name = failed_type_symbol->as_C_string();
699 size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1_name) +
700 strlen(sel) + strlen(loader2_name) + strlen(failed_type_name) + 1;
701 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
702 jio_snprintf(buf, buflen, msg, field_name, loader1_name, sel, loader2_name,
703 failed_type_name);
704 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
705 }
706 }
707
708 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
709 Bytecodes::Code code, TRAPS) {
710
711 Handle nested_exception;
712 Klass* resolved_klass = link_info.resolved_klass();
713
714 // 1. For invokevirtual, cannot call an interface method
715 if (code == Bytecodes::_invokevirtual && resolved_klass->is_interface()) {
716 ResourceMark rm(THREAD);
717 char buf[200];
|
638 } else if (!resolved_klass->is_interface()) {
639 return resolve_method(link_info, code, THREAD);
640 } else {
641 return resolve_interface_method(link_info, code, THREAD);
642 }
643 }
644
645 // Check and print a loader constraint violation message for method or interface method
646 void LinkResolver::check_method_loader_constraints(const LinkInfo& link_info,
647 const methodHandle& resolved_method,
648 const char* method_type, TRAPS) {
649 Handle current_loader(THREAD, link_info.current_klass()->class_loader());
650 Handle resolved_loader(THREAD, resolved_method->method_holder()->class_loader());
651
652 ResourceMark rm(THREAD);
653 Symbol* failed_type_symbol =
654 SystemDictionary::check_signature_loaders(link_info.signature(), current_loader,
655 resolved_loader, true, CHECK);
656 if (failed_type_symbol != NULL) {
657 const char* msg = "loader constraint violation: when resolving %s"
658 " \"%s\" the class loader %s of the current class, %s,"
659 " and the class loader %s for the method's defining class, %s, have"
660 " different Class objects for the type %s used in the signature";
661 char* sig = link_info.method_string();
662 const char* loader1_name = java_lang_ClassLoader::describe_external(current_loader());
663 char* current = link_info.current_klass()->name()->as_C_string();
664 const char* loader2_name = java_lang_ClassLoader::describe_external(resolved_loader());
665 char* target = resolved_method->method_holder()->name()->as_C_string();
666 char* failed_type_name = failed_type_symbol->as_C_string();
667 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1_name) +
668 strlen(current) + strlen(loader2_name) + strlen(target) +
669 strlen(failed_type_name) + strlen(method_type) + 1;
670 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
671 jio_snprintf(buf, buflen, msg, method_type, sig, loader1_name, current, loader2_name,
672 target, failed_type_name);
673 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
674 }
675 }
676
677 void LinkResolver::check_field_loader_constraints(Symbol* field, Symbol* sig,
678 Klass* current_klass,
679 Klass* sel_klass, TRAPS) {
680 Handle ref_loader(THREAD, current_klass->class_loader());
681 Handle sel_loader(THREAD, sel_klass->class_loader());
682
683 ResourceMark rm(THREAD); // needed for check_signature_loaders
684 Symbol* failed_type_symbol =
685 SystemDictionary::check_signature_loaders(sig,
686 ref_loader, sel_loader,
687 false,
688 CHECK);
689 if (failed_type_symbol != NULL) {
690 const char* msg = "loader constraint violation: when resolving field"
691 " \"%s\" the class loader %s of the referring class, "
692 "%s, and the class loader %s for the field's resolved "
693 "type, %s, have different Class objects for that type";
694 char* field_name = field->as_C_string();
695 const char* loader1_name = java_lang_ClassLoader::describe_external(ref_loader());
696 char* sel = sel_klass->name()->as_C_string();
697 const char* loader2_name = java_lang_ClassLoader::describe_external(sel_loader());
698 char* failed_type_name = failed_type_symbol->as_C_string();
699 size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1_name) +
700 strlen(sel) + strlen(loader2_name) + strlen(failed_type_name) + 1;
701 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
702 jio_snprintf(buf, buflen, msg, field_name, loader1_name, sel, loader2_name,
703 failed_type_name);
704 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
705 }
706 }
707
708 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
709 Bytecodes::Code code, TRAPS) {
710
711 Handle nested_exception;
712 Klass* resolved_klass = link_info.resolved_klass();
713
714 // 1. For invokevirtual, cannot call an interface method
715 if (code == Bytecodes::_invokevirtual && resolved_klass->is_interface()) {
716 ResourceMark rm(THREAD);
717 char buf[200];
|