Mercurial > hg > truffle
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 |