--- old/src/hotspot/share/classfile/defaultMethods.cpp 2017-12-04 09:20:26.244895978 -0500 +++ new/src/hotspot/share/classfile/defaultMethods.cpp 2017-12-04 09:20:26.061373577 -0500 @@ -26,6 +26,7 @@ #include "classfile/bytecodeAssembler.hpp" #include "classfile/defaultMethods.hpp" #include "classfile/symbolTable.hpp" +#include "classfile/systemDictionary.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/allocation.hpp" @@ -626,7 +627,7 @@ while (super != NULL) { for (int i = 0; i < super->methods()->length(); ++i) { Method* m = super->methods()->at(i); - if (m->is_overpass() || m->is_static()) { + if (m->is_overpass() || m->is_static()) { // m is a method that would have been a miranda if not for the // default method processing that occurred on behalf of our superclass, // so it's a method we want to re-examine in this new context. That is, @@ -683,10 +684,11 @@ Symbol* _method_name; Symbol* _method_signature; StatefulMethodFamily* _family; + bool _cur_class_is_interface; public: - FindMethodsByErasedSig(Symbol* name, Symbol* signature) : - _method_name(name), _method_signature(signature), + FindMethodsByErasedSig(Symbol* name, Symbol* signature, bool is_interf) : + _method_name(name), _method_signature(signature), _cur_class_is_interface(is_interf), _family(NULL) {} void get_discovered_family(MethodFamily** family) { @@ -709,14 +711,17 @@ InstanceKlass* iklass = current_class(); Method* m = iklass->find_method(_method_name, _method_signature); - // private interface methods are not candidates for default methods - // invokespecial to private interface methods doesn't use default method logic - // private class methods are not candidates for default methods, - // private methods do not override default methods, so need to perform - // default method inheritance without including private methods - // The overpasses are your supertypes' errors, we do not include them - // future: take access controls into account for superclass methods - if (m != NULL && !m->is_static() && !m->is_overpass() && !m->is_private()) { + // Private interface methods are not candidates for default methods. + // invokespecial to private interface methods doesn't use default method logic. + // Private class methods are not candidates for default methods. + // Private methods do not override default methods, so need to perform + // default method inheritance without including private methods. + // The overpasses are your supertypes' errors, we do not include them. + // Non-public methods in java.lang.Object are not candidates for default + // methods. + // Future: take access controls into account for superclass methods + if (m != NULL && !m->is_static() && !m->is_overpass() && !m->is_private() && + (!_cur_class_is_interface || !SystemDictionary::is_nonpublic_Object_method(m))) { if (_family == NULL) { _family = new StatefulMethodFamily(); } @@ -726,8 +731,8 @@ scope->add_mark(restorer); } else { // This is the rule that methods in classes "win" (bad word) over - // methods in interfaces. This works because of single inheritance - // private methods in classes do not "win", they will be found + // methods in interfaces. This works because of single inheritance. + // Private methods in classes do not "win", they will be found // first on searching, but overriding for invokevirtual needs // to find default method candidates for the same signature _family->set_target_if_empty(m); @@ -745,10 +750,10 @@ static void generate_erased_defaults( InstanceKlass* klass, GrowableArray* empty_slots, - EmptyVtableSlot* slot, TRAPS) { + EmptyVtableSlot* slot, bool is_intf, TRAPS) { // sets up a set of methods with the same exact erased signature - FindMethodsByErasedSig visitor(slot->name(), slot->signature()); + FindMethodsByErasedSig visitor(slot->name(), slot->signature(), is_intf); visitor.run(klass); MethodFamily* family; @@ -817,7 +822,7 @@ slot->print_on(&ls); ls.cr(); } - generate_erased_defaults(klass, empty_slots, slot, CHECK); + generate_erased_defaults(klass, empty_slots, slot, klass->is_interface(), CHECK); } log_debug(defaultmethods)("Creating defaults and overpasses..."); create_defaults_and_exceptions(empty_slots, klass, CHECK);