comparison src/share/vm/interpreter/linkResolver.cpp @ 13413:7a58803b5069

8026066: ICCE for invokeinterface static Reviewed-by: coleenp, lfoltan, hseigel
author acorn
date Tue, 03 Dec 2013 08:36:15 -0800
parents 22eaa15b7960
children 379f11bc04fc
comparison
equal deleted inserted replaced
13412:6ce6a0d23467 13413:7a58803b5069
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