提交 33b85a57 编写于 作者: H hseigel

8032536: JVM resolves wrong method in some unusual cases

Summary: Handle package private case
Reviewed-by: coleenp, acorn, jdn
上级 48631d4c
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -249,6 +249,17 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) { ...@@ -249,6 +249,17 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
// For bytecodes not produced by javac together it is possible that a method does not override // For bytecodes not produced by javac together it is possible that a method does not override
// the superclass's method, but might indirectly override a super-super class's vtable entry // the superclass's method, but might indirectly override a super-super class's vtable entry
// If none found, return a null superk, else return the superk of the method this does override // If none found, return a null superk, else return the superk of the method this does override
// For public and protected methods: if they override a superclass, they will
// also be overridden themselves appropriately.
// Private methods do not override and are not overridden.
// Package Private methods are trickier:
// e.g. P1.A, pub m
// P2.B extends A, package private m
// P1.C extends B, public m
// P1.C.m needs to override P1.A.m and can not override P2.B.m
// Therefore: all package private methods need their own vtable entries for
// them to be the root of an inheritance overriding decision
// Package private methods may also override other vtable entries
InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper, methodHandle target_method, InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper, methodHandle target_method,
int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) { int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) {
InstanceKlass* superk = initialsuper; InstanceKlass* superk = initialsuper;
...@@ -396,8 +407,11 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar ...@@ -396,8 +407,11 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar
target_classname, THREAD)) target_classname, THREAD))
!= (InstanceKlass*)NULL)))) != (InstanceKlass*)NULL))))
{ {
// overriding, so no new entry // Package private methods always need a new entry to root their own
allocate_new = false; // overriding. They may also override other methods.
if (!target_method()->is_package_private()) {
allocate_new = false;
}
if (checkconstraints) { if (checkconstraints) {
// Override vtable entry if passes loader constraint check // Override vtable entry if passes loader constraint check
...@@ -541,8 +555,9 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method, ...@@ -541,8 +555,9 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method,
AccessFlags class_flags, AccessFlags class_flags,
TRAPS) { TRAPS) {
if (class_flags.is_interface()) { if (class_flags.is_interface()) {
// Interfaces do not use vtables, so there is no point to assigning // Interfaces do not use vtables, except for java.lang.Object methods,
// a vtable index to any of their methods. If we refrain from doing this, // so there is no point to assigning
// a vtable index to any of their local methods. If we refrain from doing this,
// we can use Method::_vtable_index to hold the itable index // we can use Method::_vtable_index to hold the itable index
return false; return false;
} }
...@@ -580,6 +595,12 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method, ...@@ -580,6 +595,12 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method,
return true; return true;
} }
// Package private methods always need a new entry to root their own
// overriding. This allows transitive overriding to work.
if (target_method()->is_package_private()) {
return true;
}
// search through the super class hierarchy to see if we need // search through the super class hierarchy to see if we need
// a new entry // a new entry
ResourceMark rm; ResourceMark rm;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册