comparison src/share/vm/interpreter/linkResolver.cpp @ 6934:4735d2c84362

7200776: Implement default methods in interfaces Summary: Add generic type analysis and default method selection algorithms Reviewed-by: coleenp, acorn
author kamg
date Thu, 11 Oct 2012 12:25:42 -0400
parents f6b0eb4e44cf
children 18fb7da42534
comparison
equal deleted inserted replaced
6921:a1b8cf9cf970 6934:4735d2c84362
21 * questions. 21 * questions.
22 * 22 *
23 */ 23 */
24 24
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "classfile/defaultMethods.hpp"
26 #include "classfile/systemDictionary.hpp" 27 #include "classfile/systemDictionary.hpp"
27 #include "classfile/vmSymbols.hpp" 28 #include "classfile/vmSymbols.hpp"
28 #include "compiler/compileBroker.hpp" 29 #include "compiler/compileBroker.hpp"
29 #include "gc_interface/collectedHeap.inline.hpp" 30 #include "gc_interface/collectedHeap.inline.hpp"
30 #include "interpreter/bytecode.hpp" 31 #include "interpreter/bytecode.hpp"
402 403
403 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass, 404 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
404 Symbol* method_name, Symbol* method_signature, 405 Symbol* method_name, Symbol* method_signature,
405 KlassHandle current_klass, bool check_access, TRAPS) { 406 KlassHandle current_klass, bool check_access, TRAPS) {
406 407
407 // 1. check if klass is not interface
408 if (resolved_klass->is_interface()) {
409 ResourceMark rm(THREAD);
410 char buf[200];
411 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", Klass::cast(resolved_klass())->external_name());
412 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
413 }
414
415 Handle nested_exception; 408 Handle nested_exception;
416 409
417 // 2. lookup method in resolved klass and its super klasses 410 // 1. lookup method in resolved klass and its super klasses
418 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); 411 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
419 412
420 if (resolved_method.is_null()) { // not found in the class hierarchy 413 if (resolved_method.is_null()) { // not found in the class hierarchy
421 // 3. lookup method in all the interfaces implemented by the resolved klass 414 // 2. lookup method in all the interfaces implemented by the resolved klass
422 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); 415 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
423 416
424 if (resolved_method.is_null()) { 417 if (resolved_method.is_null()) {
425 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc 418 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
426 lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature, 419 lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature,
430 CLEAR_PENDING_EXCEPTION; 423 CLEAR_PENDING_EXCEPTION;
431 } 424 }
432 } 425 }
433 426
434 if (resolved_method.is_null()) { 427 if (resolved_method.is_null()) {
435 // 4. method lookup failed 428 // 3. method lookup failed
436 ResourceMark rm(THREAD); 429 ResourceMark rm(THREAD);
437 THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(), 430 THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
438 Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), 431 Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
439 method_name, 432 method_name,
440 method_signature), 433 method_signature),
441 nested_exception); 434 nested_exception);
442 } 435 }
436 }
437
438 // 4. check if klass is not interface
439 if (resolved_klass->is_interface() && resolved_method->is_abstract()) {
440 ResourceMark rm(THREAD);
441 char buf[200];
442 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
443 resolved_klass()->external_name());
444 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
443 } 445 }
444 446
445 // 5. check if method is concrete 447 // 5. check if method is concrete
446 if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) { 448 if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) {
447 ResourceMark rm(THREAD); 449 ResourceMark rm(THREAD);
741 // throws linktime exceptions 743 // throws linktime exceptions
742 void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass, 744 void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass,
743 Symbol* method_name, Symbol* method_signature, 745 Symbol* method_name, Symbol* method_signature,
744 KlassHandle current_klass, bool check_access, TRAPS) { 746 KlassHandle current_klass, bool check_access, TRAPS) {
745 747
748 if (resolved_klass->is_interface() && current_klass() != NULL) {
749 // If the target class is a direct interface, treat this as a "super"
750 // default call.
751 //
752 // If the current method is an overpass that happens to call a direct
753 // super-interface's method, then we'll end up rerunning the default method
754 // analysis even though we don't need to, but that's ok since it will end
755 // up with the same answer.
756 InstanceKlass* ik = InstanceKlass::cast(current_klass());
757 Array<Klass*>* interfaces = ik->local_interfaces();
758 int num_interfaces = interfaces->length();
759 for (int index = 0; index < num_interfaces; index++) {
760 if (interfaces->at(index) == resolved_klass()) {
761 Method* method = DefaultMethods::find_super_default(current_klass(),
762 resolved_klass(), method_name, method_signature, CHECK);
763 resolved_method = methodHandle(THREAD, method);
764 return;
765 }
766 }
767 }
768
746 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); 769 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
747 770
748 // check if method name is <init>, that it is found in same klass as static type 771 // check if method name is <init>, that it is found in same klass as static type
749 if (resolved_method->name() == vmSymbols::object_initializer_name() && 772 if (resolved_method->name() == vmSymbols::object_initializer_name() &&
750 resolved_method->method_holder() != resolved_klass()) { 773 resolved_method->method_holder() != resolved_klass()) {
782 805
783 // check if this is an old-style super call and do a new lookup if so 806 // check if this is an old-style super call and do a new lookup if so
784 { KlassHandle method_klass = KlassHandle(THREAD, 807 { KlassHandle method_klass = KlassHandle(THREAD,
785 resolved_method->method_holder()); 808 resolved_method->method_holder());
786 809
787 if (check_access && 810 const bool direct_calling_default_method =
811 resolved_klass() != NULL && resolved_method() != NULL &&
812 resolved_klass->is_interface() && !resolved_method->is_abstract();
813
814 if (!direct_calling_default_method &&
815 check_access &&
788 // a) check if ACC_SUPER flag is set for the current class 816 // a) check if ACC_SUPER flag is set for the current class
789 current_klass->is_super() && 817 current_klass->is_super() &&
790 // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!) 818 // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!)
791 current_klass->is_subtype_of(method_klass()) && current_klass() != method_klass() && 819 current_klass->is_subtype_of(method_klass()) &&
820 current_klass() != method_klass() &&
792 // c) check if the method is not <init> 821 // c) check if the method is not <init>
793 resolved_method->name() != vmSymbols::object_initializer_name()) { 822 resolved_method->name() != vmSymbols::object_initializer_name()) {
794 // Lookup super method 823 // Lookup super method
795 KlassHandle super_klass(THREAD, current_klass->super()); 824 KlassHandle super_klass(THREAD, current_klass->super());
796 lookup_instance_method_in_klasses(sel_method, super_klass, 825 lookup_instance_method_in_klasses(sel_method, super_klass,