Tue, 04 Mar 2014 15:46:33 -0500
8032536: JVM resolves wrong method in some unusual cases
Summary: Handle package private case
Reviewed-by: coleenp, acorn, jdn
src/share/vm/oops/klassVtable.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/oops/klassVtable.cpp Wed Feb 26 22:07:40 2014 -0800 1.2 +++ b/src/share/vm/oops/klassVtable.cpp Tue Mar 04 15:46:33 2014 -0500 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -249,6 +249,17 @@ 1.11 // For bytecodes not produced by javac together it is possible that a method does not override 1.12 // the superclass's method, but might indirectly override a super-super class's vtable entry 1.13 // If none found, return a null superk, else return the superk of the method this does override 1.14 +// For public and protected methods: if they override a superclass, they will 1.15 +// also be overridden themselves appropriately. 1.16 +// Private methods do not override and are not overridden. 1.17 +// Package Private methods are trickier: 1.18 +// e.g. P1.A, pub m 1.19 +// P2.B extends A, package private m 1.20 +// P1.C extends B, public m 1.21 +// P1.C.m needs to override P1.A.m and can not override P2.B.m 1.22 +// Therefore: all package private methods need their own vtable entries for 1.23 +// them to be the root of an inheritance overriding decision 1.24 +// Package private methods may also override other vtable entries 1.25 InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper, methodHandle target_method, 1.26 int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) { 1.27 InstanceKlass* superk = initialsuper; 1.28 @@ -396,8 +407,11 @@ 1.29 target_classname, THREAD)) 1.30 != (InstanceKlass*)NULL)))) 1.31 { 1.32 - // overriding, so no new entry 1.33 - allocate_new = false; 1.34 + // Package private methods always need a new entry to root their own 1.35 + // overriding. They may also override other methods. 1.36 + if (!target_method()->is_package_private()) { 1.37 + allocate_new = false; 1.38 + } 1.39 1.40 if (checkconstraints) { 1.41 // Override vtable entry if passes loader constraint check 1.42 @@ -541,8 +555,9 @@ 1.43 AccessFlags class_flags, 1.44 TRAPS) { 1.45 if (class_flags.is_interface()) { 1.46 - // Interfaces do not use vtables, so there is no point to assigning 1.47 - // a vtable index to any of their methods. If we refrain from doing this, 1.48 + // Interfaces do not use vtables, except for java.lang.Object methods, 1.49 + // so there is no point to assigning 1.50 + // a vtable index to any of their local methods. If we refrain from doing this, 1.51 // we can use Method::_vtable_index to hold the itable index 1.52 return false; 1.53 } 1.54 @@ -580,6 +595,12 @@ 1.55 return true; 1.56 } 1.57 1.58 + // Package private methods always need a new entry to root their own 1.59 + // overriding. This allows transitive overriding to work. 1.60 + if (target_method()->is_package_private()) { 1.61 + return true; 1.62 + } 1.63 + 1.64 // search through the super class hierarchy to see if we need 1.65 // a new entry 1.66 ResourceMark rm;