comparison src/share/vm/interpreter/linkResolver.cpp @ 12858:2f8728d92483

8026299: invokespecial gets ICCE when it should get AME. Reviewed-by: ccheung, coleenp
author acorn
date Mon, 14 Oct 2013 21:52:42 -0400
parents ac9cb1d5a202
children 8f4bb1773fd9 d248425bcfe8
comparison
equal deleted inserted replaced
12857:d37a0525c0fe 12858:2f8728d92483
452 if (code == Bytecodes::_invokedynamic) { 452 if (code == Bytecodes::_invokedynamic) {
453 resolved_klass = SystemDictionary::MethodHandle_klass(); 453 resolved_klass = SystemDictionary::MethodHandle_klass();
454 Symbol* method_name = vmSymbols::invoke_name(); 454 Symbol* method_name = vmSymbols::invoke_name();
455 Symbol* method_signature = pool->signature_ref_at(index); 455 Symbol* method_signature = pool->signature_ref_at(index);
456 KlassHandle current_klass(THREAD, pool->pool_holder()); 456 KlassHandle current_klass(THREAD, pool->pool_holder());
457 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); 457 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK);
458 return; 458 return;
459 } 459 }
460 460
461 resolve_klass(resolved_klass, pool, index, CHECK); 461 resolve_klass(resolved_klass, pool, index, CHECK);
462 462
474 } 474 }
475 } 475 }
476 476
477 if (code == Bytecodes::_invokeinterface) { 477 if (code == Bytecodes::_invokeinterface) {
478 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); 478 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
479 } else if (code == Bytecodes::_invokevirtual) {
480 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
479 } else { 481 } else {
480 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); 482 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK);
481 } 483 }
482 } 484 }
483 485
484 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass, 486 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
485 Symbol* method_name, Symbol* method_signature, 487 Symbol* method_name, Symbol* method_signature,
486 KlassHandle current_klass, bool check_access, TRAPS) { 488 KlassHandle current_klass, bool check_access,
489 bool require_methodref, TRAPS) {
487 490
488 Handle nested_exception; 491 Handle nested_exception;
489 492
490 // 1. lookup method in resolved klass and its super klasses 493 // 1. check if methodref required, that resolved_klass is not interfacemethodref
494 if (require_methodref && resolved_klass->is_interface()) {
495 ResourceMark rm(THREAD);
496 char buf[200];
497 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
498 resolved_klass()->external_name());
499 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
500 }
501
502 // 2. lookup method in resolved klass and its super klasses
491 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); 503 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
492 504
493 if (resolved_method.is_null()) { // not found in the class hierarchy 505 if (resolved_method.is_null()) { // not found in the class hierarchy
494 // 2. lookup method in all the interfaces implemented by the resolved klass 506 // 3. lookup method in all the interfaces implemented by the resolved klass
495 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); 507 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
496 508
497 if (resolved_method.is_null()) { 509 if (resolved_method.is_null()) {
498 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc 510 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
499 lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature, 511 lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature,
503 CLEAR_PENDING_EXCEPTION; 515 CLEAR_PENDING_EXCEPTION;
504 } 516 }
505 } 517 }
506 518
507 if (resolved_method.is_null()) { 519 if (resolved_method.is_null()) {
508 // 3. method lookup failed 520 // 4. method lookup failed
509 ResourceMark rm(THREAD); 521 ResourceMark rm(THREAD);
510 THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(), 522 THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
511 Method::name_and_sig_as_C_string(resolved_klass(), 523 Method::name_and_sig_as_C_string(resolved_klass(),
512 method_name, 524 method_name,
513 method_signature), 525 method_signature),
514 nested_exception); 526 nested_exception);
515 } 527 }
516 }
517
518 // 4. check if klass is not interface
519 if (resolved_klass->is_interface() && resolved_method->is_abstract()) {
520 ResourceMark rm(THREAD);
521 char buf[200];
522 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
523 resolved_klass()->external_name());
524 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
525 } 528 }
526 529
527 // 5. check if method is concrete 530 // 5. check if method is concrete
528 if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) { 531 if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) {
529 ResourceMark rm(THREAD); 532 ResourceMark rm(THREAD);
831 // throws linktime exceptions 834 // throws linktime exceptions
832 void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, KlassHandle resolved_klass, 835 void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, KlassHandle resolved_klass,
833 Symbol* method_name, Symbol* method_signature, 836 Symbol* method_name, Symbol* method_signature,
834 KlassHandle current_klass, bool check_access, TRAPS) { 837 KlassHandle current_klass, bool check_access, TRAPS) {
835 838
836 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); 839 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
837 assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier"); 840 assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
838 841
839 // check if static 842 // check if static
840 if (!resolved_method->is_static()) { 843 if (!resolved_method->is_static()) {
841 ResourceMark rm(THREAD); 844 ResourceMark rm(THREAD);
865 // local private method invocation, for classes and interfaces 868 // local private method invocation, for classes and interfaces
866 // superclass.method, which can also resolve to a default method 869 // superclass.method, which can also resolve to a default method
867 // and the selected method is recalculated relative to the direct superclass 870 // and the selected method is recalculated relative to the direct superclass
868 // superinterface.method, which explicitly does not check shadowing 871 // superinterface.method, which explicitly does not check shadowing
869 872
870 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); 873 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
871 874
872 // check if method name is <init>, that it is found in same klass as static type 875 // check if method name is <init>, that it is found in same klass as static type
873 if (resolved_method->name() == vmSymbols::object_initializer_name() && 876 if (resolved_method->name() == vmSymbols::object_initializer_name() &&
874 resolved_method->method_holder() != resolved_klass()) { 877 resolved_method->method_holder() != resolved_klass()) {
875 ResourceMark rm(THREAD); 878 ResourceMark rm(THREAD);
1011 // throws linktime exceptions 1014 // throws linktime exceptions
1012 void LinkResolver::linktime_resolve_virtual_method(methodHandle &resolved_method, KlassHandle resolved_klass, 1015 void LinkResolver::linktime_resolve_virtual_method(methodHandle &resolved_method, KlassHandle resolved_klass,
1013 Symbol* method_name, Symbol* method_signature, 1016 Symbol* method_name, Symbol* method_signature,
1014 KlassHandle current_klass, bool check_access, TRAPS) { 1017 KlassHandle current_klass, bool check_access, TRAPS) {
1015 // normal method resolution 1018 // normal method resolution
1016 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); 1019 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
1017 1020
1018 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); 1021 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
1019 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); 1022 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
1020 1023
1021 // check if private interface method 1024 // check if private interface method