# HG changeset patch # User vromero # Date 1355579691 0 # Node ID de1ec6fc93fe1df4e77ae864921f38f68b544fe2 # Parent 37a5d7eccb879bc4fbff400be3d59410bd3224dc 8000518: Javac generates duplicate name_and_type constant pool entry for class BinaryOpValueExp.java Reviewed-by: jjg, mcimadamore diff -r 37a5d7eccb87 -r de1ec6fc93fe src/share/classes/com/sun/tools/javac/code/Type.java --- a/src/share/classes/com/sun/tools/javac/code/Type.java Fri Dec 14 11:16:46 2012 +0000 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java Sat Dec 15 13:54:51 2012 +0000 @@ -302,10 +302,12 @@ * never complete classes. Where isSameType would complete a * class, equals assumes that the two types are different. */ + @Override public boolean equals(Object t) { return super.equals(t); } + @Override public int hashCode() { return super.hashCode(); } @@ -996,34 +998,6 @@ return "(" + argtypes + ")" + restype; } - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!(obj instanceof MethodType)) - return false; - MethodType m = (MethodType)obj; - List args1 = argtypes; - List args2 = m.argtypes; - while (!args1.isEmpty() && !args2.isEmpty()) { - if (!args1.head.equals(args2.head)) - return false; - args1 = args1.tail; - args2 = args2.tail; - } - if (!args1.isEmpty() || !args2.isEmpty()) - return false; - return restype.equals(m.restype); - } - - public int hashCode() { - int h = METHOD.ordinal(); - for (List thisargs = this.argtypes; - thisargs.tail != null; /*inlined: thisargs.nonEmpty()*/ - thisargs = thisargs.tail) - h = (h << 5) + thisargs.head.hashCode(); - return (h << 5) + this.restype.hashCode(); - } - public List getParameterTypes() { return argtypes; } public Type getReturnType() { return restype; } public List getThrownTypes() { return thrown; } diff -r 37a5d7eccb87 -r de1ec6fc93fe src/share/classes/com/sun/tools/javac/code/Types.java --- a/src/share/classes/com/sun/tools/javac/code/Types.java Fri Dec 14 11:16:46 2012 +0000 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Sat Dec 15 13:54:51 2012 +0000 @@ -1007,11 +1007,11 @@ if (!visit(supertype(t), supertype(s))) return false; - HashSet set = new HashSet(); + HashSet set = new HashSet(); for (Type x : interfaces(t)) - set.add(new SingletonType(x)); + set.add(new UniqueType(x, Types.this)); for (Type x : interfaces(s)) { - if (!set.remove(new SingletonType(x))) + if (!set.remove(new UniqueType(x, Types.this))) return false; } return (set.isEmpty()); @@ -3137,7 +3137,7 @@ } @Override public int hashCode() { - return 127 * Types.hashCode(t1) + Types.hashCode(t2); + return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2); } @Override public boolean equals(Object obj) { @@ -3400,7 +3400,7 @@ /** * Compute a hash code on a type. */ - public static int hashCode(Type t) { + public int hashCode(Type t) { return hashCode.visit(t); } // where @@ -3423,6 +3423,16 @@ } @Override + public Integer visitMethodType(MethodType t, Void ignored) { + int h = METHOD.ordinal(); + for (List thisargs = t.argtypes; + thisargs.tail != null; + thisargs = thisargs.tail) + h = (h << 5) + visit(thisargs.head); + return (h << 5) + visit(t.restype); + } + + @Override public Integer visitWildcardType(WildcardType t, Void ignored) { int result = t.kind.hashCode(); if (t.type != null) { @@ -4082,21 +4092,28 @@ /** * A wrapper for a type that allows use in sets. */ - class SingletonType { - final Type t; - SingletonType(Type t) { - this.t = t; + public static class UniqueType { + public final Type type; + final Types types; + + public UniqueType(Type type, Types types) { + this.type = type; + this.types = types; } + public int hashCode() { - return Types.hashCode(t); + return types.hashCode(type); } + public boolean equals(Object obj) { - return (obj instanceof SingletonType) && - isSameType(t, ((SingletonType)obj).t); + return (obj instanceof UniqueType) && + types.isSameType(type, ((UniqueType)obj).type); } + public String toString() { - return t.toString(); + return type.toString(); } + } // diff -r 37a5d7eccb87 -r de1ec6fc93fe src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Fri Dec 14 11:16:46 2012 +0000 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Sat Dec 15 13:54:51 2012 +0000 @@ -692,8 +692,9 @@ //determine the static bsm args Type mtype = makeFunctionalDescriptorType(targetType, true); List staticArgs = List.of( - new Pool.MethodHandle(ClassFile.REF_invokeInterface, types.findDescriptorSymbol(targetType.tsym)), - new Pool.MethodHandle(refKind, refSym), + new Pool.MethodHandle(ClassFile.REF_invokeInterface, + types.findDescriptorSymbol(targetType.tsym), types), + new Pool.MethodHandle(refKind, refSym, types), new MethodType(mtype.getParameterTypes(), mtype.getReturnType(), mtype.getThrownTypes(), diff -r 37a5d7eccb87 -r de1ec6fc93fe src/share/classes/com/sun/tools/javac/jvm/ClassFile.java --- a/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java Fri Dec 14 11:16:46 2012 +0000 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java Sat Dec 15 13:54:51 2012 +0000 @@ -26,6 +26,8 @@ package com.sun.tools.javac.jvm; import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.code.Types; +import com.sun.tools.javac.code.Types.UniqueType; import com.sun.tools.javac.util.Name; @@ -166,22 +168,29 @@ */ public static class NameAndType { Name name; - Type type; + UniqueType uniqueType; + Types types; - NameAndType(Name name, Type type) { + NameAndType(Name name, Type type, Types types) { this.name = name; - this.type = type; + this.uniqueType = new UniqueType(type, types); + this.types = types; } - public boolean equals(Object other) { - return - other instanceof NameAndType && - name == ((NameAndType) other).name && - type.equals(((NameAndType) other).type); + void setType(Type type) { + this.uniqueType = new UniqueType(type, types); } + @Override + public boolean equals(Object other) { + return (other instanceof NameAndType && + name == ((NameAndType) other).name && + uniqueType.equals(((NameAndType) other).uniqueType)); + } + + @Override public int hashCode() { - return name.hashCode() * type.hashCode(); + return name.hashCode() * uniqueType.hashCode(); } } } diff -r 37a5d7eccb87 -r de1ec6fc93fe src/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Dec 14 11:16:46 2012 +0000 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Sat Dec 15 13:54:51 2012 +0000 @@ -488,20 +488,20 @@ case CONSTANT_Fieldref: { ClassSymbol owner = readClassSymbol(getChar(index + 1)); NameAndType nt = (NameAndType)readPool(getChar(index + 3)); - poolObj[i] = new VarSymbol(0, nt.name, nt.type, owner); + poolObj[i] = new VarSymbol(0, nt.name, nt.uniqueType.type, owner); break; } case CONSTANT_Methodref: case CONSTANT_InterfaceMethodref: { ClassSymbol owner = readClassSymbol(getChar(index + 1)); NameAndType nt = (NameAndType)readPool(getChar(index + 3)); - poolObj[i] = new MethodSymbol(0, nt.name, nt.type, owner); + poolObj[i] = new MethodSymbol(0, nt.name, nt.uniqueType.type, owner); break; } case CONSTANT_NameandType: poolObj[i] = new NameAndType( readName(getChar(index + 1)), - readType(getChar(index + 3))); + readType(getChar(index + 3)), types); break; case CONSTANT_Integer: poolObj[i] = getInt(index + 1); @@ -1224,7 +1224,7 @@ if (nt == null) return null; - MethodType type = nt.type.asMethodType(); + MethodType type = nt.uniqueType.type.asMethodType(); for (Scope.Entry e = scope.lookup(nt.name); e.scope != null; e = e.next()) if (e.sym.kind == MTH && isSameBinaryType(e.sym.type.asMethodType(), type)) @@ -1236,16 +1236,16 @@ if ((flags & INTERFACE) != 0) // no enclosing instance return null; - if (nt.type.getParameterTypes().isEmpty()) + if (nt.uniqueType.type.getParameterTypes().isEmpty()) // no parameters return null; // A constructor of an inner class. // Remove the first argument (the enclosing instance) - nt.type = new MethodType(nt.type.getParameterTypes().tail, - nt.type.getReturnType(), - nt.type.getThrownTypes(), - syms.methodClass); + nt.setType(new MethodType(nt.uniqueType.type.getParameterTypes().tail, + nt.uniqueType.type.getReturnType(), + nt.uniqueType.type.getThrownTypes(), + syms.methodClass)); // Try searching again return findMethod(nt, scope, flags); } @@ -1959,7 +1959,7 @@ if (readAllOfClassFile) { for (int i = 1; i < poolObj.length; i++) readPool(i); - c.pool = new Pool(poolObj.length, poolObj); + c.pool = new Pool(poolObj.length, poolObj, types); } // reset and read rest of classinfo diff -r 37a5d7eccb87 -r de1ec6fc93fe src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java --- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Dec 14 11:16:46 2012 +0000 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Sat Dec 15 13:54:51 2012 +0000 @@ -39,7 +39,12 @@ import com.sun.tools.javac.code.Attribute.RetentionPolicy; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.*; +import com.sun.tools.javac.code.Types.UniqueType; import com.sun.tools.javac.file.BaseFileObject; +import com.sun.tools.javac.jvm.Pool.DynamicMethod; +import com.sun.tools.javac.jvm.Pool.Method; +import com.sun.tools.javac.jvm.Pool.MethodHandle; +import com.sun.tools.javac.jvm.Pool.Variable; import com.sun.tools.javac.util.*; import static com.sun.tools.javac.code.BoundKind.*; @@ -142,7 +147,7 @@ /** The bootstrap methods to be written in the corresponding class attribute * (one for each invokedynamic) */ - Map bootstrapMethods; + Map bootstrapMethods; /** The log to use for verbose output. */ @@ -477,10 +482,10 @@ while (i < pool.pp) { Object value = pool.pool[i]; Assert.checkNonNull(value); - if (value instanceof Pool.Method) - value = ((Pool.Method)value).m; - else if (value instanceof Pool.Variable) - value = ((Pool.Variable)value).v; + if (value instanceof Method) + value = ((Method)value).m; + else if (value instanceof Variable) + value = ((Variable)value).v; if (value instanceof MethodSymbol) { MethodSymbol m = (MethodSymbol)value; @@ -493,8 +498,9 @@ } else { //invokedynamic DynamicMethodSymbol dynSym = (DynamicMethodSymbol)m; - Pool.MethodHandle handle = new Pool.MethodHandle(dynSym.bsmKind, dynSym.bsm); - bootstrapMethods.put(dynSym, handle); + MethodHandle handle = new MethodHandle(dynSym.bsmKind, dynSym.bsm, types); + DynamicMethod dynMeth = new DynamicMethod(dynSym, types); + bootstrapMethods.put(dynMeth, handle); //init cp entries pool.put(names.BootstrapMethods); pool.put(handle); @@ -531,7 +537,7 @@ NameAndType nt = (NameAndType)value; poolbuf.appendByte(CONSTANT_NameandType); poolbuf.appendChar(pool.put(nt.name)); - poolbuf.appendChar(pool.put(typeSig(nt.type))); + poolbuf.appendChar(pool.put(typeSig(nt.uniqueType.type))); } else if (value instanceof Integer) { poolbuf.appendByte(CONSTANT_Integer); poolbuf.appendInt(((Integer)value).intValue()); @@ -549,17 +555,18 @@ } else if (value instanceof String) { poolbuf.appendByte(CONSTANT_String); poolbuf.appendChar(pool.put(names.fromString((String)value))); - } else if (value instanceof MethodType) { - MethodType mtype = (MethodType)value; - poolbuf.appendByte(CONSTANT_MethodType); - poolbuf.appendChar(pool.put(typeSig(mtype))); - } else if (value instanceof Type) { - Type type = (Type)value; - if (type.hasTag(CLASS)) enterInner((ClassSymbol)type.tsym); - poolbuf.appendByte(CONSTANT_Class); - poolbuf.appendChar(pool.put(xClassName(type))); - } else if (value instanceof Pool.MethodHandle) { - Pool.MethodHandle ref = (Pool.MethodHandle)value; + } else if (value instanceof UniqueType) { + Type type = ((UniqueType)value).type; + if (type instanceof MethodType) { + poolbuf.appendByte(CONSTANT_MethodType); + poolbuf.appendChar(pool.put(typeSig((MethodType)type))); + } else { + if (type.hasTag(CLASS)) enterInner((ClassSymbol)type.tsym); + poolbuf.appendByte(CONSTANT_Class); + poolbuf.appendChar(pool.put(xClassName(type))); + } + } else if (value instanceof MethodHandle) { + MethodHandle ref = (MethodHandle)value; poolbuf.appendByte(CONSTANT_MethodHandle); poolbuf.appendByte(ref.refKind); poolbuf.appendChar(pool.put(ref.refSym)); @@ -589,7 +596,7 @@ return new NameAndType(fieldName(sym), retrofit ? sym.erasure(types) - : sym.externalType(types)); + : sym.externalType(types), types); // if we retrofit, then the NameAndType has been read in as is // and no change is necessary. If we compile normally, the // NameAndType is generated from a symbol reference, and the @@ -951,14 +958,16 @@ void writeBootstrapMethods() { int alenIdx = writeAttr(names.BootstrapMethods); databuf.appendChar(bootstrapMethods.size()); - for (Map.Entry entry : bootstrapMethods.entrySet()) { - DynamicMethodSymbol dsym = (DynamicMethodSymbol)entry.getKey(); + for (Map.Entry entry : bootstrapMethods.entrySet()) { + DynamicMethod dmeth = entry.getKey(); + DynamicMethodSymbol dsym = (DynamicMethodSymbol)dmeth.baseSymbol(); //write BSM handle databuf.appendChar(pool.get(entry.getValue())); //write static args length databuf.appendChar(dsym.staticArgs.length); //write static args array - for (Object o : dsym.staticArgs) { + Object[] uniqueArgs = dmeth.uniqueStaticArgs; + for (Object o : uniqueArgs) { databuf.appendChar(pool.get(o)); } } @@ -1534,7 +1543,7 @@ pool = c.pool; innerClasses = null; innerClassesQueue = null; - bootstrapMethods = new LinkedHashMap(); + bootstrapMethods = new LinkedHashMap(); Type supertype = types.supertype(c.type); List interfaces = types.interfaces(c.type); diff -r 37a5d7eccb87 -r de1ec6fc93fe src/share/classes/com/sun/tools/javac/jvm/Code.java --- a/src/share/classes/com/sun/tools/javac/jvm/Code.java Fri Dec 14 11:16:46 2012 +0000 +++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java Sat Dec 15 13:54:51 2012 +0000 @@ -27,6 +27,7 @@ import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Symbol.*; +import com.sun.tools.javac.code.Types.UniqueType; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; @@ -901,6 +902,7 @@ if (o instanceof ClassSymbol) return syms.classType; if (o instanceof Type.ArrayType) return syms.classType; if (o instanceof Type.MethodType) return syms.methodTypeType; + if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type); if (o instanceof Pool.MethodHandle) return syms.methodHandleType; throw new AssertionError(o); } @@ -1030,7 +1032,7 @@ Object o = pool.pool[od]; Type t = (o instanceof Symbol) ? ((Symbol)o).erasure(types) - : types.erasure(((Type)o)); + : types.erasure((((UniqueType)o).type)); state.push(t); break; } case ldc2w: diff -r 37a5d7eccb87 -r de1ec6fc93fe src/share/classes/com/sun/tools/javac/jvm/Gen.java --- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java Fri Dec 14 11:16:46 2012 +0000 +++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java Sat Dec 15 13:54:51 2012 +0000 @@ -94,6 +94,10 @@ return instance; } + /* Constant pool, reset by genClass. + */ + private Pool pool; + protected Gen(Context context) { context.put(genKey, this); @@ -126,6 +130,7 @@ genCrt = options.isSet(XJCOV); debugCode = options.isSet("debugcode"); allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic"); + pool = new Pool(types); generateIproxies = target.requiresIproxy() || @@ -174,10 +179,6 @@ */ private boolean useJsrLocally; - /* Constant pool, reset by genClass. - */ - private Pool pool = new Pool(); - /** Code buffer, set by genMethod. */ private Code code; @@ -705,7 +706,7 @@ } int startpc = code.curPc(); genStat(tree, env); - if (tree.hasTag(BLOCK)) crtFlags |= CRT_BLOCK; + if (tree.hasTag(Tag.BLOCK)) crtFlags |= CRT_BLOCK; code.crt.put(tree, crtFlags, startpc, code.curPc()); } diff -r 37a5d7eccb87 -r de1ec6fc93fe src/share/classes/com/sun/tools/javac/jvm/Pool.java --- a/src/share/classes/com/sun/tools/javac/jvm/Pool.java Fri Dec 14 11:16:46 2012 +0000 +++ b/src/share/classes/com/sun/tools/javac/jvm/Pool.java Sat Dec 15 13:54:51 2012 +0000 @@ -28,6 +28,9 @@ import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.*; +import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.code.Types; +import com.sun.tools.javac.code.Types.UniqueType; import com.sun.tools.javac.util.ArrayUtils; import com.sun.tools.javac.util.Assert; @@ -60,11 +63,14 @@ */ Map indices; + Types types; + /** Construct a pool with given number of elements and element array. */ - public Pool(int pp, Object[] pool) { + public Pool(int pp, Object[] pool, Types types) { this.pp = pp; this.pool = pool; + this.types = types; this.indices = new HashMap(pool.length); for (int i = 1; i < pp; i++) { if (pool[i] != null) indices.put(pool[i], i); @@ -73,8 +79,8 @@ /** Construct an empty pool. */ - public Pool() { - this(1, new Object[64]); + public Pool(Types types) { + this(1, new Object[64], types); } /** Return the number of entries in the constant pool. @@ -114,11 +120,13 @@ Object makePoolValue(Object o) { if (o instanceof DynamicMethodSymbol) { - return new DynamicMethod((DynamicMethodSymbol)o); + return new DynamicMethod((DynamicMethodSymbol)o, types); } else if (o instanceof MethodSymbol) { - return new Method((MethodSymbol)o); + return new Method((MethodSymbol)o, types); } else if (o instanceof VarSymbol) { - return new Variable((VarSymbol)o); + return new Variable((VarSymbol)o, types); + } else if (o instanceof Type) { + return new UniqueType((Type)o, types); } else { return o; } @@ -134,9 +142,11 @@ static class Method extends DelegatedSymbol { MethodSymbol m; - Method(MethodSymbol m) { + UniqueType uniqueType; + Method(MethodSymbol m, Types types) { super(m); this.m = m; + this.uniqueType = new UniqueType(m.type, types); } public boolean equals(Object other) { if (!(other instanceof Method)) return false; @@ -144,20 +154,22 @@ return o.name == m.name && o.owner == m.owner && - o.type.equals(m.type); + ((Method)other).uniqueType.equals(uniqueType); } public int hashCode() { return m.name.hashCode() * 33 + m.owner.hashCode() * 9 + - m.type.hashCode(); + uniqueType.hashCode(); } } static class DynamicMethod extends Method { + public Object[] uniqueStaticArgs; - DynamicMethod(DynamicMethodSymbol m) { - super(m); + DynamicMethod(DynamicMethodSymbol m, Types types) { + super(m, types); + uniqueStaticArgs = getUniqueTypeArray(m.staticArgs, types); } @Override @@ -168,7 +180,8 @@ DynamicMethodSymbol dm2 = (DynamicMethodSymbol)((DynamicMethod)other).m; return dm1.bsm == dm2.bsm && dm1.bsmKind == dm2.bsmKind && - Arrays.equals(dm1.staticArgs, dm2.staticArgs); + Arrays.equals(uniqueStaticArgs, + ((DynamicMethod)other).uniqueStaticArgs); } @Override @@ -178,17 +191,31 @@ hash += dm.bsmKind * 7 + dm.bsm.hashCode() * 11; for (int i = 0; i < dm.staticArgs.length; i++) { - hash += (dm.staticArgs[i].hashCode() * 23); + hash += (uniqueStaticArgs[i].hashCode() * 23); } return hash; } + + private Object[] getUniqueTypeArray(Object[] objects, Types types) { + Object[] result = new Object[objects.length]; + for (int i = 0; i < objects.length; i++) { + if (objects[i] instanceof Type) { + result[i] = new UniqueType((Type)objects[i], types); + } else { + result[i] = objects[i]; + } + } + return result; + } } static class Variable extends DelegatedSymbol { VarSymbol v; - Variable(VarSymbol v) { + UniqueType uniqueType; + Variable(VarSymbol v, Types types) { super(v); this.v = v; + this.uniqueType = new UniqueType(v.type, types); } public boolean equals(Object other) { if (!(other instanceof Variable)) return false; @@ -196,13 +223,13 @@ return o.name == v.name && o.owner == v.owner && - o.type.equals(v.type); + ((Variable)other).uniqueType.equals(uniqueType); } public int hashCode() { return v.name.hashCode() * 33 + v.owner.hashCode() * 9 + - v.type.hashCode(); + uniqueType.hashCode(); } } @@ -214,9 +241,12 @@ /** Reference symbol */ Symbol refSym; - public MethodHandle(int refKind, Symbol refSym) { + UniqueType uniqueType; + + public MethodHandle(int refKind, Symbol refSym, Types types) { this.refKind = refKind; this.refSym = refSym; + this.uniqueType = new UniqueType(this.refSym.type, types); checkConsistent(); } public boolean equals(Object other) { @@ -227,14 +257,14 @@ return o.name == refSym.name && o.owner == refSym.owner && - o.type.equals(refSym.type); + ((MethodHandle)other).uniqueType.equals(uniqueType); } public int hashCode() { return refKind * 65 + refSym.name.hashCode() * 33 + refSym.owner.hashCode() * 9 + - refSym.type.hashCode(); + uniqueType.hashCode(); } /** diff -r 37a5d7eccb87 -r de1ec6fc93fe src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java --- a/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java Fri Dec 14 11:16:46 2012 +0000 +++ b/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java Sat Dec 15 13:54:51 2012 +0000 @@ -33,6 +33,7 @@ import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.code.Types; import com.sun.tools.javac.jvm.ClassReader; import com.sun.tools.javac.jvm.ClassWriter; import com.sun.tools.javac.jvm.Pool; @@ -173,7 +174,8 @@ List.>nil()); Type.moreInfo = true; - Pool pool = new Pool(); + Types types = Types.instance(task.getContext()); + Pool pool = new Pool(types); for (JavaFileObject file : fm.list(jarLocation, "", EnumSet.of(CLASS), true)) { String className = fm.inferBinaryName(jarLocation, file); int index = className.lastIndexOf('.'); diff -r 37a5d7eccb87 -r de1ec6fc93fe test/tools/javac/8000518/DuplicateConstantPoolEntry.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/8000518/DuplicateConstantPoolEntry.java Sat Dec 15 13:54:51 2012 +0000 @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8000518 + * @summary Javac generates duplicate name_and_type constant pool entry for + * class BinaryOpValueExp.java + * @run main DuplicateConstantPoolEntry + */ + +import com.sun.source.util.JavacTask; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.ConstantPoolException; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.util.Arrays; +import java.util.List; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.ToolProvider; + +/* + * This bug was reproduced having two classes B and C referenced from a class A + * class C should be compiled and generated in advance. Later class A and B should + * be compiled like this: javac A.java B.java + */ + +public class DuplicateConstantPoolEntry { + + public static void main(String args[]) throws Exception { + new DuplicateConstantPoolEntry().run(); + } + + void run() throws Exception { + generateFilesNeeded(); + checkReference(); + } + + void generateFilesNeeded() throws Exception { + + StringJavaFileObject[] CSource = new StringJavaFileObject[] { + new StringJavaFileObject("C.java", + "class C {C(String s) {}}"), + }; + + List AandBSource = Arrays.asList( + new StringJavaFileObject("A.java", + "class A {void test() {new B(null);new C(null);}}"), + new StringJavaFileObject("B.java", + "class B {B(String s) {}}") + ); + + final JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); + JavacTask compileC = (JavacTask)tool.getTask(null, null, null, null, null, + Arrays.asList(CSource)); + if (!compileC.call()) { + throw new AssertionError("Compilation error while compiling C.java sources"); + } + JavacTask compileAB = (JavacTask)tool.getTask(null, null, null, + Arrays.asList("-cp", "."), null, AandBSource); + if (!compileAB.call()) { + throw new AssertionError("Compilation error while compiling A and B sources"); + } + } + + void checkReference() throws IOException, ConstantPoolException { + File file = new File("A.class"); + ClassFile classFile = ClassFile.read(file); + for (int i = 1; + i < classFile.constant_pool.size() - 1; + i += classFile.constant_pool.get(i).size()) { + for (int j = i + classFile.constant_pool.get(i).size(); + j < classFile.constant_pool.size(); + j += classFile.constant_pool.get(j).size()) { + if (classFile.constant_pool.get(i).toString(). + equals(classFile.constant_pool.get(j).toString())) { + throw new AssertionError( + "Duplicate entries in the constant pool at positions " + + i + " and " + j); + } + } + } + } + + private static class StringJavaFileObject extends SimpleJavaFileObject { + StringJavaFileObject(String name, String text) { + super(URI.create(name), JavaFileObject.Kind.SOURCE); + this.text = text; + } + @Override + public CharSequence getCharContent(boolean b) { + return text; + } + private String text; + } +} diff -r 37a5d7eccb87 -r de1ec6fc93fe test/tools/javac/lambda/TestInvokeDynamic.java --- a/test/tools/javac/lambda/TestInvokeDynamic.java Fri Dec 14 11:16:46 2012 +0000 +++ b/test/tools/javac/lambda/TestInvokeDynamic.java Sat Dec 15 13:54:51 2012 +0000 @@ -50,6 +50,7 @@ import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.code.Symtab; +import com.sun.tools.javac.code.Types; import com.sun.tools.javac.jvm.Pool; import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; @@ -151,7 +152,7 @@ abstract boolean check(CPInfo cpInfo) throws Exception; - Object getValue(Symtab syms, Names names) { + Object getValue(Symtab syms, Names names, Types types) { switch (this) { case STRING: case INTEGER: @@ -162,7 +163,7 @@ case CLASS: return syms.stringType.tsym; case METHOD_HANDLE: - return new Pool.MethodHandle(REF_invokeVirtual, syms.arrayCloneMethod); + return new Pool.MethodHandle(REF_invokeVirtual, syms.arrayCloneMethod, types); case METHOD_TYPE: return syms.arrayCloneMethod.type; default: @@ -231,7 +232,8 @@ Context context = ct.getContext(); Symtab syms = Symtab.instance(context); Names names = Names.instance(context); - ct.addTaskListener(new Indifier(syms, names)); + Types types = Types.instance(context); + ct.addTaskListener(new Indifier(syms, names, types)); try { ct.generate(); } catch (Throwable t) { @@ -378,10 +380,12 @@ MethodSymbol bsm; Symtab syms; Names names; + Types types; - Indifier(Symtab syms, Names names) { + Indifier(Symtab syms, Names names, Types types) { this.syms = syms; this.names = names; + this.types = types; } @Override @@ -405,7 +409,7 @@ if (!oldSym.isConstructor()) { Object[] staticArgs = new Object[arity.arity]; for (int i = 0; i < arity.arity ; i++) { - staticArgs[i] = saks[i].getValue(syms, names); + staticArgs[i] = saks[i].getValue(syms, names, types); } ident.sym = new Symbol.DynamicMethodSymbol(oldSym.name, oldSym.owner, REF_invokeStatic, bsm, oldSym.type, staticArgs); }