8000518: Javac generates duplicate name_and_type constant pool entry for class BinaryOpValueExp.java

Sat, 15 Dec 2012 13:54:51 +0000

author
vromero
date
Sat, 15 Dec 2012 13:54:51 +0000
changeset 1452
de1ec6fc93fe
parent 1451
37a5d7eccb87
child 1453
f72dc656a306

8000518: Javac generates duplicate name_and_type constant pool entry for class BinaryOpValueExp.java
Reviewed-by: jjg, mcimadamore

src/share/classes/com/sun/tools/javac/code/Type.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/Types.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/jvm/ClassFile.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/jvm/ClassReader.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/jvm/Code.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/jvm/Gen.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/jvm/Pool.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java file | annotate | diff | comparison | revisions
test/tools/javac/8000518/DuplicateConstantPoolEntry.java file | annotate | diff | comparison | revisions
test/tools/javac/lambda/TestInvokeDynamic.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/Type.java	Fri Dec 14 11:16:46 2012 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Sat Dec 15 13:54:51 2012 +0000
     1.3 @@ -302,10 +302,12 @@
     1.4       * never complete classes. Where isSameType would complete a
     1.5       * class, equals assumes that the two types are different.
     1.6       */
     1.7 +    @Override
     1.8      public boolean equals(Object t) {
     1.9          return super.equals(t);
    1.10      }
    1.11  
    1.12 +    @Override
    1.13      public int hashCode() {
    1.14          return super.hashCode();
    1.15      }
    1.16 @@ -996,34 +998,6 @@
    1.17              return "(" + argtypes + ")" + restype;
    1.18          }
    1.19  
    1.20 -        public boolean equals(Object obj) {
    1.21 -            if (this == obj)
    1.22 -                return true;
    1.23 -            if (!(obj instanceof MethodType))
    1.24 -                return false;
    1.25 -            MethodType m = (MethodType)obj;
    1.26 -            List<Type> args1 = argtypes;
    1.27 -            List<Type> args2 = m.argtypes;
    1.28 -            while (!args1.isEmpty() && !args2.isEmpty()) {
    1.29 -                if (!args1.head.equals(args2.head))
    1.30 -                    return false;
    1.31 -                args1 = args1.tail;
    1.32 -                args2 = args2.tail;
    1.33 -            }
    1.34 -            if (!args1.isEmpty() || !args2.isEmpty())
    1.35 -                return false;
    1.36 -            return restype.equals(m.restype);
    1.37 -        }
    1.38 -
    1.39 -        public int hashCode() {
    1.40 -            int h = METHOD.ordinal();
    1.41 -            for (List<Type> thisargs = this.argtypes;
    1.42 -                 thisargs.tail != null; /*inlined: thisargs.nonEmpty()*/
    1.43 -                 thisargs = thisargs.tail)
    1.44 -                h = (h << 5) + thisargs.head.hashCode();
    1.45 -            return (h << 5) + this.restype.hashCode();
    1.46 -        }
    1.47 -
    1.48          public List<Type>        getParameterTypes() { return argtypes; }
    1.49          public Type              getReturnType()     { return restype; }
    1.50          public List<Type>        getThrownTypes()    { return thrown; }
     2.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Dec 14 11:16:46 2012 +0000
     2.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Sat Dec 15 13:54:51 2012 +0000
     2.3 @@ -1007,11 +1007,11 @@
     2.4                      if (!visit(supertype(t), supertype(s)))
     2.5                          return false;
     2.6  
     2.7 -                    HashSet<SingletonType> set = new HashSet<SingletonType>();
     2.8 +                    HashSet<UniqueType> set = new HashSet<UniqueType>();
     2.9                      for (Type x : interfaces(t))
    2.10 -                        set.add(new SingletonType(x));
    2.11 +                        set.add(new UniqueType(x, Types.this));
    2.12                      for (Type x : interfaces(s)) {
    2.13 -                        if (!set.remove(new SingletonType(x)))
    2.14 +                        if (!set.remove(new UniqueType(x, Types.this)))
    2.15                              return false;
    2.16                      }
    2.17                      return (set.isEmpty());
    2.18 @@ -3137,7 +3137,7 @@
    2.19              }
    2.20              @Override
    2.21              public int hashCode() {
    2.22 -                return 127 * Types.hashCode(t1) + Types.hashCode(t2);
    2.23 +                return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2);
    2.24              }
    2.25              @Override
    2.26              public boolean equals(Object obj) {
    2.27 @@ -3400,7 +3400,7 @@
    2.28      /**
    2.29       * Compute a hash code on a type.
    2.30       */
    2.31 -    public static int hashCode(Type t) {
    2.32 +    public int hashCode(Type t) {
    2.33          return hashCode.visit(t);
    2.34      }
    2.35      // where
    2.36 @@ -3423,6 +3423,16 @@
    2.37              }
    2.38  
    2.39              @Override
    2.40 +            public Integer visitMethodType(MethodType t, Void ignored) {
    2.41 +                int h = METHOD.ordinal();
    2.42 +                for (List<Type> thisargs = t.argtypes;
    2.43 +                     thisargs.tail != null;
    2.44 +                     thisargs = thisargs.tail)
    2.45 +                    h = (h << 5) + visit(thisargs.head);
    2.46 +                return (h << 5) + visit(t.restype);
    2.47 +            }
    2.48 +
    2.49 +            @Override
    2.50              public Integer visitWildcardType(WildcardType t, Void ignored) {
    2.51                  int result = t.kind.hashCode();
    2.52                  if (t.type != null) {
    2.53 @@ -4082,21 +4092,28 @@
    2.54      /**
    2.55       * A wrapper for a type that allows use in sets.
    2.56       */
    2.57 -    class SingletonType {
    2.58 -        final Type t;
    2.59 -        SingletonType(Type t) {
    2.60 -            this.t = t;
    2.61 +    public static class UniqueType {
    2.62 +        public final Type type;
    2.63 +        final Types types;
    2.64 +
    2.65 +        public UniqueType(Type type, Types types) {
    2.66 +            this.type = type;
    2.67 +            this.types = types;
    2.68          }
    2.69 +
    2.70          public int hashCode() {
    2.71 -            return Types.hashCode(t);
    2.72 +            return types.hashCode(type);
    2.73          }
    2.74 +
    2.75          public boolean equals(Object obj) {
    2.76 -            return (obj instanceof SingletonType) &&
    2.77 -                isSameType(t, ((SingletonType)obj).t);
    2.78 +            return (obj instanceof UniqueType) &&
    2.79 +                types.isSameType(type, ((UniqueType)obj).type);
    2.80          }
    2.81 +
    2.82          public String toString() {
    2.83 -            return t.toString();
    2.84 +            return type.toString();
    2.85          }
    2.86 +
    2.87      }
    2.88      // </editor-fold>
    2.89  
     3.1 --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Fri Dec 14 11:16:46 2012 +0000
     3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Sat Dec 15 13:54:51 2012 +0000
     3.3 @@ -692,8 +692,9 @@
     3.4          //determine the static bsm args
     3.5          Type mtype = makeFunctionalDescriptorType(targetType, true);
     3.6          List<Object> staticArgs = List.<Object>of(
     3.7 -                new Pool.MethodHandle(ClassFile.REF_invokeInterface, types.findDescriptorSymbol(targetType.tsym)),
     3.8 -                new Pool.MethodHandle(refKind, refSym),
     3.9 +                new Pool.MethodHandle(ClassFile.REF_invokeInterface,
    3.10 +                    types.findDescriptorSymbol(targetType.tsym), types),
    3.11 +                new Pool.MethodHandle(refKind, refSym, types),
    3.12                  new MethodType(mtype.getParameterTypes(),
    3.13                          mtype.getReturnType(),
    3.14                          mtype.getThrownTypes(),
     4.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Fri Dec 14 11:16:46 2012 +0000
     4.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Sat Dec 15 13:54:51 2012 +0000
     4.3 @@ -26,6 +26,8 @@
     4.4  package com.sun.tools.javac.jvm;
     4.5  
     4.6  import com.sun.tools.javac.code.Type;
     4.7 +import com.sun.tools.javac.code.Types;
     4.8 +import com.sun.tools.javac.code.Types.UniqueType;
     4.9  import com.sun.tools.javac.util.Name;
    4.10  
    4.11  
    4.12 @@ -166,22 +168,29 @@
    4.13       */
    4.14      public static class NameAndType {
    4.15          Name name;
    4.16 -        Type type;
    4.17 +        UniqueType uniqueType;
    4.18 +        Types types;
    4.19  
    4.20 -        NameAndType(Name name, Type type) {
    4.21 +        NameAndType(Name name, Type type, Types types) {
    4.22              this.name = name;
    4.23 -            this.type = type;
    4.24 +            this.uniqueType = new UniqueType(type, types);
    4.25 +            this.types = types;
    4.26          }
    4.27  
    4.28 -        public boolean equals(Object other) {
    4.29 -            return
    4.30 -                other instanceof NameAndType &&
    4.31 -                name == ((NameAndType) other).name &&
    4.32 -                type.equals(((NameAndType) other).type);
    4.33 +        void setType(Type type) {
    4.34 +            this.uniqueType = new UniqueType(type, types);
    4.35          }
    4.36  
    4.37 +        @Override
    4.38 +        public boolean equals(Object other) {
    4.39 +            return (other instanceof NameAndType &&
    4.40 +                    name == ((NameAndType) other).name &&
    4.41 +                        uniqueType.equals(((NameAndType) other).uniqueType));
    4.42 +        }
    4.43 +
    4.44 +        @Override
    4.45          public int hashCode() {
    4.46 -            return name.hashCode() * type.hashCode();
    4.47 +            return name.hashCode() * uniqueType.hashCode();
    4.48          }
    4.49      }
    4.50  }
     5.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri Dec 14 11:16:46 2012 +0000
     5.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Sat Dec 15 13:54:51 2012 +0000
     5.3 @@ -488,20 +488,20 @@
     5.4          case CONSTANT_Fieldref: {
     5.5              ClassSymbol owner = readClassSymbol(getChar(index + 1));
     5.6              NameAndType nt = (NameAndType)readPool(getChar(index + 3));
     5.7 -            poolObj[i] = new VarSymbol(0, nt.name, nt.type, owner);
     5.8 +            poolObj[i] = new VarSymbol(0, nt.name, nt.uniqueType.type, owner);
     5.9              break;
    5.10          }
    5.11          case CONSTANT_Methodref:
    5.12          case CONSTANT_InterfaceMethodref: {
    5.13              ClassSymbol owner = readClassSymbol(getChar(index + 1));
    5.14              NameAndType nt = (NameAndType)readPool(getChar(index + 3));
    5.15 -            poolObj[i] = new MethodSymbol(0, nt.name, nt.type, owner);
    5.16 +            poolObj[i] = new MethodSymbol(0, nt.name, nt.uniqueType.type, owner);
    5.17              break;
    5.18          }
    5.19          case CONSTANT_NameandType:
    5.20              poolObj[i] = new NameAndType(
    5.21                  readName(getChar(index + 1)),
    5.22 -                readType(getChar(index + 3)));
    5.23 +                readType(getChar(index + 3)), types);
    5.24              break;
    5.25          case CONSTANT_Integer:
    5.26              poolObj[i] = getInt(index + 1);
    5.27 @@ -1224,7 +1224,7 @@
    5.28          if (nt == null)
    5.29              return null;
    5.30  
    5.31 -        MethodType type = nt.type.asMethodType();
    5.32 +        MethodType type = nt.uniqueType.type.asMethodType();
    5.33  
    5.34          for (Scope.Entry e = scope.lookup(nt.name); e.scope != null; e = e.next())
    5.35              if (e.sym.kind == MTH && isSameBinaryType(e.sym.type.asMethodType(), type))
    5.36 @@ -1236,16 +1236,16 @@
    5.37          if ((flags & INTERFACE) != 0)
    5.38              // no enclosing instance
    5.39              return null;
    5.40 -        if (nt.type.getParameterTypes().isEmpty())
    5.41 +        if (nt.uniqueType.type.getParameterTypes().isEmpty())
    5.42              // no parameters
    5.43              return null;
    5.44  
    5.45          // A constructor of an inner class.
    5.46          // Remove the first argument (the enclosing instance)
    5.47 -        nt.type = new MethodType(nt.type.getParameterTypes().tail,
    5.48 -                                 nt.type.getReturnType(),
    5.49 -                                 nt.type.getThrownTypes(),
    5.50 -                                 syms.methodClass);
    5.51 +        nt.setType(new MethodType(nt.uniqueType.type.getParameterTypes().tail,
    5.52 +                                 nt.uniqueType.type.getReturnType(),
    5.53 +                                 nt.uniqueType.type.getThrownTypes(),
    5.54 +                                 syms.methodClass));
    5.55          // Try searching again
    5.56          return findMethod(nt, scope, flags);
    5.57      }
    5.58 @@ -1959,7 +1959,7 @@
    5.59  
    5.60          if (readAllOfClassFile) {
    5.61              for (int i = 1; i < poolObj.length; i++) readPool(i);
    5.62 -            c.pool = new Pool(poolObj.length, poolObj);
    5.63 +            c.pool = new Pool(poolObj.length, poolObj, types);
    5.64          }
    5.65  
    5.66          // reset and read rest of classinfo
     6.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Dec 14 11:16:46 2012 +0000
     6.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Sat Dec 15 13:54:51 2012 +0000
     6.3 @@ -39,7 +39,12 @@
     6.4  import com.sun.tools.javac.code.Attribute.RetentionPolicy;
     6.5  import com.sun.tools.javac.code.Symbol.*;
     6.6  import com.sun.tools.javac.code.Type.*;
     6.7 +import com.sun.tools.javac.code.Types.UniqueType;
     6.8  import com.sun.tools.javac.file.BaseFileObject;
     6.9 +import com.sun.tools.javac.jvm.Pool.DynamicMethod;
    6.10 +import com.sun.tools.javac.jvm.Pool.Method;
    6.11 +import com.sun.tools.javac.jvm.Pool.MethodHandle;
    6.12 +import com.sun.tools.javac.jvm.Pool.Variable;
    6.13  import com.sun.tools.javac.util.*;
    6.14  
    6.15  import static com.sun.tools.javac.code.BoundKind.*;
    6.16 @@ -142,7 +147,7 @@
    6.17      /** The bootstrap methods to be written in the corresponding class attribute
    6.18       *  (one for each invokedynamic)
    6.19       */
    6.20 -    Map<MethodSymbol, Pool.MethodHandle> bootstrapMethods;
    6.21 +    Map<DynamicMethod, MethodHandle> bootstrapMethods;
    6.22  
    6.23      /** The log to use for verbose output.
    6.24       */
    6.25 @@ -477,10 +482,10 @@
    6.26          while (i < pool.pp) {
    6.27              Object value = pool.pool[i];
    6.28              Assert.checkNonNull(value);
    6.29 -            if (value instanceof Pool.Method)
    6.30 -                value = ((Pool.Method)value).m;
    6.31 -            else if (value instanceof Pool.Variable)
    6.32 -                value = ((Pool.Variable)value).v;
    6.33 +            if (value instanceof Method)
    6.34 +                value = ((Method)value).m;
    6.35 +            else if (value instanceof Variable)
    6.36 +                value = ((Variable)value).v;
    6.37  
    6.38              if (value instanceof MethodSymbol) {
    6.39                  MethodSymbol m = (MethodSymbol)value;
    6.40 @@ -493,8 +498,9 @@
    6.41                  } else {
    6.42                      //invokedynamic
    6.43                      DynamicMethodSymbol dynSym = (DynamicMethodSymbol)m;
    6.44 -                    Pool.MethodHandle handle = new Pool.MethodHandle(dynSym.bsmKind, dynSym.bsm);
    6.45 -                    bootstrapMethods.put(dynSym, handle);
    6.46 +                    MethodHandle handle = new MethodHandle(dynSym.bsmKind, dynSym.bsm, types);
    6.47 +                    DynamicMethod dynMeth = new DynamicMethod(dynSym, types);
    6.48 +                    bootstrapMethods.put(dynMeth, handle);
    6.49                      //init cp entries
    6.50                      pool.put(names.BootstrapMethods);
    6.51                      pool.put(handle);
    6.52 @@ -531,7 +537,7 @@
    6.53                  NameAndType nt = (NameAndType)value;
    6.54                  poolbuf.appendByte(CONSTANT_NameandType);
    6.55                  poolbuf.appendChar(pool.put(nt.name));
    6.56 -                poolbuf.appendChar(pool.put(typeSig(nt.type)));
    6.57 +                poolbuf.appendChar(pool.put(typeSig(nt.uniqueType.type)));
    6.58              } else if (value instanceof Integer) {
    6.59                  poolbuf.appendByte(CONSTANT_Integer);
    6.60                  poolbuf.appendInt(((Integer)value).intValue());
    6.61 @@ -549,17 +555,18 @@
    6.62              } else if (value instanceof String) {
    6.63                  poolbuf.appendByte(CONSTANT_String);
    6.64                  poolbuf.appendChar(pool.put(names.fromString((String)value)));
    6.65 -            } else if (value instanceof MethodType) {
    6.66 -                MethodType mtype = (MethodType)value;
    6.67 -                poolbuf.appendByte(CONSTANT_MethodType);
    6.68 -                poolbuf.appendChar(pool.put(typeSig(mtype)));
    6.69 -            } else if (value instanceof Type) {
    6.70 -                Type type = (Type)value;
    6.71 -                if (type.hasTag(CLASS)) enterInner((ClassSymbol)type.tsym);
    6.72 -                poolbuf.appendByte(CONSTANT_Class);
    6.73 -                poolbuf.appendChar(pool.put(xClassName(type)));
    6.74 -            } else if (value instanceof Pool.MethodHandle) {
    6.75 -                Pool.MethodHandle ref = (Pool.MethodHandle)value;
    6.76 +            } else if (value instanceof UniqueType) {
    6.77 +                Type type = ((UniqueType)value).type;
    6.78 +                if (type instanceof MethodType) {
    6.79 +                    poolbuf.appendByte(CONSTANT_MethodType);
    6.80 +                    poolbuf.appendChar(pool.put(typeSig((MethodType)type)));
    6.81 +                } else {
    6.82 +                    if (type.hasTag(CLASS)) enterInner((ClassSymbol)type.tsym);
    6.83 +                    poolbuf.appendByte(CONSTANT_Class);
    6.84 +                    poolbuf.appendChar(pool.put(xClassName(type)));
    6.85 +                }
    6.86 +            } else if (value instanceof MethodHandle) {
    6.87 +                MethodHandle ref = (MethodHandle)value;
    6.88                  poolbuf.appendByte(CONSTANT_MethodHandle);
    6.89                  poolbuf.appendByte(ref.refKind);
    6.90                  poolbuf.appendChar(pool.put(ref.refSym));
    6.91 @@ -589,7 +596,7 @@
    6.92          return new NameAndType(fieldName(sym),
    6.93                                 retrofit
    6.94                                 ? sym.erasure(types)
    6.95 -                               : sym.externalType(types));
    6.96 +                               : sym.externalType(types), types);
    6.97          // if we retrofit, then the NameAndType has been read in as is
    6.98          // and no change is necessary. If we compile normally, the
    6.99          // NameAndType is generated from a symbol reference, and the
   6.100 @@ -951,14 +958,16 @@
   6.101      void writeBootstrapMethods() {
   6.102          int alenIdx = writeAttr(names.BootstrapMethods);
   6.103          databuf.appendChar(bootstrapMethods.size());
   6.104 -        for (Map.Entry<MethodSymbol, Pool.MethodHandle> entry : bootstrapMethods.entrySet()) {
   6.105 -            DynamicMethodSymbol dsym = (DynamicMethodSymbol)entry.getKey();
   6.106 +        for (Map.Entry<DynamicMethod, MethodHandle> entry : bootstrapMethods.entrySet()) {
   6.107 +            DynamicMethod dmeth = entry.getKey();
   6.108 +            DynamicMethodSymbol dsym = (DynamicMethodSymbol)dmeth.baseSymbol();
   6.109              //write BSM handle
   6.110              databuf.appendChar(pool.get(entry.getValue()));
   6.111              //write static args length
   6.112              databuf.appendChar(dsym.staticArgs.length);
   6.113              //write static args array
   6.114 -            for (Object o : dsym.staticArgs) {
   6.115 +            Object[] uniqueArgs = dmeth.uniqueStaticArgs;
   6.116 +            for (Object o : uniqueArgs) {
   6.117                  databuf.appendChar(pool.get(o));
   6.118              }
   6.119          }
   6.120 @@ -1534,7 +1543,7 @@
   6.121          pool = c.pool;
   6.122          innerClasses = null;
   6.123          innerClassesQueue = null;
   6.124 -        bootstrapMethods = new LinkedHashMap<MethodSymbol, Pool.MethodHandle>();
   6.125 +        bootstrapMethods = new LinkedHashMap<DynamicMethod, MethodHandle>();
   6.126  
   6.127          Type supertype = types.supertype(c.type);
   6.128          List<Type> interfaces = types.interfaces(c.type);
     7.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Code.java	Fri Dec 14 11:16:46 2012 +0000
     7.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java	Sat Dec 15 13:54:51 2012 +0000
     7.3 @@ -27,6 +27,7 @@
     7.4  
     7.5  import com.sun.tools.javac.code.*;
     7.6  import com.sun.tools.javac.code.Symbol.*;
     7.7 +import com.sun.tools.javac.code.Types.UniqueType;
     7.8  import com.sun.tools.javac.util.*;
     7.9  import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    7.10  
    7.11 @@ -901,6 +902,7 @@
    7.12          if (o instanceof ClassSymbol) return syms.classType;
    7.13          if (o instanceof Type.ArrayType) return syms.classType;
    7.14          if (o instanceof Type.MethodType) return syms.methodTypeType;
    7.15 +        if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type);
    7.16          if (o instanceof Pool.MethodHandle) return syms.methodHandleType;
    7.17          throw new AssertionError(o);
    7.18      }
    7.19 @@ -1030,7 +1032,7 @@
    7.20              Object o = pool.pool[od];
    7.21              Type t = (o instanceof Symbol)
    7.22                  ? ((Symbol)o).erasure(types)
    7.23 -                : types.erasure(((Type)o));
    7.24 +                : types.erasure((((UniqueType)o).type));
    7.25              state.push(t);
    7.26              break; }
    7.27          case ldc2w:
     8.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Fri Dec 14 11:16:46 2012 +0000
     8.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Sat Dec 15 13:54:51 2012 +0000
     8.3 @@ -94,6 +94,10 @@
     8.4          return instance;
     8.5      }
     8.6  
     8.7 +    /* Constant pool, reset by genClass.
     8.8 +     */
     8.9 +    private Pool pool;
    8.10 +
    8.11      protected Gen(Context context) {
    8.12          context.put(genKey, this);
    8.13  
    8.14 @@ -126,6 +130,7 @@
    8.15          genCrt = options.isSet(XJCOV);
    8.16          debugCode = options.isSet("debugcode");
    8.17          allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic");
    8.18 +        pool = new Pool(types);
    8.19  
    8.20          generateIproxies =
    8.21              target.requiresIproxy() ||
    8.22 @@ -174,10 +179,6 @@
    8.23       */
    8.24      private boolean useJsrLocally;
    8.25  
    8.26 -    /* Constant pool, reset by genClass.
    8.27 -     */
    8.28 -    private Pool pool = new Pool();
    8.29 -
    8.30      /** Code buffer, set by genMethod.
    8.31       */
    8.32      private Code code;
    8.33 @@ -705,7 +706,7 @@
    8.34          }
    8.35          int startpc = code.curPc();
    8.36          genStat(tree, env);
    8.37 -        if (tree.hasTag(BLOCK)) crtFlags |= CRT_BLOCK;
    8.38 +        if (tree.hasTag(Tag.BLOCK)) crtFlags |= CRT_BLOCK;
    8.39          code.crt.put(tree, crtFlags, startpc, code.curPc());
    8.40      }
    8.41  
     9.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Pool.java	Fri Dec 14 11:16:46 2012 +0000
     9.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Pool.java	Sat Dec 15 13:54:51 2012 +0000
     9.3 @@ -28,6 +28,9 @@
     9.4  import com.sun.tools.javac.code.Kinds;
     9.5  import com.sun.tools.javac.code.Symbol;
     9.6  import com.sun.tools.javac.code.Symbol.*;
     9.7 +import com.sun.tools.javac.code.Type;
     9.8 +import com.sun.tools.javac.code.Types;
     9.9 +import com.sun.tools.javac.code.Types.UniqueType;
    9.10  
    9.11  import com.sun.tools.javac.util.ArrayUtils;
    9.12  import com.sun.tools.javac.util.Assert;
    9.13 @@ -60,11 +63,14 @@
    9.14       */
    9.15      Map<Object,Integer> indices;
    9.16  
    9.17 +    Types types;
    9.18 +
    9.19      /** Construct a pool with given number of elements and element array.
    9.20       */
    9.21 -    public Pool(int pp, Object[] pool) {
    9.22 +    public Pool(int pp, Object[] pool, Types types) {
    9.23          this.pp = pp;
    9.24          this.pool = pool;
    9.25 +        this.types = types;
    9.26          this.indices = new HashMap<Object,Integer>(pool.length);
    9.27          for (int i = 1; i < pp; i++) {
    9.28              if (pool[i] != null) indices.put(pool[i], i);
    9.29 @@ -73,8 +79,8 @@
    9.30  
    9.31      /** Construct an empty pool.
    9.32       */
    9.33 -    public Pool() {
    9.34 -        this(1, new Object[64]);
    9.35 +    public Pool(Types types) {
    9.36 +        this(1, new Object[64], types);
    9.37      }
    9.38  
    9.39      /** Return the number of entries in the constant pool.
    9.40 @@ -114,11 +120,13 @@
    9.41  
    9.42      Object makePoolValue(Object o) {
    9.43          if (o instanceof DynamicMethodSymbol) {
    9.44 -            return new DynamicMethod((DynamicMethodSymbol)o);
    9.45 +            return new DynamicMethod((DynamicMethodSymbol)o, types);
    9.46          } else if (o instanceof MethodSymbol) {
    9.47 -            return new Method((MethodSymbol)o);
    9.48 +            return new Method((MethodSymbol)o, types);
    9.49          } else if (o instanceof VarSymbol) {
    9.50 -            return new Variable((VarSymbol)o);
    9.51 +            return new Variable((VarSymbol)o, types);
    9.52 +        } else if (o instanceof Type) {
    9.53 +            return new UniqueType((Type)o, types);
    9.54          } else {
    9.55              return o;
    9.56          }
    9.57 @@ -134,9 +142,11 @@
    9.58  
    9.59      static class Method extends DelegatedSymbol {
    9.60          MethodSymbol m;
    9.61 -        Method(MethodSymbol m) {
    9.62 +        UniqueType uniqueType;
    9.63 +        Method(MethodSymbol m, Types types) {
    9.64              super(m);
    9.65              this.m = m;
    9.66 +            this.uniqueType = new UniqueType(m.type, types);
    9.67          }
    9.68          public boolean equals(Object other) {
    9.69              if (!(other instanceof Method)) return false;
    9.70 @@ -144,20 +154,22 @@
    9.71              return
    9.72                  o.name == m.name &&
    9.73                  o.owner == m.owner &&
    9.74 -                o.type.equals(m.type);
    9.75 +                ((Method)other).uniqueType.equals(uniqueType);
    9.76          }
    9.77          public int hashCode() {
    9.78              return
    9.79                  m.name.hashCode() * 33 +
    9.80                  m.owner.hashCode() * 9 +
    9.81 -                m.type.hashCode();
    9.82 +                uniqueType.hashCode();
    9.83          }
    9.84      }
    9.85  
    9.86      static class DynamicMethod extends Method {
    9.87 +        public Object[] uniqueStaticArgs;
    9.88  
    9.89 -        DynamicMethod(DynamicMethodSymbol m) {
    9.90 -            super(m);
    9.91 +        DynamicMethod(DynamicMethodSymbol m, Types types) {
    9.92 +            super(m, types);
    9.93 +            uniqueStaticArgs = getUniqueTypeArray(m.staticArgs, types);
    9.94          }
    9.95  
    9.96          @Override
    9.97 @@ -168,7 +180,8 @@
    9.98              DynamicMethodSymbol dm2 = (DynamicMethodSymbol)((DynamicMethod)other).m;
    9.99              return dm1.bsm == dm2.bsm &&
   9.100                          dm1.bsmKind == dm2.bsmKind &&
   9.101 -                        Arrays.equals(dm1.staticArgs, dm2.staticArgs);
   9.102 +                        Arrays.equals(uniqueStaticArgs,
   9.103 +                            ((DynamicMethod)other).uniqueStaticArgs);
   9.104          }
   9.105  
   9.106          @Override
   9.107 @@ -178,17 +191,31 @@
   9.108              hash += dm.bsmKind * 7 +
   9.109                      dm.bsm.hashCode() * 11;
   9.110              for (int i = 0; i < dm.staticArgs.length; i++) {
   9.111 -                hash += (dm.staticArgs[i].hashCode() * 23);
   9.112 +                hash += (uniqueStaticArgs[i].hashCode() * 23);
   9.113              }
   9.114              return hash;
   9.115          }
   9.116 +
   9.117 +        private Object[] getUniqueTypeArray(Object[] objects, Types types) {
   9.118 +            Object[] result = new Object[objects.length];
   9.119 +            for (int i = 0; i < objects.length; i++) {
   9.120 +                if (objects[i] instanceof Type) {
   9.121 +                    result[i] = new UniqueType((Type)objects[i], types);
   9.122 +                } else {
   9.123 +                    result[i] = objects[i];
   9.124 +                }
   9.125 +            }
   9.126 +            return result;
   9.127 +        }
   9.128      }
   9.129  
   9.130      static class Variable extends DelegatedSymbol {
   9.131          VarSymbol v;
   9.132 -        Variable(VarSymbol v) {
   9.133 +        UniqueType uniqueType;
   9.134 +        Variable(VarSymbol v, Types types) {
   9.135              super(v);
   9.136              this.v = v;
   9.137 +            this.uniqueType = new UniqueType(v.type, types);
   9.138          }
   9.139          public boolean equals(Object other) {
   9.140              if (!(other instanceof Variable)) return false;
   9.141 @@ -196,13 +223,13 @@
   9.142              return
   9.143                  o.name == v.name &&
   9.144                  o.owner == v.owner &&
   9.145 -                o.type.equals(v.type);
   9.146 +                ((Variable)other).uniqueType.equals(uniqueType);
   9.147          }
   9.148          public int hashCode() {
   9.149              return
   9.150                  v.name.hashCode() * 33 +
   9.151                  v.owner.hashCode() * 9 +
   9.152 -                v.type.hashCode();
   9.153 +                uniqueType.hashCode();
   9.154          }
   9.155      }
   9.156  
   9.157 @@ -214,9 +241,12 @@
   9.158          /** Reference symbol */
   9.159          Symbol refSym;
   9.160  
   9.161 -        public MethodHandle(int refKind, Symbol refSym) {
   9.162 +        UniqueType uniqueType;
   9.163 +
   9.164 +        public MethodHandle(int refKind, Symbol refSym, Types types) {
   9.165              this.refKind = refKind;
   9.166              this.refSym = refSym;
   9.167 +            this.uniqueType = new UniqueType(this.refSym.type, types);
   9.168              checkConsistent();
   9.169          }
   9.170          public boolean equals(Object other) {
   9.171 @@ -227,14 +257,14 @@
   9.172              return
   9.173                  o.name == refSym.name &&
   9.174                  o.owner == refSym.owner &&
   9.175 -                o.type.equals(refSym.type);
   9.176 +                ((MethodHandle)other).uniqueType.equals(uniqueType);
   9.177          }
   9.178          public int hashCode() {
   9.179              return
   9.180                  refKind * 65 +
   9.181                  refSym.name.hashCode() * 33 +
   9.182                  refSym.owner.hashCode() * 9 +
   9.183 -                refSym.type.hashCode();
   9.184 +                uniqueType.hashCode();
   9.185          }
   9.186  
   9.187          /**
    10.1 --- a/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java	Fri Dec 14 11:16:46 2012 +0000
    10.2 +++ b/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java	Sat Dec 15 13:54:51 2012 +0000
    10.3 @@ -33,6 +33,7 @@
    10.4  import com.sun.tools.javac.code.Attribute;
    10.5  import com.sun.tools.javac.code.Symtab;
    10.6  import com.sun.tools.javac.code.Type;
    10.7 +import com.sun.tools.javac.code.Types;
    10.8  import com.sun.tools.javac.jvm.ClassReader;
    10.9  import com.sun.tools.javac.jvm.ClassWriter;
   10.10  import com.sun.tools.javac.jvm.Pool;
   10.11 @@ -173,7 +174,8 @@
   10.12                                     List.<Pair<Symbol.MethodSymbol,Attribute>>nil());
   10.13  
   10.14          Type.moreInfo = true;
   10.15 -        Pool pool = new Pool();
   10.16 +        Types types = Types.instance(task.getContext());
   10.17 +        Pool pool = new Pool(types);
   10.18          for (JavaFileObject file : fm.list(jarLocation, "", EnumSet.of(CLASS), true)) {
   10.19              String className = fm.inferBinaryName(jarLocation, file);
   10.20              int index = className.lastIndexOf('.');
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/test/tools/javac/8000518/DuplicateConstantPoolEntry.java	Sat Dec 15 13:54:51 2012 +0000
    11.3 @@ -0,0 +1,119 @@
    11.4 +/*
    11.5 + * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
    11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.7 + *
    11.8 + * This code is free software; you can redistribute it and/or modify it
    11.9 + * under the terms of the GNU General Public License version 2 only, as
   11.10 + * published by the Free Software Foundation.
   11.11 + *
   11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   11.15 + * version 2 for more details (a copy is included in the LICENSE file that
   11.16 + * accompanied this code).
   11.17 + *
   11.18 + * You should have received a copy of the GNU General Public License version
   11.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   11.21 + *
   11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   11.23 + * or visit www.oracle.com if you need additional information or have any
   11.24 + * questions.
   11.25 + */
   11.26 +
   11.27 +/*
   11.28 + * @test
   11.29 + * @bug 8000518
   11.30 + * @summary Javac generates duplicate name_and_type constant pool entry for
   11.31 + * class BinaryOpValueExp.java
   11.32 + * @run main DuplicateConstantPoolEntry
   11.33 + */
   11.34 +
   11.35 +import com.sun.source.util.JavacTask;
   11.36 +import com.sun.tools.classfile.ClassFile;
   11.37 +import com.sun.tools.classfile.ConstantPoolException;
   11.38 +import java.io.File;
   11.39 +import java.io.IOException;
   11.40 +import java.net.URI;
   11.41 +import java.util.Arrays;
   11.42 +import java.util.List;
   11.43 +import javax.tools.JavaCompiler;
   11.44 +import javax.tools.JavaFileObject;
   11.45 +import javax.tools.SimpleJavaFileObject;
   11.46 +import javax.tools.ToolProvider;
   11.47 +
   11.48 +/*
   11.49 + * This bug was reproduced having two classes B and C referenced from a class A
   11.50 + * class C should be compiled and generated in advance. Later class A and B should
   11.51 + * be compiled like this: javac A.java B.java
   11.52 + */
   11.53 +
   11.54 +public class DuplicateConstantPoolEntry {
   11.55 +
   11.56 +    public static void main(String args[]) throws Exception {
   11.57 +        new DuplicateConstantPoolEntry().run();
   11.58 +    }
   11.59 +
   11.60 +    void run() throws Exception {
   11.61 +        generateFilesNeeded();
   11.62 +        checkReference();
   11.63 +    }
   11.64 +
   11.65 +    void generateFilesNeeded() throws Exception {
   11.66 +
   11.67 +        StringJavaFileObject[] CSource = new StringJavaFileObject[] {
   11.68 +            new StringJavaFileObject("C.java",
   11.69 +                "class C {C(String s) {}}"),
   11.70 +        };
   11.71 +
   11.72 +        List<StringJavaFileObject> AandBSource = Arrays.asList(
   11.73 +                new StringJavaFileObject("A.java",
   11.74 +                    "class A {void test() {new B(null);new C(null);}}"),
   11.75 +                new StringJavaFileObject("B.java",
   11.76 +                    "class B {B(String s) {}}")
   11.77 +        );
   11.78 +
   11.79 +        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
   11.80 +        JavacTask compileC = (JavacTask)tool.getTask(null, null, null, null, null,
   11.81 +                Arrays.asList(CSource));
   11.82 +        if (!compileC.call()) {
   11.83 +            throw new AssertionError("Compilation error while compiling C.java sources");
   11.84 +        }
   11.85 +        JavacTask compileAB = (JavacTask)tool.getTask(null, null, null,
   11.86 +                Arrays.asList("-cp", "."), null, AandBSource);
   11.87 +        if (!compileAB.call()) {
   11.88 +            throw new AssertionError("Compilation error while compiling A and B sources");
   11.89 +        }
   11.90 +    }
   11.91 +
   11.92 +    void checkReference() throws IOException, ConstantPoolException {
   11.93 +        File file = new File("A.class");
   11.94 +        ClassFile classFile = ClassFile.read(file);
   11.95 +        for (int i = 1;
   11.96 +                i < classFile.constant_pool.size() - 1;
   11.97 +                i += classFile.constant_pool.get(i).size()) {
   11.98 +            for (int j = i + classFile.constant_pool.get(i).size();
   11.99 +                    j < classFile.constant_pool.size();
  11.100 +                    j += classFile.constant_pool.get(j).size()) {
  11.101 +                if (classFile.constant_pool.get(i).toString().
  11.102 +                        equals(classFile.constant_pool.get(j).toString())) {
  11.103 +                    throw new AssertionError(
  11.104 +                            "Duplicate entries in the constant pool at positions " +
  11.105 +                            i + " and " + j);
  11.106 +                }
  11.107 +            }
  11.108 +        }
  11.109 +    }
  11.110 +
  11.111 +    private static class StringJavaFileObject extends SimpleJavaFileObject {
  11.112 +        StringJavaFileObject(String name, String text) {
  11.113 +            super(URI.create(name), JavaFileObject.Kind.SOURCE);
  11.114 +            this.text = text;
  11.115 +        }
  11.116 +        @Override
  11.117 +        public CharSequence getCharContent(boolean b) {
  11.118 +            return text;
  11.119 +        }
  11.120 +        private String text;
  11.121 +    }
  11.122 +}
    12.1 --- a/test/tools/javac/lambda/TestInvokeDynamic.java	Fri Dec 14 11:16:46 2012 +0000
    12.2 +++ b/test/tools/javac/lambda/TestInvokeDynamic.java	Sat Dec 15 13:54:51 2012 +0000
    12.3 @@ -50,6 +50,7 @@
    12.4  import com.sun.tools.javac.code.Symbol;
    12.5  import com.sun.tools.javac.code.Symbol.MethodSymbol;
    12.6  import com.sun.tools.javac.code.Symtab;
    12.7 +import com.sun.tools.javac.code.Types;
    12.8  import com.sun.tools.javac.jvm.Pool;
    12.9  import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
   12.10  import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
   12.11 @@ -151,7 +152,7 @@
   12.12  
   12.13          abstract boolean check(CPInfo cpInfo) throws Exception;
   12.14  
   12.15 -        Object getValue(Symtab syms, Names names) {
   12.16 +        Object getValue(Symtab syms, Names names, Types types) {
   12.17              switch (this) {
   12.18                  case STRING:
   12.19                  case INTEGER:
   12.20 @@ -162,7 +163,7 @@
   12.21                  case CLASS:
   12.22                      return syms.stringType.tsym;
   12.23                  case METHOD_HANDLE:
   12.24 -                    return new Pool.MethodHandle(REF_invokeVirtual, syms.arrayCloneMethod);
   12.25 +                    return new Pool.MethodHandle(REF_invokeVirtual, syms.arrayCloneMethod, types);
   12.26                  case METHOD_TYPE:
   12.27                      return syms.arrayCloneMethod.type;
   12.28                  default:
   12.29 @@ -231,7 +232,8 @@
   12.30          Context context = ct.getContext();
   12.31          Symtab syms = Symtab.instance(context);
   12.32          Names names = Names.instance(context);
   12.33 -        ct.addTaskListener(new Indifier(syms, names));
   12.34 +        Types types = Types.instance(context);
   12.35 +        ct.addTaskListener(new Indifier(syms, names, types));
   12.36          try {
   12.37              ct.generate();
   12.38          } catch (Throwable t) {
   12.39 @@ -378,10 +380,12 @@
   12.40          MethodSymbol bsm;
   12.41          Symtab syms;
   12.42          Names names;
   12.43 +        Types types;
   12.44  
   12.45 -        Indifier(Symtab syms, Names names) {
   12.46 +        Indifier(Symtab syms, Names names, Types types) {
   12.47              this.syms = syms;
   12.48              this.names = names;
   12.49 +            this.types = types;
   12.50          }
   12.51  
   12.52          @Override
   12.53 @@ -405,7 +409,7 @@
   12.54              if (!oldSym.isConstructor()) {
   12.55                  Object[] staticArgs = new Object[arity.arity];
   12.56                  for (int i = 0; i < arity.arity ; i++) {
   12.57 -                    staticArgs[i] = saks[i].getValue(syms, names);
   12.58 +                    staticArgs[i] = saks[i].getValue(syms, names, types);
   12.59                  }
   12.60                  ident.sym = new Symbol.DynamicMethodSymbol(oldSym.name, oldSym.owner, REF_invokeStatic, bsm, oldSym.type, staticArgs);
   12.61              }

mercurial