You need to sign in or sign up before continuing.
提交 0faaca5a 编写于 作者: A acorn

8028438: static superclass method masks default methods

Reviewed-by: hseigel, lfoltan, coleenp
上级 7e476f9e
......@@ -625,13 +625,13 @@ static GrowableArray<EmptyVtableSlot*>* find_empty_vtable_slots(
while (super != NULL) {
for (int i = 0; i < super->methods()->length(); ++i) {
Method* m = super->methods()->at(i);
if (m->is_overpass()) {
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,
// unless we have a real implementation of it in the current class.
Method* impl = klass->lookup_method(m->name(), m->signature());
if (impl == NULL || impl->is_overpass()) {
if (impl == NULL || impl->is_overpass() || impl->is_static()) {
if (!already_in_vtable_slots(slots, m)) {
slots->append(new EmptyVtableSlot(m));
}
......@@ -648,7 +648,7 @@ static GrowableArray<EmptyVtableSlot*>* find_empty_vtable_slots(
// so it's a method we want to re-examine in this new context. That is,
// unless we have a real implementation of it in the current class.
Method* impl = klass->lookup_method(m->name(), m->signature());
if (impl == NULL || impl->is_overpass()) {
if (impl == NULL || impl->is_overpass() || impl->is_static()) {
if (!already_in_vtable_slots(slots, m)) {
slots->append(new EmptyVtableSlot(m));
}
......
......@@ -267,8 +267,8 @@ void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, Klass
Method* result_oop = klass->uncached_lookup_method(name, signature);
result = methodHandle(THREAD, result_oop);
while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) {
klass = KlassHandle(THREAD, result->method_holder()->super());
result = methodHandle(THREAD, klass->uncached_lookup_method(name, signature));
KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super());
result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature));
}
if (result.is_null()) {
......
......@@ -1427,6 +1427,17 @@ Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const {
return InstanceKlass::find_method(methods(), name, signature);
}
// find_instance_method looks up the name/signature in the local methods array
// and skips over static methods
Method* InstanceKlass::find_instance_method(
Array<Method*>* methods, Symbol* name, Symbol* signature) {
Method* meth = InstanceKlass::find_method(methods, name, signature);
if (meth != NULL && meth->is_static()) {
meth = NULL;
}
return meth;
}
// find_method looks up the name/signature in the local methods array
Method* InstanceKlass::find_method(
Array<Method*>* methods, Symbol* name, Symbol* signature) {
......
......@@ -515,6 +515,7 @@ class InstanceKlass: public Klass {
// find a local method (returns NULL if not found)
Method* find_method(Symbol* name, Symbol* signature) const;
static Method* find_method(Array<Method*>* methods, Symbol* name, Symbol* signature);
static Method* find_instance_method(Array<Method*>* methods, Symbol* name, Symbol* signature);
// find a local method index in default_methods (returns -1 if not found)
static int find_method_index(Array<Method*>* methods, Symbol* name, Symbol* signature);
......
......@@ -665,6 +665,11 @@ bool klassVtable::is_miranda_entry_at(int i) {
// check if a method is a miranda method, given a class's methods table,
// its default_method table and its super
// Miranda methods are calculated twice:
// first: before vtable size calculation: including abstract and default
// This is seen by default method creation
// Second: recalculated during vtable initialization: only abstract
// This is seen by link resolution and selection.
// "miranda" means not static, not defined by this class.
// private methods in interfaces do not belong in the miranda list.
// the caller must make sure that the method belongs to an interface implemented by the class
......@@ -678,7 +683,8 @@ bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods,
}
Symbol* name = m->name();
Symbol* signature = m->signature();
if (InstanceKlass::find_method(class_methods, name, signature) == NULL) {
if (InstanceKlass::find_instance_method(class_methods, name, signature) == NULL) {
// did not find it in the method table of the current class
if ((default_methods == NULL) ||
InstanceKlass::find_method(default_methods, name, signature) == NULL) {
......@@ -688,6 +694,12 @@ bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods,
}
Method* mo = InstanceKlass::cast(super)->lookup_method(name, signature);
while (mo != NULL && mo->access_flags().is_static()
&& mo->method_holder() != NULL
&& mo->method_holder()->super() != NULL)
{
mo = mo->method_holder()->super()->uncached_lookup_method(name, signature);
}
if (mo == NULL || mo->access_flags().is_private() ) {
// super class hierarchy does not implement it or protection is different
return true;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册