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