240 // |
240 // |
241 // According to JVM spec. $5.4.3c & $5.4.3d |
241 // According to JVM spec. $5.4.3c & $5.4.3d |
242 |
242 |
243 // Look up method in klasses, including static methods |
243 // Look up method in klasses, including static methods |
244 // Then look up local default methods |
244 // Then look up local default methods |
245 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
245 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, TRAPS) { |
246 Method* result_oop = klass->uncached_lookup_method(name, signature); |
246 Method* result_oop = klass->uncached_lookup_method(name, signature); |
247 if (result_oop == NULL) { |
247 if (result_oop == NULL) { |
248 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods(); |
248 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods(); |
249 if (default_methods != NULL) { |
249 if (default_methods != NULL) { |
250 result_oop = InstanceKlass::find_method(default_methods, name, signature); |
250 result_oop = InstanceKlass::find_method(default_methods, name, signature); |
251 } |
251 } |
252 } |
252 } |
253 |
253 |
254 if (EnableInvokeDynamic && result_oop != NULL) { |
254 if (checkpolymorphism && EnableInvokeDynamic && result_oop != NULL) { |
255 vmIntrinsics::ID iid = result_oop->intrinsic_id(); |
255 vmIntrinsics::ID iid = result_oop->intrinsic_id(); |
256 if (MethodHandles::is_signature_polymorphic(iid)) { |
256 if (MethodHandles::is_signature_polymorphic(iid)) { |
257 // Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method. |
257 // Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method. |
258 return; |
258 return; |
259 } |
259 } |
501 return; |
501 return; |
502 } |
502 } |
503 } |
503 } |
504 |
504 |
505 if (code == Bytecodes::_invokeinterface) { |
505 if (code == Bytecodes::_invokeinterface) { |
506 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); |
506 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); |
507 } else if (code == Bytecodes::_invokevirtual) { |
507 } else if (code == Bytecodes::_invokevirtual) { |
508 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); |
508 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); |
|
509 } else if (!resolved_klass->is_interface()) { |
|
510 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK); |
509 } else { |
511 } else { |
510 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK); |
512 bool nostatics = (code == Bytecodes::_invokestatic) ? false : true; |
|
513 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, nostatics, CHECK); |
511 } |
514 } |
512 } |
515 } |
513 |
516 |
514 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass, |
517 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass, |
515 Symbol* method_name, Symbol* method_signature, |
518 Symbol* method_name, Symbol* method_signature, |
526 resolved_klass()->external_name()); |
529 resolved_klass()->external_name()); |
527 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
530 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
528 } |
531 } |
529 |
532 |
530 // 2. lookup method in resolved klass and its super klasses |
533 // 2. lookup method in resolved klass and its super klasses |
531 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); |
534 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, CHECK); |
532 |
535 |
533 if (resolved_method.is_null()) { // not found in the class hierarchy |
536 if (resolved_method.is_null()) { // not found in the class hierarchy |
534 // 3. lookup method in all the interfaces implemented by the resolved klass |
537 // 3. lookup method in all the interfaces implemented by the resolved klass |
535 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); |
538 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); |
536 |
539 |
610 void LinkResolver::resolve_interface_method(methodHandle& resolved_method, |
613 void LinkResolver::resolve_interface_method(methodHandle& resolved_method, |
611 KlassHandle resolved_klass, |
614 KlassHandle resolved_klass, |
612 Symbol* method_name, |
615 Symbol* method_name, |
613 Symbol* method_signature, |
616 Symbol* method_signature, |
614 KlassHandle current_klass, |
617 KlassHandle current_klass, |
615 bool check_access, TRAPS) { |
618 bool check_access, |
|
619 bool nostatics, TRAPS) { |
616 |
620 |
617 // check if klass is interface |
621 // check if klass is interface |
618 if (!resolved_klass->is_interface()) { |
622 if (!resolved_klass->is_interface()) { |
619 ResourceMark rm(THREAD); |
623 ResourceMark rm(THREAD); |
620 char buf[200]; |
624 char buf[200]; |
621 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name()); |
625 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name()); |
622 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
626 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
623 } |
627 } |
624 |
628 |
625 // lookup method in this interface or its super, java.lang.Object |
629 // lookup method in this interface or its super, java.lang.Object |
626 lookup_instance_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); |
630 // JDK8: also look for static methods |
|
631 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, CHECK); |
627 |
632 |
628 if (resolved_method.is_null()) { |
633 if (resolved_method.is_null()) { |
629 // lookup method in all the super-interfaces |
634 // lookup method in all the super-interfaces |
630 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); |
635 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); |
631 if (resolved_method.is_null()) { |
636 if (resolved_method.is_null()) { |
635 Method::name_and_sig_as_C_string(resolved_klass(), |
640 Method::name_and_sig_as_C_string(resolved_klass(), |
636 method_name, |
641 method_name, |
637 method_signature)); |
642 method_signature)); |
638 } |
643 } |
639 } |
644 } |
|
645 |
|
646 if (nostatics && resolved_method->is_static()) { |
|
647 ResourceMark rm(THREAD); |
|
648 char buf[200]; |
|
649 jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", Method::name_and_sig_as_C_string(resolved_klass(), |
|
650 resolved_method->name(), |
|
651 resolved_method->signature())); |
|
652 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
|
653 } |
|
654 |
640 |
655 |
641 if (check_access) { |
656 if (check_access) { |
642 // JDK8 adds non-public interface methods, and accessability check requirement |
657 // JDK8 adds non-public interface methods, and accessability check requirement |
643 assert(current_klass.not_null() , "current_klass should not be null"); |
658 assert(current_klass.not_null() , "current_klass should not be null"); |
644 |
659 |
862 // throws linktime exceptions |
877 // throws linktime exceptions |
863 void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, KlassHandle resolved_klass, |
878 void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, KlassHandle resolved_klass, |
864 Symbol* method_name, Symbol* method_signature, |
879 Symbol* method_name, Symbol* method_signature, |
865 KlassHandle current_klass, bool check_access, TRAPS) { |
880 KlassHandle current_klass, bool check_access, TRAPS) { |
866 |
881 |
867 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); |
882 if (!resolved_klass->is_interface()) { |
|
883 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); |
|
884 } else { |
|
885 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); |
|
886 } |
868 assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier"); |
887 assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier"); |
869 |
888 |
870 // check if static |
889 // check if static |
871 if (!resolved_method->is_static()) { |
890 if (!resolved_method->is_static()) { |
872 ResourceMark rm(THREAD); |
891 ResourceMark rm(THREAD); |
896 // local private method invocation, for classes and interfaces |
915 // local private method invocation, for classes and interfaces |
897 // superclass.method, which can also resolve to a default method |
916 // superclass.method, which can also resolve to a default method |
898 // and the selected method is recalculated relative to the direct superclass |
917 // and the selected method is recalculated relative to the direct superclass |
899 // superinterface.method, which explicitly does not check shadowing |
918 // superinterface.method, which explicitly does not check shadowing |
900 |
919 |
901 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); |
920 if (!resolved_klass->is_interface()) { |
|
921 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); |
|
922 } else { |
|
923 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK); |
|
924 } |
902 |
925 |
903 // check if method name is <init>, that it is found in same klass as static type |
926 // check if method name is <init>, that it is found in same klass as static type |
904 if (resolved_method->name() == vmSymbols::object_initializer_name() && |
927 if (resolved_method->name() == vmSymbols::object_initializer_name() && |
905 resolved_method->method_holder() != resolved_klass()) { |
928 resolved_method->method_holder() != resolved_klass()) { |
906 ResourceMark rm(THREAD); |
929 ResourceMark rm(THREAD); |
1217 |
1240 |
1218 // throws linktime exceptions |
1241 // throws linktime exceptions |
1219 void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, |
1242 void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, |
1220 Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { |
1243 Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { |
1221 // normal interface method resolution |
1244 // normal interface method resolution |
1222 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); |
1245 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK); |
1223 |
1246 |
1224 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); |
1247 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); |
1225 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); |
1248 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); |
1226 } |
1249 } |
1227 |
1250 |