8026286: Improper locking of annotation queues causes assertion failures.

Wed, 16 Oct 2013 16:33:04 -0400

author
emc
date
Wed, 16 Oct 2013 16:33:04 -0400
changeset 2136
7f6481e5fe3a
parent 2135
d7e155f874a7
child 2137
a48d3b981083

8026286: Improper locking of annotation queues causes assertion failures.
8026063: Calls to annotate.flush() cause incorrect type annotations to be generated.
Summary: Fix locking in ClassReader.java
Reviewed-by: jfranck

src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Annotate.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/jvm/ClassReader.java file | annotate | diff | comparison | revisions
test/tools/javac/annotations/typeAnnotations/TestAnonInnerInstance1.java file | annotate | diff | comparison | revisions
test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Wed Oct 16 10:47:21 2013 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Wed Oct 16 16:33:04 2013 -0400
     1.3 @@ -97,7 +97,6 @@
     1.4      final Symtab syms;
     1.5      final Annotate annotate;
     1.6      final Attr attr;
     1.7 -    private final boolean typeAnnoAsserts;
     1.8  
     1.9      protected TypeAnnotations(Context context) {
    1.10          context.put(typeAnnosKey, this);
    1.11 @@ -107,7 +106,6 @@
    1.12          annotate = Annotate.instance(context);
    1.13          attr = Attr.instance(context);
    1.14          Options options = Options.instance(context);
    1.15 -        typeAnnoAsserts = options.isSet("TypeAnnotationAsserts");
    1.16      }
    1.17  
    1.18      /**
    1.19 @@ -1042,11 +1040,7 @@
    1.20          @Override
    1.21          public void visitMethodDef(final JCMethodDecl tree) {
    1.22              if (tree.sym == null) {
    1.23 -                if (typeAnnoAsserts) {
    1.24 -                    Assert.error("Visiting tree node before memberEnter");
    1.25 -                } else {
    1.26 -                return;
    1.27 -            }
    1.28 +                Assert.error("Visiting tree node before memberEnter");
    1.29              }
    1.30              if (sigOnly) {
    1.31                  if (!tree.mods.annotations.isEmpty()) {
    1.32 @@ -1150,10 +1144,7 @@
    1.33                  // Nothing to do for separateAnnotationsKinds if
    1.34                  // there are no annotations of either kind.
    1.35              } else if (tree.sym == null) {
    1.36 -                if (typeAnnoAsserts) {
    1.37 -                    Assert.error("Visiting tree node before memberEnter");
    1.38 -                }
    1.39 -                // Something is wrong already. Quietly ignore.
    1.40 +                Assert.error("Visiting tree node before memberEnter");
    1.41              } else if (tree.sym.getKind() == ElementKind.PARAMETER) {
    1.42                  // Parameters are handled in visitMethodDef or visitLambda.
    1.43              } else if (tree.sym.getKind() == ElementKind.FIELD) {
     2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Wed Oct 16 10:47:21 2013 -0700
     2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Wed Oct 16 16:33:04 2013 -0400
     2.3 @@ -129,6 +129,12 @@
     2.4          flush();
     2.5      }
     2.6  
     2.7 +    /** Variant which allows for a delayed flush of annotations.
     2.8 +     * Needed by ClassReader */
     2.9 +    public void enterDoneWithoutFlush() {
    2.10 +        enterCount--;
    2.11 +    }
    2.12 +
    2.13      public void flush() {
    2.14          if (enterCount != 0) return;
    2.15          enterCount++;
     3.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Oct 16 10:47:21 2013 -0700
     3.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Oct 16 16:33:04 2013 -0400
     3.3 @@ -2405,8 +2405,6 @@
     3.4              return c;
     3.5      }
     3.6  
     3.7 -    private boolean suppressFlush = false;
     3.8 -
     3.9      /** Completion for classes to be loaded. Before a class is loaded
    3.10       *  we make sure its enclosing class (if any) is loaded.
    3.11       */
    3.12 @@ -2414,13 +2412,14 @@
    3.13          if (sym.kind == TYP) {
    3.14              ClassSymbol c = (ClassSymbol)sym;
    3.15              c.members_field = new Scope.ErrorScope(c); // make sure it's always defined
    3.16 -            boolean saveSuppressFlush = suppressFlush;
    3.17 -            suppressFlush = true;
    3.18 +            annotate.enterStart();
    3.19              try {
    3.20                  completeOwners(c.owner);
    3.21                  completeEnclosing(c);
    3.22              } finally {
    3.23 -                suppressFlush = saveSuppressFlush;
    3.24 +                // The flush needs to happen only after annotations
    3.25 +                // are filled in.
    3.26 +                annotate.enterDoneWithoutFlush();
    3.27              }
    3.28              fillIn(c);
    3.29          } else if (sym.kind == PCK) {
    3.30 @@ -2431,7 +2430,7 @@
    3.31                  throw new CompletionFailure(sym, ex.getLocalizedMessage()).initCause(ex);
    3.32              }
    3.33          }
    3.34 -        if (!filling && !suppressFlush)
    3.35 +        if (!filling)
    3.36              annotate.flush(); // finish attaching annotations
    3.37      }
    3.38  
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/tools/javac/annotations/typeAnnotations/TestAnonInnerInstance1.java	Wed Oct 16 16:33:04 2013 -0400
     4.3 @@ -0,0 +1,57 @@
     4.4 +/*
     4.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 + *
     4.8 + * This code is free software; you can redistribute it and/or modify it
     4.9 + * under the terms of the GNU General Public License version 2 only, as
    4.10 + * published by the Free Software Foundation.
    4.11 + *
    4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.15 + * version 2 for more details (a copy is included in the LICENSE file that
    4.16 + * accompanied this code).
    4.17 + *
    4.18 + * You should have received a copy of the GNU General Public License version
    4.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.21 + *
    4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    4.23 + * or visit www.oracle.com if you need additional information or have any
    4.24 + * questions.
    4.25 + */
    4.26 +
    4.27 +/*
    4.28 + * @test
    4.29 + * @bug 8026286
    4.30 + * @summary This test previously forced an assertion to fail, due to
    4.31 + *          TypeAnnotationPosition visiting a tree node prior to
    4.32 + *          memberEnter.
    4.33 + * @compile TestAnonInnerInstance1.java
    4.34 + */
    4.35 +
    4.36 +import java.lang.annotation.*;
    4.37 +import static java.lang.annotation.RetentionPolicy.*;
    4.38 +import static java.lang.annotation.ElementType.*;
    4.39 +import java.util.List;
    4.40 +
    4.41 +class TestAnonInnerInstance1<T> {
    4.42 +    Object mtest(TestAnonInnerInstance1<T> t){ return null; }
    4.43 +    Object mmtest(TestAnonInnerInstance1<T> t){ return null; }
    4.44 +
    4.45 +    public void test() {
    4.46 +
    4.47 +        mtest(new TestAnonInnerInstance1<T>() {
    4.48 +                  class InnerAnon<U> { // Test1$1$InnerAnon.class
    4.49 +                      @A @B @C @D String ia_m1(){ return null; };
    4.50 +                  }
    4.51 +    //If this is commented out, annotations are attributed correctly
    4.52 +                  InnerAnon<String> IA = new InnerAnon< String>();
    4.53 +              });
    4.54 +   }
    4.55 +}
    4.56 +
    4.57 +@Retention(RUNTIME) @Target({TYPE_USE,FIELD}) @interface A { }
    4.58 +@Retention(RUNTIME) @Target({TYPE_USE,METHOD}) @interface B { }
    4.59 +@Retention(CLASS) @Target({TYPE_USE,FIELD}) @interface C { }
    4.60 +@Retention(CLASS) @Target({TYPE_USE,METHOD}) @interface D { }
     5.1 --- a/test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java	Wed Oct 16 10:47:21 2013 -0700
     5.2 +++ b/test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java	Wed Oct 16 16:33:04 2013 -0400
     5.3 @@ -24,7 +24,6 @@
     5.4  /*
     5.5   * @test
     5.6   * @bug 8008762
     5.7 - * @ignore 8013409: test failures for type annotations
     5.8   * @summary Type annotation on inner class in anonymous class
     5.9   *          shows up as regular annotation
    5.10   */

mercurial