changeset 3291:6a97b8d3ea09

Enhancement: Update TypeVar_info to match latest draft
author mcimadamore
date Mon, 25 Jan 2016 16:46:13 +0000
parents 7a9f046780db
children 9e83e2551f52
files src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.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.compiler/share/classes/com/sun/tools/javac/sym/CreateSymbols.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/TypeVariablesMap_attribute.java src/jdk.jdeps/share/classes/com/sun/tools/javap/ConstantWriter.java
diffstat 12 files changed, 132 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri Jan 22 17:19:08 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Jan 25 16:46:13 2016 +0000
@@ -2198,7 +2198,7 @@
             printCCF("found.later.version",
                      Integer.toString(minorVersion));
         }
-        poolReader = new PoolReader(this, types);
+        poolReader = new PoolReader(c, this, types);
         bp = poolReader.readPool(buf, bp);
         if (signatureBuffer.length < bp) {
             int ns = Integer.highestOneBit(bp) << 1;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Fri Jan 22 17:19:08 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Mon Jan 25 16:46:13 2016 +0000
@@ -2614,7 +2614,7 @@
             ClassSymbol c = cdef.sym;
             this.toplevel = env.toplevel;
             this.endPosTable = toplevel.endPositions;
-            pool = c.poolWriter = new PoolWriter(types, genericClassFile);
+            pool = c.poolWriter = new PoolWriter(cdef.sym, types, genericClassFile);
             /* method normalizeDefs() can add references to external classes into the constant pool
              */
             cdef.defs = normalizeDefs(cdef.defs, c);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Pool.java	Fri Jan 22 17:19:08 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Pool.java	Mon Jan 25 16:46:13 2016 +0000
@@ -26,6 +26,7 @@
 package com.sun.tools.javac.jvm;
 
 import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.MethodHandleSymbol;
 import com.sun.tools.javac.code.Type;
 import com.sun.tools.javac.code.Type.ClassType;
@@ -397,33 +398,28 @@
      */
     static class TypeVariable extends Entry {
 
-        /** Type-variable name. */
-        Constant<Name> name;
+        /** Type-variable index. */
+        int adr;
 
-        /** Type-variable owner. */
-        Entry owner;
+        /** Type-variable erasure. */
+        Entry erasure;
 
-        /** Type-variable bounds. */
-        Entry[] bounds;
-
-        TypeVariable(Constant<Name> name, Entry owner, Entry[] bounds, TypeVar tv) {
+        TypeVariable(int adr, Entry erasure, TypeVar tv) {
             super(ClassFile.CONSTANT_TypeVar, tv);
-            this.name = name;
-            this.owner = owner;
-            this.bounds = bounds;
+            this.adr = adr;
+            this.erasure = erasure;
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(name, owner, Arrays.hashCode(bounds));
+            return Objects.hash(adr, erasure);
         }
 
         @Override
         public boolean equals(Object obj) {
             if (obj instanceof TypeVariable) {
                 TypeVariable that = (TypeVariable)obj;
-                return that.name.equals(name) && that.owner.equals(owner) &&
-                        Objects.deepEquals(that.bounds, bounds);
+                return that.adr == adr && that.erasure.equals(erasure);
             } else {
                 return false;
             }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolReader.java	Fri Jan 22 17:19:08 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolReader.java	Mon Jan 25 16:46:13 2016 +0000
@@ -78,10 +78,23 @@
     ClassReader reader;
     Types types;
 
-    PoolReader(ClassReader reader, Types types) {
+    ClassSymbol poolClass;
+    Type[] typeVarsByOwner;
+
+    PoolReader(ClassSymbol poolClass, ClassReader reader, Types types) {
         this.pool = new Pool();
         this.reader = reader;
         this.types = types;
+        this.poolClass = poolClass;
+    }
+
+    Type[] typeVars() {
+        if (typeVarsByOwner == null) {
+            typeVarsByOwner = types.typeVarsByOwner(poolClass).stream()
+                    .flatMap(t -> t.elem1.stream())
+                    .toArray(Type[]::new);
+        }
+        return typeVarsByOwner;
     }
 
     /**
@@ -236,17 +249,18 @@
      */
     class UnresolvedTypeVar extends Unresolved<Type> {
 
-        int nbounds;
-
-        UnresolvedTypeVar(int tag, int offset, int nbounds) {
+        UnresolvedTypeVar(int tag, int offset) {
             super(tag, offset);
-            this.nbounds = nbounds;
         }
 
         @Override
         Type doResolve() {
-            //return (erasure of) first bound
-            return getType(reader.buf.getChar(offset + 5));
+            int adr = reader.buf.getByte(offset) & 0xFF;
+            try {
+                return typeVars()[adr];
+            } catch (Throwable ex) {
+                throw ex;
+            }
         }
     }
 
@@ -442,13 +456,12 @@
                     pool.put(new Skip(tag));
                     break;
                 case CONSTANT_TypeVar:
-                    int nbounds = poolbuf.getByte(start + 4) & 0xFF;
-                    offset += 5 + (nbounds * 2);
-                    pool.put(new UnresolvedTypeVar(tag, start, nbounds));
+                    offset += 3;
+                    pool.put(new UnresolvedTypeVar(tag, start));
                     break;
                 case CONSTANT_ParameterizedType:
                     int nargs = poolbuf.getByte(start + 5) & 0xFF;
-                    offset += 5 + (nargs * 2);
+                    offset += 6 + (nargs * 2);
                     pool.put(new UnresolvedParameterizedType(tag, start, nargs));
                     break;
                 case CONSTANT_ArrayType:
@@ -456,7 +469,7 @@
                     pool.put(new UnresolvedArrayType(tag, start));
                     break;
                 case CONSTANT_MethodDescriptor:
-                    int nparams = poolbuf.getByte(start + 2) & 0xFF;
+                    int nparams = poolbuf.getByte(start) & 0xFF;
                     offset += 3 + (nparams * 2);
                     pool.put(new UnresolvedMethodDescriptor(tag, start, nparams));
                     break;
@@ -509,6 +522,8 @@
                         internalize(name.getByteArray(),
                                     name.getByteOffset(),
                                     name.getByteLength())));
+            case CONSTANT_ParameterizedType:
+                return (ClassSymbol)((Type)e.data.get()).tsym;
             default:
                 throw new IllegalStateException("Illegal type entry: " + e.tag);
         }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java	Fri Jan 22 17:19:08 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java	Mon Jan 25 16:46:13 2016 +0000
@@ -59,6 +59,7 @@
 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;
 
@@ -102,10 +103,15 @@
     /** Did this class encoded any of the Valhalla-specific CP-forms? */
     boolean useNewCPForms = false;
 
-    public PoolWriter(Types types, boolean genericClassFile) {
+    Type[] typeVarsByOwner;
+
+    public PoolWriter(ClassSymbol poolClass, Types types, boolean genericClassFile) {
         this.pool = new Pool();
         this.types = types;
         this.genericClassFile = genericClassFile;
+        this.typeVarsByOwner = types.typeVarsByOwner(poolClass).stream()
+                    .flatMap(t -> t.elem1.stream())
+                    .toArray(Type[]::new);
     }
 
     /**
@@ -401,7 +407,7 @@
     /** Generic type factory. Some entries are mapped into new structural forms. */
     TypeFactory genericTypeFactory = new TypeFactory() {
 
-        final String arrayTemplate = "[[[[[[[[[[[[[[[[#";
+        boolean typeArgPosition = false;
 
         @Override
         public Entry visitType(Type t, Function<Type, Name> typeNameFunc) {
@@ -421,12 +427,12 @@
         @SuppressWarnings("unchecked")
         public Entry visitTypeVar(TypeVar tv, Function<Type, Name> typeNameFunc) {
             useNewCPForms = true;
-            Constant<Name> name = (Constant<Name>)makeConstant(tv.tsym.name);
-            Entry owner = makeSymbol(tv.tsym.owner);
-            Entry[] bounds = types.getBounds(tv).stream()
-                    .map(b -> visit(b, typeNameFunc))
-                    .toArray(Entry[]::new);
-            Entry e = new TypeVariable(name, owner, bounds, tv);
+            int adr = 0;
+            for (; adr < typeVarsByOwner.length && typeVarsByOwner[adr].tsym != tv.tsym ; adr++ );
+            Entry erasure = typeArgPosition ?
+                    makeConstant(types.names.fromString("_")) :
+                    visit(types.getBounds(tv).head, typeNameFunc);
+            Entry e = new TypeVariable(adr, erasure, tv);
             return pool.put(e);
         }
 
@@ -451,9 +457,16 @@
                     }
                 }
                 Constant<Name> clazz = (Constant<Name>)makeConstant(t.tsym.flatName());
-                Entry[] typeargs = t.getTypeArguments().stream()
-                        .map(ta -> visit(ta, PoolWriter.this::typeToSig))
-                        .toArray(Entry[]::new);
+                boolean prevTypeArgPosition = typeArgPosition;
+                Entry[] typeargs = null;
+                try {
+                    typeArgPosition = true;
+                    typeargs = t.getTypeArguments().stream()
+                            .map(ta -> visit(ta, PoolWriter.this::typeToSig))
+                            .toArray(Entry[]::new);
+                } finally {
+                    typeArgPosition = prevTypeArgPosition;
+                }
                 char basicType = types.isValue(t) ? 'Q' : 'L';
                 Entry e = new ParameterizedType((ParameterizedType)encl_entry, basicType, clazz, typeargs, t);
                 return pool.put(e);
@@ -565,10 +578,8 @@
                     poolbuf.appendChar(((InvokeDynamic)e).nt.index);
                     break;
                 case ClassFile.CONSTANT_TypeVar:
-                    poolbuf.appendChar(((TypeVariable)e).name.index);
-                    poolbuf.appendChar(((TypeVariable)e).owner.index);
-                    poolbuf.appendByte(((TypeVariable)e).bounds.length);
-                    Stream.of(((TypeVariable)e).bounds).mapToInt(b -> b.index).forEach(poolbuf::appendChar);
+                    poolbuf.appendByte(((TypeVariable)e).adr);
+                    poolbuf.appendChar(((TypeVariable)e).erasure.index);
                     break;
                 case ClassFile.CONSTANT_ParameterizedType:
                     ParameterizedType encl = ((ParameterizedType)e).enclosing;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/sym/CreateSymbols.java	Fri Jan 22 17:19:08 2016 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/sym/CreateSymbols.java	Mon Jan 25 16:46:13 2016 +0000
@@ -203,7 +203,6 @@
 
         Type.moreInfo = true;
         Types types = Types.instance(task.getContext());
-        PoolWriter poolWriter = new PoolWriter(types, false);
         for (JavaFileObject file : fm.list(jarLocation, "", EnumSet.of(CLASS), true)) {
             String className = fm.inferBinaryName(jarLocation, file);
             int index = className.lastIndexOf('.');
@@ -241,6 +240,7 @@
             int p = profiles.getProfile(cs.fullname.toString().replace(".", "/"));
             if (0 < p && p < profileAnnos.length)
                 cs.prependAttributes(List.of(profileAnnos[p]));
+            PoolWriter poolWriter = new PoolWriter(cs, types, false);
             writeClass(poolWriter, cs, writer);
         }
 
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassTranslator.java	Fri Jan 22 17:19:08 2016 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassTranslator.java	Mon Jan 25 16:46:13 2016 +0000
@@ -415,7 +415,7 @@
     public CPInfo visitTypeVar(CONSTANT_TypeVar_info info, Map<Object, Object> translations) {
         CONSTANT_TypeVar_info info2 = (CONSTANT_TypeVar_info) translations.get(info);
         if (info2 == null) {
-            info2 = new CONSTANT_TypeVar_info(info.name_idx, info.owner_idx, info.bounds_idxs);
+            info2 = new CONSTANT_TypeVar_info(info.adr, info.erasure_idx);
             translations.put(info, info2);
         }
         return info;
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassWriter.java	Fri Jan 22 17:19:08 2016 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassWriter.java	Mon Jan 25 16:46:13 2016 +0000
@@ -316,10 +316,8 @@
 
         @Override
         public Integer visitTypeVar(CONSTANT_TypeVar_info info, ClassOutputStream out) {
-            out.writeShort(info.name_idx);
-            out.writeShort(info.owner_idx);
-            out.writeByte(info.bounds_idxs.length);
-            IntStream.of(info.bounds_idxs).forEach(idx -> out.writeShort(idx));
+            out.writeByte(info.adr);
+            out.writeShort(info.erasure_idx);
             return 1;
         }
 
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ConstantPool.java	Fri Jan 22 17:19:08 2016 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ConstantPool.java	Mon Jan 25 16:46:13 2016 +0000
@@ -30,6 +30,7 @@
 import java.io.OutputStream;
 import java.util.Arrays;
 import java.util.Iterator;
+import java.util.Optional;
 import java.util.stream.Collector;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
@@ -1037,20 +1038,18 @@
     }
 
     public static class CONSTANT_TypeVar_info extends CPInfo {
+
+        Optional<ClassFile> classFileOpt;
+
         CONSTANT_TypeVar_info(ClassReader cr) throws IOException {
-            name_idx = cr.readUnsignedShort();
-            owner_idx = cr.readUnsignedShort();
-            int nbounds = cr.readUnsignedByte();
-            bounds_idxs = new int[nbounds];
-            for (int i = 0 ; i < bounds_idxs.length ; i++) {
-                bounds_idxs[i] = cr.readUnsignedShort();
-            }
+            adr = cr.readUnsignedByte();
+            erasure_idx = cr.readUnsignedShort();
+            classFileOpt = Optional.of(cr.getClassFile());
         }
 
-        public CONSTANT_TypeVar_info(int name_idx, int owner_idx, int[] bounds_idxs) {
-            this.name_idx = name_idx;
-            this.owner_idx = owner_idx;
-            this.bounds_idxs = bounds_idxs;
+        public CONSTANT_TypeVar_info(int adr, int erasure_idx) {
+            this.adr = adr;
+            this.erasure_idx = erasure_idx;
         }
 
         public int getTag() {
@@ -1059,24 +1058,37 @@
 
         public int byteLength() {
             return 1 + //tag
-                    2 + //name_idx
-                    2 + //owner_idx
-                    1 + //bounds length
-                    (bounds_idxs.length) * 2; //bounds_idxs
+                    1 + //adr
+                    2; //erasure_idx
         }
 
         @Override
         public String toString() {
-            return "CONSTANT_TypeVar_info[name_index: " + name_idx + ", owner_index: " + owner_idx + ", bounds = " + Arrays.toString(bounds_idxs) + "]";
+            return "CONSTANT_TypeVar_info[adr: " + adr + ", erasure_index: " + erasure_idx + "]";
         }
 
         public <R, D> R accept(Visitor<R, D> visitor, D data) {
             return visitor.visitTypeVar(this, data);
         }
 
-        public final int name_idx;
-        public final int owner_idx;
-        public final int[] bounds_idxs;
+        TypeVariablesMap_attribute typeVarMap() {
+            return (TypeVariablesMap_attribute)classFileOpt.get().getAttribute(Attribute.TypeVariablesMap);
+        }
+
+        public int getNameIndex() {
+            return typeVarMap().flatten()[adr].name_idx;
+        }
+
+        public int getBoundIndex() {
+            return typeVarMap().flatten()[adr].bound_idx;
+        }
+
+        public int getOwnerIndex() {
+            return typeVarMap().flatten()[adr].owner_idx;
+        }
+
+        public final int adr;
+        public final int erasure_idx;
     }
 
     //Todo: add enclosing type
@@ -1220,7 +1232,7 @@
         @Override
         public String visitTypeVar(CONSTANT_TypeVar_info info, ConstantPool pool) {
             try {
-                return pool.getUTF8Value(info.name_idx);
+                return pool.getUTF8Value(info.getNameIndex());
             } catch (Throwable ex) {
                 throw new AssertionError(ex.getMessage());
             }
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Dependencies.java	Fri Jan 22 17:19:08 2016 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Dependencies.java	Mon Jan 25 16:46:13 2016 +0000
@@ -727,7 +727,7 @@
             @Override
             public Void visitTypeVar(CONSTANT_TypeVar_info info, Void aVoid) {
                 try {
-                    visitClass((CONSTANT_Class_info)constant_pool.get(info.owner_idx), null);
+                    visitClass((CONSTANT_Class_info)constant_pool.get(info.getOwnerIndex()), null);
                     return null;
                 } catch (ConstantPoolException e) {
                     throw new ClassFileError(e);
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/TypeVariablesMap_attribute.java	Fri Jan 22 17:19:08 2016 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/TypeVariablesMap_attribute.java	Mon Jan 25 16:46:13 2016 +0000
@@ -27,6 +27,7 @@
 
 import java.io.IOException;
 import java.util.EnumSet;
+import java.util.stream.Stream;
 
 /**
  *  <p><b>This is NOT part of any supported API.
@@ -47,9 +48,28 @@
         return visitor.visitTypeVariablesMap(this, data);
     }
 
+    FlatEntry[] flatten() {
+        return Stream.of(type_variables_map_table)
+                .flatMap(e -> Stream.of(e.mappings)
+                .map(m -> new FlatEntry(e.owner_idx, m.tvar_name_index, m.bound_index)))
+                .toArray(FlatEntry[]::new);
+    }
+
     public final int type_variables_map_length;
     public final Entry[] type_variables_map_table;
 
+    public static class FlatEntry {
+        public final int owner_idx;
+        public final int name_idx;
+        public final int bound_idx;
+
+        FlatEntry(int owner_idx, int name_idx, int bound_idx) {
+            this.owner_idx = owner_idx;
+            this.name_idx = name_idx;
+            this.bound_idx = bound_idx;
+        }
+    }
+
     public static class Entry {
         public final int owner_idx;
         public final Mapping[] mappings;
--- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/ConstantWriter.java	Fri Jan 22 17:19:08 2016 +0000
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/ConstantWriter.java	Mon Jan 25 16:46:13 2016 +0000
@@ -155,8 +155,7 @@
 
             @Override
             public Integer visitTypeVar(CONSTANT_TypeVar_info info, Void aVoid) {
-                print(String.format("#%d::%d %s", info.owner_idx, info.name_idx,
-                        IntStream.of(info.bounds_idxs).mapToObj(i -> "#" + i).collect(Collectors.joining(",", "{", "}"))));
+                print(String.format("%d/#%d", info.adr, info.erasure_idx));
                 tab();
                 println("// " + stringValue(info));
                 return 1;
@@ -164,7 +163,10 @@
 
             @Override
             public Integer visitParameterizedType(CONSTANT_ParameterizedType_info info, Void aVoid) {
-                print(String.format("#%d%s", info.clazz_idx,
+                String encl = info.encl_idx != 0 ?
+                        "#" + String.valueOf(info.encl_idx) + "." :
+                        "";
+                print(String.format("%s#%d%s", encl, info.clazz_idx,
                         IntStream.of(info.params_idxs).mapToObj(i -> "#" + i).collect(Collectors.joining(",", "<", ">"))));
                 tab();
                 println("// " + stringValue(info));
@@ -459,24 +461,21 @@
 
         @Override
         public String visitTypeVar(CONSTANT_TypeVar_info info, Void aVoid) {
-            String owner = stringValue(info.owner_idx);
-            String name = stringValue(info.name_idx);
-            String bounds = IntStream.of(info.bounds_idxs)
-                    .mapToObj(i -> stringValue(i))
-                    .collect(Collectors.joining(","));
-            return String.format("%s::%s extends %s", owner, name, bounds);
+            String name = stringValue(info.getNameIndex());
+            String erasure = stringValue(info.erasure_idx);
+            return String.format("%s/%s", name, erasure);
         }
 
         @Override
         public String visitParameterizedType(CONSTANT_ParameterizedType_info info, Void aVoid) {
             String encl = info.encl_idx != 0 ?
-                    stringValue(info.encl_idx) :
+                    stringValue(info.encl_idx) + "." :
                     "";
             String clazz = stringValue(info.clazz_idx);
             String targs = IntStream.of(info.params_idxs)
                     .mapToObj(i -> stringValue(i))
                     .collect(Collectors.joining(",", "<", ">"));
-            return String.format("[%s]%c%s%s", encl, info.basicType, clazz, targs);
+            return String.format("%s%c%s%s", encl, info.basicType, clazz, targs);
         }
 
         @Override