Sat, 15 Dec 2012 13:54:51 +0000
8000518: Javac generates duplicate name_and_type constant pool entry for class BinaryOpValueExp.java
Reviewed-by: jjg, mcimadamore
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 }