changeset 20284 | 595a25ab9474 |
parent 19966 | 64732b96b5f5 |
child 20300 | fe4818444117 |
20283:ddf704c33210 | 20284:595a25ab9474 |
---|---|
323 GrowableArray<Pair<Method*,QualifiedState> > _members; |
323 GrowableArray<Pair<Method*,QualifiedState> > _members; |
324 ResourceHashtable<Method*, int> _member_index; |
324 ResourceHashtable<Method*, int> _member_index; |
325 |
325 |
326 Method* _selected_target; // Filled in later, if a unique target exists |
326 Method* _selected_target; // Filled in later, if a unique target exists |
327 Symbol* _exception_message; // If no unique target is found |
327 Symbol* _exception_message; // If no unique target is found |
328 Symbol* _exception_name; // If no unique target is found |
|
328 |
329 |
329 bool contains_method(Method* method) { |
330 bool contains_method(Method* method) { |
330 int* lookup = _member_index.get(method); |
331 int* lookup = _member_index.get(method); |
331 return lookup != NULL; |
332 return lookup != NULL; |
332 } |
333 } |
348 Symbol* generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const; |
349 Symbol* generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const; |
349 |
350 |
350 public: |
351 public: |
351 |
352 |
352 MethodFamily() |
353 MethodFamily() |
353 : _selected_target(NULL), _exception_message(NULL) {} |
354 : _selected_target(NULL), _exception_message(NULL), _exception_name(NULL) {} |
354 |
355 |
355 void set_target_if_empty(Method* m) { |
356 void set_target_if_empty(Method* m) { |
356 if (_selected_target == NULL && !m->is_overpass()) { |
357 if (_selected_target == NULL && !m->is_overpass()) { |
357 _selected_target = m; |
358 _selected_target = m; |
358 } |
359 } |
381 bool has_target() const { return _selected_target != NULL; } |
382 bool has_target() const { return _selected_target != NULL; } |
382 bool throws_exception() { return _exception_message != NULL; } |
383 bool throws_exception() { return _exception_message != NULL; } |
383 |
384 |
384 Method* get_selected_target() { return _selected_target; } |
385 Method* get_selected_target() { return _selected_target; } |
385 Symbol* get_exception_message() { return _exception_message; } |
386 Symbol* get_exception_message() { return _exception_message; } |
387 Symbol* get_exception_name() { return _exception_name; } |
|
386 |
388 |
387 // Either sets the target or the exception error message |
389 // Either sets the target or the exception error message |
388 void determine_target(InstanceKlass* root, TRAPS) { |
390 void determine_target(InstanceKlass* root, TRAPS) { |
389 if (has_target() || throws_exception()) { |
391 if (has_target() || throws_exception()) { |
390 return; |
392 return; |
398 } |
400 } |
399 } |
401 } |
400 |
402 |
401 if (qualified_methods.length() == 0) { |
403 if (qualified_methods.length() == 0) { |
402 _exception_message = generate_no_defaults_message(CHECK); |
404 _exception_message = generate_no_defaults_message(CHECK); |
405 _exception_name = vmSymbols::java_lang_AbstractMethodError(); |
|
403 } else if (qualified_methods.length() == 1) { |
406 } else if (qualified_methods.length() == 1) { |
404 Method* method = qualified_methods.at(0); |
407 Method* method = qualified_methods.at(0); |
405 if (method->is_abstract()) { |
408 if (method->is_abstract()) { |
406 _exception_message = generate_abstract_method_message(method, CHECK); |
409 _exception_message = generate_abstract_method_message(method, CHECK); |
410 _exception_name = vmSymbols::java_lang_AbstractMethodError(); |
|
407 } else { |
411 } else { |
408 _selected_target = qualified_methods.at(0); |
412 _selected_target = qualified_methods.at(0); |
409 } |
413 } |
410 } else { |
414 } else { |
411 _exception_message = generate_conflicts_message(&qualified_methods,CHECK); |
415 _exception_message = generate_conflicts_message(&qualified_methods,CHECK); |
416 _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError(); |
|
412 } |
417 } |
413 |
418 |
414 assert((has_target() ^ throws_exception()) == 1, |
419 assert((has_target() ^ throws_exception()) == 1, |
415 "One and only one must be true"); |
420 "One and only one must be true"); |
416 } |
421 } |
457 str->print_cr(""); |
462 str->print_cr(""); |
458 } |
463 } |
459 |
464 |
460 void print_exception(outputStream* str, int indent) { |
465 void print_exception(outputStream* str, int indent) { |
461 assert(throws_exception(), "Should be called otherwise"); |
466 assert(throws_exception(), "Should be called otherwise"); |
467 assert(_exception_name != NULL, "exception_name should be set"); |
|
462 streamIndentor si(str, indent * 2); |
468 streamIndentor si(str, indent * 2); |
463 str->indent().print_cr("%s", _exception_message->as_C_string()); |
469 str->indent().print_cr("%s: %s", _exception_name->as_C_string(), _exception_message->as_C_string()); |
464 } |
470 } |
465 #endif // ndef PRODUCT |
471 #endif // ndef PRODUCT |
466 }; |
472 }; |
467 |
473 |
468 Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const { |
474 Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const { |
668 bool visit() { |
674 bool visit() { |
669 PseudoScope* scope = PseudoScope::cast(current_data()); |
675 PseudoScope* scope = PseudoScope::cast(current_data()); |
670 InstanceKlass* iklass = current_class(); |
676 InstanceKlass* iklass = current_class(); |
671 |
677 |
672 Method* m = iklass->find_method(_method_name, _method_signature); |
678 Method* m = iklass->find_method(_method_name, _method_signature); |
673 if (m != NULL) { |
679 // private interface methods are not candidates for default methods |
680 // invokespecial to private interface methods doesn't use default method logic |
|
681 // future: take access controls into account for superclass methods |
|
682 if (m != NULL && (!iklass->is_interface() || m->is_public())) { |
|
674 if (_family == NULL) { |
683 if (_family == NULL) { |
675 _family = new StatefulMethodFamily(); |
684 _family = new StatefulMethodFamily(); |
676 } |
685 } |
677 |
686 |
678 if (iklass->is_interface()) { |
687 if (iklass->is_interface()) { |
780 tty->print_cr("Default method processing complete"); |
789 tty->print_cr("Default method processing complete"); |
781 } |
790 } |
782 #endif // ndef PRODUCT |
791 #endif // ndef PRODUCT |
783 } |
792 } |
784 |
793 |
785 /** |
794 |
786 * Interface inheritance rules were used to find a unique default method |
|
787 * candidate for the resolved class. This |
|
788 * method is only viable if it would also be in the set of default method |
|
789 * candidates if we ran a full analysis on the current class. |
|
790 * |
|
791 * The only reason that the method would not be in the set of candidates for |
|
792 * the current class is if that there's another matching method |
|
793 * which is "more specific" than the found method -- i.e., one could find a |
|
794 * path in the interface hierarchy in which the matching method appears |
|
795 * before we get to '_target'. |
|
796 * |
|
797 * In order to determine this, we examine all of the implemented |
|
798 * interfaces. If we find path that leads to the '_target' interface, then |
|
799 * we examine that path to see if there are any methods that would shadow |
|
800 * the selected method along that path. |
|
801 */ |
|
802 class ShadowChecker : public HierarchyVisitor<ShadowChecker> { |
|
803 protected: |
|
804 Thread* THREAD; |
|
805 |
|
806 InstanceKlass* _target; |
|
807 |
|
808 Symbol* _method_name; |
|
809 InstanceKlass* _method_holder; |
|
810 bool _found_shadow; |
|
811 |
|
812 |
|
813 public: |
|
814 |
|
815 ShadowChecker(Thread* thread, Symbol* name, InstanceKlass* holder, |
|
816 InstanceKlass* target) |
|
817 : THREAD(thread), _method_name(name), _method_holder(holder), |
|
818 _target(target), _found_shadow(false) {} |
|
819 |
|
820 void* new_node_data(InstanceKlass* cls) { return NULL; } |
|
821 void free_node_data(void* data) { return; } |
|
822 |
|
823 bool visit() { |
|
824 InstanceKlass* ik = current_class(); |
|
825 if (ik == _target && current_depth() == 1) { |
|
826 return false; // This was the specified super -- no need to search it |
|
827 } |
|
828 if (ik == _method_holder || ik == _target) { |
|
829 // We found a path that should be examined to see if it shadows _method |
|
830 if (path_has_shadow()) { |
|
831 _found_shadow = true; |
|
832 cancel_iteration(); |
|
833 } |
|
834 return false; // no need to continue up hierarchy |
|
835 } |
|
836 return true; |
|
837 } |
|
838 |
|
839 virtual bool path_has_shadow() = 0; |
|
840 bool found_shadow() { return _found_shadow; } |
|
841 }; |
|
842 |
|
843 // Used for Invokespecial. |
|
844 // Invokespecial is allowed to invoke a concrete interface method |
|
845 // and can be used to disambuiguate among qualified candidates, |
|
846 // which are methods in immediate superinterfaces, |
|
847 // but may not be used to invoke a candidate that would be shadowed |
|
848 // from the perspective of the caller. |
|
849 // Invokespecial is also used in the overpass generation today |
|
850 // We re-run the shadowchecker because we can't distinguish this case, |
|
851 // but it should return the same answer, since the overpass target |
|
852 // is now the invokespecial caller. |
|
853 class ErasedShadowChecker : public ShadowChecker { |
|
854 private: |
|
855 bool path_has_shadow() { |
|
856 |
|
857 for (int i = current_depth() - 1; i > 0; --i) { |
|
858 InstanceKlass* ik = class_at_depth(i); |
|
859 |
|
860 if (ik->is_interface()) { |
|
861 int end; |
|
862 int start = ik->find_method_by_name(_method_name, &end); |
|
863 if (start != -1) { |
|
864 return true; |
|
865 } |
|
866 } |
|
867 } |
|
868 return false; |
|
869 } |
|
870 public: |
|
871 |
|
872 ErasedShadowChecker(Thread* thread, Symbol* name, InstanceKlass* holder, |
|
873 InstanceKlass* target) |
|
874 : ShadowChecker(thread, name, holder, target) {} |
|
875 }; |
|
876 |
|
877 // Find the unique qualified candidate from the perspective of the super_class |
|
878 // which is the resolved_klass, which must be an immediate superinterface |
|
879 // of klass |
|
880 Method* find_erased_super_default(InstanceKlass* current_class, InstanceKlass* super_class, Symbol* method_name, Symbol* sig, TRAPS) { |
|
881 |
|
882 FindMethodsByErasedSig visitor(method_name, sig); |
|
883 visitor.run(super_class); // find candidates from resolved_klass |
|
884 |
|
885 MethodFamily* family; |
|
886 visitor.get_discovered_family(&family); |
|
887 |
|
888 if (family != NULL) { |
|
889 family->determine_target(current_class, CHECK_NULL); // get target from current_class |
|
890 |
|
891 if (family->has_target()) { |
|
892 Method* target = family->get_selected_target(); |
|
893 InstanceKlass* holder = InstanceKlass::cast(target->method_holder()); |
|
894 |
|
895 // Verify that the identified method is valid from the context of |
|
896 // the current class, which is the caller class for invokespecial |
|
897 // link resolution, i.e. ensure there it is not shadowed. |
|
898 // You can use invokespecial to disambiguate interface methods, but |
|
899 // you can not use it to skip over an interface method that would shadow it. |
|
900 ErasedShadowChecker checker(THREAD, target->name(), holder, super_class); |
|
901 checker.run(current_class); |
|
902 |
|
903 if (checker.found_shadow()) { |
|
904 #ifndef PRODUCT |
|
905 if (TraceDefaultMethods) { |
|
906 tty->print_cr(" Only candidate found was shadowed."); |
|
907 } |
|
908 #endif // ndef PRODUCT |
|
909 THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), |
|
910 "Accessible default method not found", NULL); |
|
911 } else { |
|
912 #ifndef PRODUCT |
|
913 if (TraceDefaultMethods) { |
|
914 family->print_sig_on(tty, target->signature(), 1); |
|
915 } |
|
916 #endif // ndef PRODUCT |
|
917 return target; |
|
918 } |
|
919 } else { |
|
920 assert(family->throws_exception(), "must have target or throw"); |
|
921 THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), |
|
922 family->get_exception_message()->as_C_string(), NULL); |
|
923 } |
|
924 } else { |
|
925 // no method found |
|
926 ResourceMark rm(THREAD); |
|
927 THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), |
|
928 Method::name_and_sig_as_C_string(current_class, |
|
929 method_name, sig), NULL); |
|
930 } |
|
931 } |
|
932 // This is called during linktime when we find an invokespecial call that |
|
933 // refers to a direct superinterface. It indicates that we should find the |
|
934 // default method in the hierarchy of that superinterface, and if that method |
|
935 // would have been a candidate from the point of view of 'this' class, then we |
|
936 // return that method. |
|
937 // This logic assumes that the super is a direct superclass of the caller |
|
938 Method* DefaultMethods::find_super_default( |
|
939 Klass* cls, Klass* super, Symbol* method_name, Symbol* sig, TRAPS) { |
|
940 |
|
941 ResourceMark rm(THREAD); |
|
942 |
|
943 assert(cls != NULL && super != NULL, "Need real classes"); |
|
944 |
|
945 InstanceKlass* current_class = InstanceKlass::cast(cls); |
|
946 InstanceKlass* super_class = InstanceKlass::cast(super); |
|
947 |
|
948 // Keep entire hierarchy alive for the duration of the computation |
|
949 KeepAliveRegistrar keepAlive(THREAD); |
|
950 KeepAliveVisitor loadKeepAlive(&keepAlive); |
|
951 loadKeepAlive.run(current_class); // get hierarchy from current class |
|
952 |
|
953 #ifndef PRODUCT |
|
954 if (TraceDefaultMethods) { |
|
955 tty->print_cr("Finding super default method %s.%s%s from %s", |
|
956 super_class->name()->as_C_string(), |
|
957 method_name->as_C_string(), sig->as_C_string(), |
|
958 current_class->name()->as_C_string()); |
|
959 } |
|
960 #endif // ndef PRODUCT |
|
961 |
|
962 assert(super_class->is_interface(), "only call for default methods"); |
|
963 |
|
964 Method* target = NULL; |
|
965 target = find_erased_super_default(current_class, super_class, |
|
966 method_name, sig, CHECK_NULL); |
|
967 |
|
968 #ifndef PRODUCT |
|
969 if (target != NULL) { |
|
970 if (TraceDefaultMethods) { |
|
971 tty->print(" Returning "); |
|
972 print_method(tty, target, true); |
|
973 tty->print_cr(""); |
|
974 } |
|
975 } |
|
976 #endif // ndef PRODUCT |
|
977 return target; |
|
978 } |
|
979 |
795 |
980 #ifndef PRODUCT |
796 #ifndef PRODUCT |
981 // Return true is broad type is a covariant return of narrow type |
797 // Return true is broad type is a covariant return of narrow type |
982 static bool covariant_return_type(BasicType narrow, BasicType broad) { |
798 static bool covariant_return_type(BasicType narrow, BasicType broad) { |
983 if (narrow == broad) { |
799 if (narrow == broad) { |
1033 } |
849 } |
1034 assem._return(in.type()); |
850 assem._return(in.type()); |
1035 return parameter_count; |
851 return parameter_count; |
1036 } |
852 } |
1037 |
853 |
1038 static int assemble_abstract_method_error( |
854 static int assemble_method_error( |
1039 BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* message, TRAPS) { |
855 BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* errorName, Symbol* message, TRAPS) { |
1040 |
856 |
1041 Symbol* errorName = vmSymbols::java_lang_AbstractMethodError(); |
|
1042 Symbol* init = vmSymbols::object_initializer_name(); |
857 Symbol* init = vmSymbols::object_initializer_name(); |
1043 Symbol* sig = vmSymbols::string_void_signature(); |
858 Symbol* sig = vmSymbols::string_void_signature(); |
1044 |
859 |
1045 BytecodeAssembler assem(buffer, cp); |
860 BytecodeAssembler assem(buffer, cp); |
1046 |
861 |
1148 if (selected->method_holder()->is_interface()) { |
963 if (selected->method_holder()->is_interface()) { |
1149 max_stack = assemble_redirect( |
964 max_stack = assemble_redirect( |
1150 &bpool, &buffer, slot->signature(), selected, CHECK); |
965 &bpool, &buffer, slot->signature(), selected, CHECK); |
1151 } |
966 } |
1152 } else if (method->throws_exception()) { |
967 } else if (method->throws_exception()) { |
1153 max_stack = assemble_abstract_method_error( |
968 max_stack = assemble_method_error(&bpool, &buffer, method->get_exception_name(), method->get_exception_message(), CHECK); |
1154 &bpool, &buffer, method->get_exception_message(), CHECK); |
|
1155 } |
969 } |
1156 if (max_stack != 0) { |
970 if (max_stack != 0) { |
1157 AccessFlags flags = accessFlags_from( |
971 AccessFlags flags = accessFlags_from( |
1158 JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE); |
972 JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE); |
1159 Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(), |
973 Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(), |