< prev index next >
src/hotspot/share/classfile/defaultMethods.cpp
Print this page
@@ -24,10 +24,11 @@
#include "precompiled.hpp"
#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"
#include "memory/metadataFactory.hpp"
#include "memory/resourceArea.hpp"
@@ -681,14 +682,15 @@
private:
// Context data
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) {
if (_family != NULL) {
*family = _family->get_method_family();
@@ -707,29 +709,32 @@
bool visit() {
PseudoScope* scope = PseudoScope::cast(current_data());
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();
}
if (iklass->is_interface()) {
StateRestorer* restorer = _family->record_method_and_dq_further(m);
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);
}
}
@@ -743,14 +748,14 @@
static void create_defaults_and_exceptions(
GrowableArray<EmptyVtableSlot*>* slots, InstanceKlass* klass, TRAPS);
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;
visitor.get_discovered_family(&family);
if (family != NULL) {
@@ -815,11 +820,11 @@
streamIndentor si(&ls, 2);
ls.indent().print("Looking for default methods for slot ");
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);
log_debug(defaultmethods)("Default method processing complete");
}
< prev index next >