8032536: JVM resolves wrong method in some unusual cases

Tue, 04 Mar 2014 15:46:33 -0500

author
hseigel
date
Tue, 04 Mar 2014 15:46:33 -0500
changeset 6759
c02077c4b79c
parent 6758
c28dffbb1d74
child 6760
cc7a96a360d0

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;

mercurial