Mercurial > hg > truffle
comparison src/share/vm/classfile/defaultMethods.cpp @ 12140:915cc4f3fb15
8020489: VM crash when non-existent interface called by invokespecial
Reviewed-by: kamg, coleenp
author | acorn |
---|---|
date | Wed, 28 Aug 2013 08:15:01 -0400 |
parents | 91b93f523ec6 |
children | 42863137168c |
comparison
equal
deleted
inserted
replaced
12139:c26d57fa08aa | 12140:915cc4f3fb15 |
---|---|
868 ErasedShadowChecker(Thread* thread, Symbol* name, InstanceKlass* holder, | 868 ErasedShadowChecker(Thread* thread, Symbol* name, InstanceKlass* holder, |
869 InstanceKlass* target) | 869 InstanceKlass* target) |
870 : ShadowChecker(thread, name, holder, target) {} | 870 : ShadowChecker(thread, name, holder, target) {} |
871 }; | 871 }; |
872 | 872 |
873 | |
874 // Find the unique qualified candidate from the perspective of the super_class | 873 // Find the unique qualified candidate from the perspective of the super_class |
875 // which is the resolved_klass, which must be an immediate superinterface | 874 // which is the resolved_klass, which must be an immediate superinterface |
876 // of klass | 875 // of klass |
877 Method* find_erased_super_default(InstanceKlass* current_class, InstanceKlass* super_class, Symbol* method_name, Symbol* sig, TRAPS) { | 876 Method* find_erased_super_default(InstanceKlass* current_class, InstanceKlass* super_class, Symbol* method_name, Symbol* sig, TRAPS) { |
878 | 877 |
882 MethodFamily* family; | 881 MethodFamily* family; |
883 visitor.get_discovered_family(&family); | 882 visitor.get_discovered_family(&family); |
884 | 883 |
885 if (family != NULL) { | 884 if (family != NULL) { |
886 family->determine_target(current_class, CHECK_NULL); // get target from current_class | 885 family->determine_target(current_class, CHECK_NULL); // get target from current_class |
887 } | 886 |
888 | 887 if (family->has_target()) { |
889 if (family->has_target()) { | 888 Method* target = family->get_selected_target(); |
890 Method* target = family->get_selected_target(); | 889 InstanceKlass* holder = InstanceKlass::cast(target->method_holder()); |
891 InstanceKlass* holder = InstanceKlass::cast(target->method_holder()); | 890 |
892 | 891 // Verify that the identified method is valid from the context of |
893 // Verify that the identified method is valid from the context of | 892 // the current class, which is the caller class for invokespecial |
894 // the current class, which is the caller class for invokespecial | 893 // link resolution, i.e. ensure there it is not shadowed. |
895 // link resolution, i.e. ensure there it is not shadowed. | 894 // You can use invokespecial to disambiguate interface methods, but |
896 // You can use invokespecial to disambiguate interface methods, but | 895 // you can not use it to skip over an interface method that would shadow it. |
897 // you can not use it to skip over an interface method that would shadow it. | 896 ErasedShadowChecker checker(THREAD, target->name(), holder, super_class); |
898 ErasedShadowChecker checker(THREAD, target->name(), holder, super_class); | 897 checker.run(current_class); |
899 checker.run(current_class); | 898 |
900 | 899 if (checker.found_shadow()) { |
901 if (checker.found_shadow()) { | 900 #ifndef PRODUCT |
902 #ifndef PRODUCT | 901 if (TraceDefaultMethods) { |
903 if (TraceDefaultMethods) { | 902 tty->print_cr(" Only candidate found was shadowed."); |
904 tty->print_cr(" Only candidate found was shadowed."); | 903 } |
905 } | 904 #endif // ndef PRODUCT |
906 #endif // ndef PRODUCT | 905 THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), |
906 "Accessible default method not found", NULL); | |
907 } else { | |
908 #ifndef PRODUCT | |
909 if (TraceDefaultMethods) { | |
910 family->print_sig_on(tty, target->signature(), 1); | |
911 } | |
912 #endif // ndef PRODUCT | |
913 return target; | |
914 } | |
915 } else { | |
916 assert(family->throws_exception(), "must have target or throw"); | |
907 THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), | 917 THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), |
908 "Accessible default method not found", NULL); | 918 family->get_exception_message()->as_C_string(), NULL); |
909 } else { | 919 } |
910 #ifndef PRODUCT | |
911 if (TraceDefaultMethods) { | |
912 family->print_sig_on(tty, target->signature(), 1); | |
913 } | |
914 #endif // ndef PRODUCT | |
915 return target; | |
916 } | |
917 } else { | 920 } else { |
918 assert(family->throws_exception(), "must have target or throw"); | 921 // no method found |
919 THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), | 922 ResourceMark rm(THREAD); |
920 family->get_exception_message()->as_C_string(), NULL); | 923 THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), |
921 } | 924 Method::name_and_sig_as_C_string(current_class, |
922 } | 925 method_name, sig), NULL); |
923 | 926 } |
927 } | |
924 // This is called during linktime when we find an invokespecial call that | 928 // This is called during linktime when we find an invokespecial call that |
925 // refers to a direct superinterface. It indicates that we should find the | 929 // refers to a direct superinterface. It indicates that we should find the |
926 // default method in the hierarchy of that superinterface, and if that method | 930 // default method in the hierarchy of that superinterface, and if that method |
927 // would have been a candidate from the point of view of 'this' class, then we | 931 // would have been a candidate from the point of view of 'this' class, then we |
928 // return that method. | 932 // return that method. |