src/hotspot/share/classfile/defaultMethods.cpp
changeset 48463 474cec233fb2
parent 47554 bc112140e089
child 49677 a1a7456dd8b9
--- a/src/hotspot/share/classfile/defaultMethods.cpp	Fri Dec 15 16:51:13 2017 +0100
+++ b/src/hotspot/share/classfile/defaultMethods.cpp	Fri Dec 15 11:23:50 2017 -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"
@@ -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<EmptyVtableSlot*>* 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);