changeset 3286:e48d890d4788

Enhancement: Split CompoundType_info into ArrayType_info and MethodDescriptor_info
author mcimadamore
date Thu, 21 Jan 2016 16:30:27 +0000
parents ce45cc7d0b52
children 659f44b99b6c
files src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Pool.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolReader.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassTranslator.java src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassWriter.java src/jdk.jdeps/share/classes/com/sun/tools/classfile/ConstantPool.java src/jdk.jdeps/share/classes/com/sun/tools/classfile/Dependencies.java src/jdk.jdeps/share/classes/com/sun/tools/classfile/ReferenceFinder.java src/jdk.jdeps/share/classes/com/sun/tools/javap/ConstantWriter.java test/tools/javac/lambda/ByteCodeTest.java
diffstat 11 files changed, 278 insertions(+), 118 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Tue Jan 19 15:23:34 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Thu Jan 21 16:30:27 2016 +0000
@@ -88,7 +88,8 @@
     public final static int CONSTANT_InvokeDynamic = 18;
     public final static int CONSTANT_TypeVar = 19;
     public final static int CONSTANT_ParameterizedType = 20;
-    public final static int CONSTANT_CompoundType = 21;
+    public final static int CONSTANT_ArrayType = 21;
+    public final static int CONSTANT_MethodDescriptor = 22;
 
     public final static int REF_getField = 1;
     public final static int REF_getStatic = 2;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Pool.java	Tue Jan 19 15:23:34 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Pool.java	Thu Jan 21 16:30:27 2016 +0000
@@ -464,35 +464,65 @@
     }
 
     /**
-     * Pool entry associated with compound type entries (either array or methods). A compound descriptor is made up
-     * of a string descriptor (containing on or more holes) and a set of replacements. For instance,
-     * an array type is represented with the string descriptor "#]" where "#" denotes a hole to
-     * be replaced by actual array element type.
+     * Pool entry associated with array types.
      */
-    static class CompoundType extends Entry {
+    static class ArrayType extends Entry {
 
-        /** Descriptor. */
-        Constant<Name> template;
+        /** Dimensions. */
+        int arrayDepth;
 
-        /** Holes list. */
-        Entry[] holes;
+        /** Element type. */
+        Entry componentType;
 
-        CompoundType(Constant<Name> template, Entry[] holes, Type t) {
-            super(ClassFile.CONSTANT_CompoundType, t);
-            this.template = template;
-            this.holes = holes;
+        ArrayType(int dims, Entry componentType, Type t) {
+            super(ClassFile.CONSTANT_ArrayType, t);
+            this.arrayDepth = dims;
+            this.componentType = componentType;
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(template, Arrays.hashCode(holes));
+            return Objects.hash(componentType, arrayDepth);
         }
 
         @Override
         public boolean equals(Object obj) {
-            if (obj instanceof CompoundType) {
-                CompoundType that = (CompoundType)obj;
-                return that.template.equals(template) && Objects.deepEquals(that.holes, holes);
+            if (obj instanceof ArrayType) {
+                ArrayType that = (ArrayType)obj;
+                return that.arrayDepth == arrayDepth && that.componentType.equals(componentType);
+            } else {
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Pool entry associated with method descriptors.
+     */
+    static class MethodDescriptor extends Entry {
+
+        /** Arguments. */
+        Entry[] args;
+
+        /** Return type. */
+        Entry returnType;
+
+        MethodDescriptor(Entry[] args, Entry returnType, Type t) {
+            super(ClassFile.CONSTANT_MethodDescriptor, t);
+            this.args = args;
+            this.returnType = returnType;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(returnType, Arrays.hashCode(args));
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof MethodDescriptor) {
+                MethodDescriptor that = (MethodDescriptor)obj;
+                return that.returnType.equals(returnType) && Objects.deepEquals(args, that.args);
             } else {
                 return false;
             }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolReader.java	Tue Jan 19 15:23:34 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolReader.java	Thu Jan 21 16:30:27 2016 +0000
@@ -29,17 +29,20 @@
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.VarSymbol;
 import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.ArrayType;
+import com.sun.tools.javac.code.Type.MethodType;
 import com.sun.tools.javac.code.Types;
 import com.sun.tools.javac.jvm.Pool.Entry;
 import com.sun.tools.javac.util.ByteBuffer;
 import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Name;
 import com.sun.tools.javac.util.Tuple.Tuple2;
 
 import java.util.Optional;
 
+import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_ArrayType;
 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Class;
-import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_CompoundType;
 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Double;
 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Fieldref;
 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Float;
@@ -47,6 +50,7 @@
 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_InterfaceMethodref;
 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_InvokeDynamic;
 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Long;
+import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_MethodDescriptor;
 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_MethodHandle;
 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Methodref;
 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_MethodType;
@@ -266,25 +270,45 @@
     }
 
     /**
-     * Unresolved entry pointing to a either an array or a method type.
+     * Unresolved entry pointing to an array type.
      */
-    class UnresolvedCompoundType extends Unresolved<Type> {
+    class UnresolvedArrayType extends Unresolved<Type> {
 
-        int nholes;
-
-        UnresolvedCompoundType(int tag, int offset, int nholes) {
+        UnresolvedArrayType(int tag, int offset) {
             super(tag, offset);
-            this.nholes = nholes;
         }
 
         @Override
         Type doResolve() {
-            String template = getName(reader.buf.getChar(offset)).toString();
-            for (int i = 0 ; i < nholes ; i++) {
-                Type hole = getType(reader.buf.getChar(offset + 3 + (i * 2)));
-                template = template.replaceFirst("#", types.typeSig(hole).toString());
+            int dims = reader.buf.getByte(offset);
+            Type t = getType(reader.buf.getChar(offset + 1));
+            for (int i = 0 ; i < dims ; i++) {
+                t = new ArrayType(t, types.syms.arrayClass);
             }
-            return resolveSig(types.names.fromString(template));
+            return t;
+        }
+    }
+
+    /**
+     * Unresolved entry pointing to a method descriptor.
+     */
+    class UnresolvedMethodDescriptor extends Unresolved<Type> {
+
+        int nargs;
+
+        UnresolvedMethodDescriptor(int tag, int offset, int nargs) {
+            super(tag, offset);
+            this.nargs = nargs;
+        }
+
+        @Override
+        Type doResolve() {
+            Type retType = getType(reader.buf.getChar(offset + 1));
+            ListBuffer<Type> args = new ListBuffer<>();
+            for (int i = 0 ; i < nargs ; i++) {
+                args.add(getType(reader.buf.getChar(offset + 3 + (i * 2))));
+            }
+            return new MethodType(args.toList(), retType, List.nil(), types.syms.methodClass);
         }
     }
 
@@ -319,7 +343,8 @@
             case CONSTANT_Utf8:
                 return resolveSig((Name)e.data.get());
             case CONSTANT_TypeVar:
-            case CONSTANT_CompoundType:
+            case CONSTANT_ArrayType:
+            case CONSTANT_MethodDescriptor:
             case CONSTANT_ParameterizedType:
                 return types.erasure((Type)e.data.get());
             default:
@@ -426,10 +451,14 @@
                     offset += 3 + (nargs * 2);
                     pool.put(new UnresolvedParameterizedType(tag, start, nargs));
                     break;
-                case CONSTANT_CompoundType:
-                    int nholes = poolbuf.getByte(start + 2) & 0xFF;
-                    offset += 3 + (nholes * 2);
-                    pool.put(new UnresolvedCompoundType(tag, start, nholes));
+                case CONSTANT_ArrayType:
+                    offset += 3;
+                    pool.put(new UnresolvedArrayType(tag, start));
+                    break;
+                case CONSTANT_MethodDescriptor:
+                    int nparams = poolbuf.getByte(start + 2) & 0xFF;
+                    offset += 3 + (nparams * 2);
+                    pool.put(new UnresolvedMethodDescriptor(tag, start, nparams));
                     break;
                 default:
                     throw reader.badClassFile("bad.const.pool.tag.at",
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java	Tue Jan 19 15:23:34 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java	Thu Jan 21 16:30:27 2016 +0000
@@ -36,21 +36,18 @@
 import com.sun.tools.javac.code.Type.ArrayType;
 import com.sun.tools.javac.code.Type.CapturedType;
 import com.sun.tools.javac.code.Type.ClassType;
-import com.sun.tools.javac.code.Type.DelegatedType;
 import com.sun.tools.javac.code.Type.TypeVar;
 import com.sun.tools.javac.code.Type.WildcardType;
-import com.sun.tools.javac.code.TypeMetadata;
-import com.sun.tools.javac.code.TypeTag;
 import com.sun.tools.javac.code.Types;
 import com.sun.tools.javac.code.Types.DefaultSymbolVisitor;
 import com.sun.tools.javac.code.Types.DefaultTypeVisitor;
 import com.sun.tools.javac.jvm.ClassWriter.PoolOverflow;
 import com.sun.tools.javac.jvm.ClassWriter.StringOverflow;
 import com.sun.tools.javac.jvm.Gen.Descriptor;
-import com.sun.tools.javac.jvm.Pool.CompoundType;
 import com.sun.tools.javac.jvm.Pool.Constant;
 import com.sun.tools.javac.jvm.Pool.InvokeDynamic;
 import com.sun.tools.javac.jvm.Pool.MemberRef;
+import com.sun.tools.javac.jvm.Pool.MethodDescriptor;
 import com.sun.tools.javac.jvm.Pool.MethodHandle;
 import com.sun.tools.javac.jvm.Pool.MethodType;
 import com.sun.tools.javac.jvm.Pool.NameAndType;
@@ -61,7 +58,6 @@
 import com.sun.tools.javac.jvm.Pool.TypeVariable;
 import com.sun.tools.javac.util.Assert;
 import com.sun.tools.javac.util.ByteBuffer;
-import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.Name;
 import com.sun.tools.javac.util.Tuple.Tuple2;
 
@@ -71,13 +67,11 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.function.Function;
-import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import static com.sun.tools.javac.code.Kinds.Kind.TYP;
 import static com.sun.tools.javac.code.TypeTag.ANY_BOUND;
 import static com.sun.tools.javac.code.TypeTag.CLASS;
-import static com.sun.tools.javac.code.TypeTag.NONE;
 
 /**
  * Pool interface towards {@code ClassWriter}. Exposes methods to encode and write javac entities
@@ -465,10 +459,8 @@
                 useNewCPForms = true;
                 int dim = types.dimensions(t);
                 Assert.check(dim <= 16);
-                Constant<Name> template = (Constant<Name>)makeConstant(types.names.fromString(
-                        arrayTemplate.substring(arrayTemplate.length() - 1 - dim, arrayTemplate.length())));
-                Entry[] holes = new Entry[] { visit(elemRec, typeNameFunc) };
-                Entry e = new CompoundType(template, holes, t);
+                Entry component = visit(elemRec, typeNameFunc);
+                Entry e = new Pool.ArrayType(dim, component, t);
                 return pool.put(e);
             }
         }
@@ -480,37 +472,15 @@
                 return super.visitMethodType(t, typeNameFunc);
             } else {
                 useNewCPForms = true;
-                List<Type> holes = methodHoleTypes(t);
-                Function<Type, String> holeMapper = h -> h.hasTag(NONE) ? "#" : typeToSig(h).toString();
-                String args = holes.tail.stream()
-                        .map(holeMapper)
-                        .collect(Collectors.joining("","(",")"));
-                String ret = holeMapper.apply(holes.head);
-                Entry e = new CompoundType((Constant<Name>)makeConstant(types.names.fromString(args + ret)),
-                        holes.stream()
-                                .filter(h -> h.hasTag(NONE))
-                                .map(h -> makeType(h.baseType(), PoolWriter.this::typeToSig))
-                                .toArray(Entry[]::new), t);
+                Entry[] args = t.getParameterTypes().stream()
+                        .map(p -> visit(p, typeNameFunc))
+                        .toArray(Entry[]::new);
+                Entry ret = visit(t.getReturnType(), typeNameFunc);
+                Entry e = new MethodDescriptor(args, ret, t);
                 return pool.put(e);
             }
         }
 
-        private List<Type> methodHoleTypes(Type.MethodType type) {
-            return type.getParameterTypes().prepend(type.getReturnType()).stream()
-                    .map(t -> (t.isPrimitiveOrVoid() || (t.hasTag(TypeTag.CLASS) && t.allparams().isEmpty())) ?
-                            t : new DelegatedType(TypeTag.NONE, t) {
-                                @Override
-                                public Type cloneWithMetadata(TypeMetadata metadata) {
-                                    return null;
-                                }
-                                @Override
-                                public Type baseType() {
-                                    return t;
-                                }
-                    })
-                    .collect(List.collector());
-        }
-
         private Type elemtypeRecursive(Type type) {
             Type arr = type;
             while (types.elemtype(arr) != null) {
@@ -594,10 +564,14 @@
                     poolbuf.appendByte(((ParameterizedType)e).typeargs.length);
                     Stream.of(((ParameterizedType)e).typeargs).mapToInt(ta -> ta.index).forEach(poolbuf::appendChar);
                     break;
-                case ClassFile.CONSTANT_CompoundType:
-                    poolbuf.appendChar(((CompoundType)e).template.index);
-                    poolbuf.appendByte(((CompoundType)e).holes.length);
-                    Stream.of(((CompoundType)e).holes).mapToInt(h -> h.index).forEach(poolbuf::appendChar);
+                case ClassFile.CONSTANT_ArrayType:
+                    poolbuf.appendByte(((Pool.ArrayType)e).arrayDepth);
+                    poolbuf.appendChar(((Pool.ArrayType)e).componentType.index);
+                    break;
+                case ClassFile.CONSTANT_MethodDescriptor:
+                    poolbuf.appendByte(((MethodDescriptor)e).args.length);
+                    poolbuf.appendChar(((MethodDescriptor)e).returnType.index);
+                    Stream.of(((MethodDescriptor)e).args).mapToInt(h -> h.index).forEach(poolbuf::appendChar);
                     break;
                 default:
                     Assert.error("Unsupported entry: " + e.tag);
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassTranslator.java	Tue Jan 19 15:23:34 2016 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassTranslator.java	Thu Jan 21 16:30:27 2016 +0000
@@ -27,8 +27,8 @@
 
 import java.util.Map;
 
+import com.sun.tools.classfile.ConstantPool.CONSTANT_ArrayType_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
-import com.sun.tools.classfile.ConstantPool.CONSTANT_CompoundType_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_Double_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_Fieldref_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_Float_info;
@@ -36,6 +36,7 @@
 import com.sun.tools.classfile.ConstantPool.CONSTANT_InterfaceMethodref_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_InvokeDynamic_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_Long_info;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_MethodDescriptor_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_MethodHandle_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_MethodType_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_Methodref_info;
@@ -431,10 +432,20 @@
     }
 
     @Override
-    public CPInfo visitCompoundType(CONSTANT_CompoundType_info info, Map<Object, Object> translations) {
-        CONSTANT_CompoundType_info info2 = (CONSTANT_CompoundType_info) translations.get(info);
+    public CPInfo visitArrayType(CONSTANT_ArrayType_info info, Map<Object, Object> translations) {
+        CONSTANT_ArrayType_info info2 = (CONSTANT_ArrayType_info) translations.get(info);
         if (info2 == null) {
-            info2 = new CONSTANT_CompoundType_info(info.desc_idx, info.params_idxs);
+            info2 = new CONSTANT_ArrayType_info(info.dims, info.componentType_idx);
+            translations.put(info, info2);
+        }
+        return info;
+    }
+
+    @Override
+    public CPInfo visitMethodDescriptor(CONSTANT_MethodDescriptor_info info, Map<Object, Object> translations) {
+        CONSTANT_MethodDescriptor_info info2 = (CONSTANT_MethodDescriptor_info) translations.get(info);
+        if (info2 == null) {
+            info2 = new CONSTANT_MethodDescriptor_info(info.returnType_idx, info.params_idxs);
             translations.put(info, info2);
         }
         return info;
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassWriter.java	Tue Jan 19 15:23:34 2016 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassWriter.java	Thu Jan 21 16:30:27 2016 +0000
@@ -332,8 +332,15 @@
         }
 
         @Override
-        public Integer visitCompoundType(CONSTANT_CompoundType_info info, ClassOutputStream out) {
-            out.writeShort(info.desc_idx);
+        public Integer visitArrayType(CONSTANT_ArrayType_info info, ClassOutputStream out) {
+            out.writeByte(info.dims);
+            out.writeShort(info.componentType_idx);
+            return 1;
+        }
+
+        @Override
+        public Integer visitMethodDescriptor(CONSTANT_MethodDescriptor_info info, ClassOutputStream out) {
+            out.writeShort(info.returnType_idx);
             out.writeByte(info.params_idxs.length);
             IntStream.of(info.params_idxs).forEach(idx -> out.writeShort(idx));
             return 1;
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ConstantPool.java	Tue Jan 19 15:23:34 2016 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ConstantPool.java	Thu Jan 21 16:30:27 2016 +0000
@@ -30,8 +30,10 @@
 import java.io.OutputStream;
 import java.util.Arrays;
 import java.util.Iterator;
+import java.util.stream.Collector;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
+import java.util.stream.Stream;
 
 /**
  * See JVMS, section 4.5.
@@ -122,7 +124,8 @@
     public static final int CONSTANT_InvokeDynamic = 18;
     public static final int CONSTANT_TypeVar = 19;
     public static final int CONSTANT_ParameterizedType = 20;
-    public static final int CONSTANT_CompoundType = 21;
+    public static final int CONSTANT_ArrayType = 21;
+    public static final int CONSTANT_MethodDescriptor = 22;
 
     public static enum RefKind {
         REF_getField(1, "getfield"),
@@ -241,8 +244,12 @@
                 pool[i] = new CONSTANT_ParameterizedType_info(cr);
                 break;
 
-            case CONSTANT_CompoundType:
-                pool[i] = new CONSTANT_CompoundType_info(cr);
+            case CONSTANT_ArrayType:
+                pool[i] = new CONSTANT_ArrayType_info(cr);
+                break;
+
+            case CONSTANT_MethodDescriptor:
+                pool[i] = new CONSTANT_MethodDescriptor_info(cr);
                 break;
 
             default:
@@ -367,7 +374,8 @@
         R visitUtf8(CONSTANT_Utf8_info info, P p);
         R visitTypeVar(CONSTANT_TypeVar_info info, P p);
         R visitParameterizedType(CONSTANT_ParameterizedType_info info, P p);
-        R visitCompoundType(CONSTANT_CompoundType_info info, P p);
+        R visitArrayType(CONSTANT_ArrayType_info info, P p);
+        R visitMethodDescriptor(CONSTANT_MethodDescriptor_info info, P p);
     }
 
     public static abstract class SimpleCPVisitor<R, P> implements Visitor<R, P> {
@@ -452,7 +460,12 @@
         }
 
         @Override
-        public R visitCompoundType(CONSTANT_CompoundType_info info, P p) {
+        public R visitArrayType(CONSTANT_ArrayType_info info, P p) {
+            return visitEntry(info, p);
+        }
+
+        @Override
+        public R visitMethodDescriptor(CONSTANT_MethodDescriptor_info info, P p) {
             return visitEntry(info, p);
         }
 
@@ -1106,42 +1119,76 @@
         public final int[] params_idxs;
     }
 
-    public static class CONSTANT_CompoundType_info extends CPInfo {
-        CONSTANT_CompoundType_info(ClassReader cr) throws IOException {
-            desc_idx = cr.readUnsignedShort();
+    public static class CONSTANT_ArrayType_info extends CPInfo {
+        CONSTANT_ArrayType_info(ClassReader cr) throws IOException {
+            dims = cr.readUnsignedByte();
+            componentType_idx = cr.readUnsignedShort();
+        }
+
+        public CONSTANT_ArrayType_info(int dims, int componentType_idx) {
+            this.dims = dims;
+            this.componentType_idx = componentType_idx;
+        }
+
+        public int getTag() {
+            return CONSTANT_ArrayType;
+        }
+
+        public int byteLength() {
+            return 1 + //tag
+                    1 + //dims
+                    2; //componentType_idx
+        }
+
+        @Override
+        public String toString() {
+            return "CONSTANT_ArrayType_info[dims: " + dims + ", elem = " + componentType_idx + "]";
+        }
+
+        public <R, D> R accept(Visitor<R, D> visitor, D data) {
+            return visitor.visitArrayType(this, data);
+        }
+
+        public final int dims;
+        public final int componentType_idx;
+    }
+
+    public static class CONSTANT_MethodDescriptor_info extends CPInfo {
+        CONSTANT_MethodDescriptor_info(ClassReader cr) throws IOException {
             int nparams = cr.readUnsignedByte();
+            returnType_idx = cr.readUnsignedShort();
             params_idxs = new int[nparams];
             for (int i = 0 ; i < params_idxs.length ; i++) {
                 params_idxs[i] = cr.readUnsignedShort();
             }
         }
 
-        public CONSTANT_CompoundType_info(int desc_idx, int[] params_idxs) {
-            this.desc_idx = desc_idx;
+        public CONSTANT_MethodDescriptor_info(int returnType_idx, int[] params_idxs) {
+            this.returnType_idx = returnType_idx;
             this.params_idxs = params_idxs;
         }
 
         public int getTag() {
-            return CONSTANT_CompoundType;
+            return CONSTANT_MethodDescriptor;
         }
 
         public int byteLength() {
             return 1 + //tag
-                    2 + //clazz_idx
+                    2 + //returnType_idx
                     1 + //params length
                     (params_idxs.length) * 2; //params_idxs
         }
 
         @Override
         public String toString() {
-            return "CONSTANT_ParameterizedType_info[clazz_index: " + desc_idx + ", holes = " + Arrays.toString(params_idxs) + "]";
+            return "CONSTANT_MethodDescriptor_info[returnType_index: " + returnType_idx + ", params = " + Arrays.toString(params_idxs) + "]";
         }
 
         public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitCompoundType(this, data);
+            return visitor.visitMethodDescriptor(this, data);
         }
 
-        public final int desc_idx;
+        public final int returnType_idx;
         public final int[] params_idxs;
     }
 
@@ -1198,14 +1245,29 @@
         }
 
         @Override
-        public String visitCompoundType(CONSTANT_CompoundType_info info, ConstantPool pool) {
+        public String visitArrayType(CONSTANT_ArrayType_info info, ConstantPool pool) {
             try {
-                String desc = pool.getUTF8Value(info.desc_idx);
-                //this must be an array
-                for (int idx : info.params_idxs) {
-                    desc = desc.replaceFirst("#", pool.get(idx).accept(this, pool));
-                }
-                return desc;
+                String elemDesc = pool.get(info.componentType_idx).accept(this, pool);
+                return "[[[[[[[[[[[[[[[[".substring(0, info.dims) + elemDesc;
+            } catch (Throwable ex) {
+                throw new AssertionError(ex.getMessage());
+            }
+        }
+
+        @Override
+        public String visitMethodDescriptor(CONSTANT_MethodDescriptor_info info, ConstantPool pool) {
+            try {
+                String retDesc = pool.get(info.returnType_idx).accept(this, pool);
+                String args = IntStream.of(info.params_idxs)
+                        .mapToObj(idx -> {
+                            try {
+                                return pool.get(idx).accept(this, pool);
+                            } catch (Throwable ex) {
+                                throw new AssertionError(ex.getMessage());
+                            }
+                        })
+                        .collect(Collectors.joining("", "(", ")"));
+                return args + retDesc;
             } catch (Throwable ex) {
                 throw new AssertionError(ex.getMessage());
             }
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Dependencies.java	Tue Jan 19 15:23:34 2016 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Dependencies.java	Thu Jan 21 16:30:27 2016 +0000
@@ -745,7 +745,12 @@
             }
 
             @Override
-            public Void visitCompoundType(CONSTANT_CompoundType_info info, Void aVoid) {
+            public Void visitArrayType(CONSTANT_ArrayType_info info, Void aVoid) {
+                return null;
+            }
+
+            @Override
+            public Void visitMethodDescriptor(CONSTANT_MethodDescriptor_info info, Void aVoid) {
                 return null;
             }
 
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ReferenceFinder.java	Tue Jan 19 15:23:34 2016 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ReferenceFinder.java	Thu Jan 21 16:30:27 2016 +0000
@@ -198,7 +198,12 @@
         }
 
         @Override
-        public Boolean visitCompoundType(CONSTANT_CompoundType_info info, ConstantPool constantPool) {
+        public Boolean visitArrayType(CONSTANT_ArrayType_info info, ConstantPool constantPool) {
+            return false;
+        }
+
+        @Override
+        public Boolean visitMethodDescriptor(CONSTANT_MethodDescriptor_info info, ConstantPool constantPool) {
             return false;
         }
     };
--- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/ConstantWriter.java	Tue Jan 19 15:23:34 2016 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/ConstantWriter.java	Thu Jan 21 16:30:27 2016 +0000
@@ -172,9 +172,18 @@
             }
 
             @Override
-            public Integer visitCompoundType(CONSTANT_CompoundType_info info, Void aVoid) {
-                print(String.format("#%d%s", info.desc_idx,
-                        IntStream.of(info.params_idxs).mapToObj(i -> "#" + i).collect(Collectors.joining(",", "[", "]"))));
+            public Integer visitArrayType(CONSTANT_ArrayType_info info, Void aVoid) {
+                print(String.format("#%d[%d]", info.componentType_idx, info.dims));
+                tab();
+                println("// " + stringValue(info));
+                return 1;
+            }
+
+            @Override
+            public Integer visitMethodDescriptor(CONSTANT_MethodDescriptor_info info, Void aVoid) {
+                print(String.format("%s#%d",
+                        IntStream.of(info.params_idxs).mapToObj(i -> "#" + i).collect(Collectors.joining(",", "(", ")")),
+                        info.returnType_idx));
                 tab();
                 println("// " + stringValue(info));
                 return 1;
@@ -268,8 +277,10 @@
                 return "TypeVar";
             case CONSTANT_ParameterizedType:
                 return "ParameterizedType";
-            case CONSTANT_CompoundType:
-                return "CompoundType";
+            case CONSTANT_ArrayType:
+                return "ArrayType";
+            case CONSTANT_MethodDescriptor:
+                return "MethodDescriptor";
             default:
                 return "(unknown tag " + tag + ")";
         }
@@ -466,12 +477,32 @@
         }
 
         @Override
-        public String visitCompoundType(CONSTANT_CompoundType_info info, Void aVoid) {
-            String desc = stringValue(info.desc_idx);
-            for (int i : info.params_idxs) {
-                desc = desc.replaceFirst("#", stringValue(i));
+        public String visitArrayType(CONSTANT_ArrayType_info info, Void aVoid) {
+            try {
+                String elemDesc = stringValue(info.componentType_idx);
+                return "[[[[[[[[[[[[[[[[".substring(0, info.dims) + elemDesc;
+            } catch (Throwable ex) {
+                throw new AssertionError(ex.getMessage());
             }
-            return desc;
+        }
+
+        @Override
+        public String visitMethodDescriptor(CONSTANT_MethodDescriptor_info info, Void aVoid) {
+            try {
+                String retDesc = stringValue(info.returnType_idx);
+                String args = IntStream.of(info.params_idxs)
+                        .mapToObj(idx -> {
+                            try {
+                                return stringValue(idx);
+                            } catch (Throwable ex) {
+                                throw new AssertionError(ex.getMessage());
+                            }
+                        })
+                        .collect(Collectors.joining(",", "(", ")"));
+                return args + retDesc;
+            } catch (Throwable ex) {
+                throw new AssertionError(ex.getMessage());
+            }
         }
     }
 
--- a/test/tools/javac/lambda/ByteCodeTest.java	Tue Jan 19 15:23:34 2016 +0000
+++ b/test/tools/javac/lambda/ByteCodeTest.java	Thu Jan 21 16:30:27 2016 +0000
@@ -655,7 +655,12 @@
         }
 
         @Override
-        public String visitCompoundType(CONSTANT_CompoundType_info info, Integer integer) {
+        public String visitArrayType(CONSTANT_ArrayType_info info, Integer integer) {
+            throw new UnsupportedOperationException("Cannot get here!");
+        }
+
+        @Override
+        public String visitMethodDescriptor(CONSTANT_MethodDescriptor_info info, Integer integer) {
             throw new UnsupportedOperationException("Cannot get here!");
         }
     }