changeset 3279:71e8f37f46ae

Enhancement: simplify Items hierarchy
author mcimadamore
date Fri, 18 Dec 2015 18:24:00 +0000
parents 3f01e9c496fe
children 2bb582ce72c4
files src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java src/jdk.compiler/share/classes/com/sun/tools/javac/util/ByteBuffer.java test/tools/javac/valhalla/typespec/items/tests/TestRespecialization.java
diffstat 7 files changed, 187 insertions(+), 235 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Thu Dec 17 16:28:01 2015 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Fri Dec 18 18:24:00 2015 +0000
@@ -5197,6 +5197,13 @@
         }
 
         @Override
+        public Type visitCapturedType(CapturedType t, Type target) {
+            Type erased = erasure(target);
+            return skipTypeVars(t.bound, true) == syms.anyType ?
+                    t : asSuper(t, erased.tsym);
+        }
+
+        @Override
         public Type visitTypeVar(TypeVar t, Type target) {
             Type erased = erasure(target);
             return isSpecializableTypeVar(t) ? t : asSuper(t, erased.tsym);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Thu Dec 17 16:28:01 2015 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Fri Dec 18 18:24:00 2015 +0000
@@ -1987,10 +1987,12 @@
         VarSymbol lhs = outerThisStack.tail.head;
         Assert.check(rhs.owner.owner == lhs.owner);
         make.at(pos);
+        JCExpression thiz = make.This(lhs.owner.erasure(types));
+        thiz.unerasedType = lhs.owner.type;
         return
             make.Exec(
                 make.Assign(
-                    make.Select(make.This(lhs.owner.erasure(types)), lhs),
+                    make.Select(thiz, lhs),
                     make.Ident(rhs)).setType(lhs.erasure(types)));
     }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java	Thu Dec 17 16:28:01 2015 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java	Fri Dec 18 18:24:00 2015 +0000
@@ -294,6 +294,9 @@
                 ? make.This(origin.erasure(types))
                 : make.Super(types.supertype(origin.type).tsym.erasure(types), origin);
 
+            receiver.unerasedType = (impl.owner == origin) ?
+                    origin.type : types.supertype(origin.type);
+
             // The type returned from the original method.
             Type calltype = erasure(impl.type.getReturnType());
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Thu Dec 17 16:28:01 2015 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Fri Dec 18 18:24:00 2015 +0000
@@ -307,56 +307,65 @@
                 case MTH:
                     Type mt1 = asExternalType(instType(types), types);
                     Type mt2 = asExternalType(other.type, types);
-                    return types.decorateDescriptor(mt1, mt2).asMethodType();
+                    return dropTypeParameters(types.decorateDescriptor(mt1, mt2), types);
                 case VAR:
                     return types.decorateDescriptor(types.memberType(types.capture(site), other), other.type);
                 default:
                     throw new AssertionError("Cant get here!");
             }
         }
+        //where
+            private Type dropTypeParameters(Type descType, Types types) {
+                if (descType.hasTag(TypeTag.FORALL)) {
+                    ForAll fa = (ForAll)descType;
+                    List<Type> tvars = fa.tvars;
+                    descType = types.subst(descType.asMethodType(), tvars, types.erasure(tvars));
+                }
+                return descType;
+            }
 
-        /**
-         * Return the instantiated view of this descriptor.
-         */
-        private Type instType(Types types) {
-            if (!other.isStatic()) {
-                return types.memberType(types.capture(site), other);
-            } else if (other.name.toString().startsWith("access$")) {
-                //patch up accessor symbol
-                List<Type> from = other.enclClass().type.allparams();
-                List<Type> to = site.allparams();
-                return types.subst(other.type, from, to);
-            } else {
-                return other.type;
+            /**
+             * Return the instantiated view of this descriptor.
+             */
+            private Type instType(Types types) {
+                if (!other.isStatic()) {
+                    return types.memberType(types.capture(site), other);
+                } else if (other.name.toString().startsWith("access$")) {
+                    //patch up accessor symbol
+                    List<Type> from = other.enclClass().type.allparams();
+                    List<Type> to = types.capture(site).allparams();
+                    return types.subst(other.type, from, to);
+                } else {
+                    return other.type;
+                }
             }
-        }
 
-        /**
-         * Return external type associated with given method (this is similar to {@link Symbol#externalType(Types)}
-         * but it takes generic info into account).
-         */
-        private Type asExternalType(Type t, Types types) {
-            List<Type> params = t.getParameterTypes();
-            boolean addedParams = false;
-            if (name == name.table.names.init && other.owner.hasOuterInstance()) {
-                //add outer instance param
-                params = params.prepend(site.getEnclosingType());
-                addedParams = true;
-            } else if (name == name.table.names.init &&
-                    (other.owner.flags_field & ENUM) != 0 &&
-                    (other.flags() & SYNTHETIC) == 0) { //do not touch access constructor
-                params = params.prependList(other.externalType(types).getParameterTypes().take(2));
-                addedParams = true;
+            /**
+             * Return external type associated with given method (this is similar to {@link Symbol#externalType(Types)}
+             * but it takes generic info into account).
+             */
+            private Type asExternalType(Type t, Types types) {
+                List<Type> params = t.getParameterTypes();
+                boolean addedParams = false;
+                if (name == name.table.names.init && other.owner.hasOuterInstance()) {
+                    //add outer instance param
+                    params = params.prepend(site.getEnclosingType());
+                    addedParams = true;
+                } else if (name == name.table.names.init &&
+                        (other.owner.flags_field & ENUM) != 0 &&
+                        (other.flags() & SYNTHETIC) == 0) { //do not touch access constructor
+                    params = params.prependList(other.externalType(types).getParameterTypes().take(2));
+                    addedParams = true;
+                }
+                for (Symbol p : ((MethodSymbol)other).capturedLocals) {
+                    //add proxy var
+                    params = params.append(p.type);
+                    addedParams = true;
+                }
+                return addedParams ?
+                        types.createMethodTypeWithParameters(t, params) :
+                        t;
             }
-            for (Symbol p : ((MethodSymbol)other).capturedLocals) {
-                //add proxy var
-                params = params.append(p.type);
-                addedParams = true;
-            }
-            return addedParams ?
-                    types.createMethodTypeWithParameters(t, params) :
-                    t;
-        }
 
         /**
          * Factory method for creating descriptors.
@@ -367,8 +376,8 @@
                 // leave alone methods inherited from Object
                 // JLS 13.1.
                 descSite = sym.enclClass().type;
-            } else if (site.hasTag(ARRAY) ||
-                    (types.isSpecialized(site) && (!sym.isStatic() || (sym.flags() & SPECIALIZABLE) != 0))) {
+            } else if (needsInstantiatedSite(site, types) &&
+                    (!sym.isStatic() || (sym.flags() & SPECIALIZABLE) != 0)) {
                 //keep specialized info
                 descSite = site;
             } else if ((sym.flags() & (STATIC | SYNTHETIC)) == (STATIC | SYNTHETIC)) {
@@ -385,6 +394,19 @@
             }
             return new Descriptor(sym, descSite);
         }
+        //where
+            private static boolean needsInstantiatedSite(Type site, Types types) {
+                switch (site.getTag()) {
+                    case ARRAY:
+                        return true;
+                    case CLASS:
+                        return !site.isCompound();
+                    case TYPEVAR:
+                        return types.containsSpecializableTvars(site);
+                    default:
+                        return false;
+                }
+            }
 
         @Override
         public <R, P> R accept(Visitor<R, P> v, P p) {
@@ -463,7 +485,7 @@
         Symbol msym = rs.
             resolveInternalMethod(pos, attrEnv, site, name, argtypes, null);
         if (isStatic) items.makeStaticMethodItem(msym).invoke();
-        else items.makeInternalMethodItem(msym, name == names.init).invoke();
+        else items.makeMethodItem(msym, name == names.init).invoke();
     }
 
     /** Is the given method definition an access method
@@ -1943,26 +1965,17 @@
         // the parameters of the method's external type (that is, any implicit
         // outer instance of a super(...) call appears as first parameter).
         Symbol msym = m.member();
-        if (msym.name.toString().startsWith("access$") &&
-                m.isAny() && !msym.baseSymbol().isStatic() &&
-                tree.args.head.unerasedType != null) {
-            //patch up any item
-            AnyMemberItem anyItem = (AnyMemberItem)m;
-            List<Type> from = anyItem.ownerType.allparams();
-            List<Type> to = tree.args.head.unerasedType.allparams();
-            m = items.new AnyMemberItem((SymbolicItem)anyItem.delegatedItem,
-                    types.subst(anyItem.originalType, from, to),
-                    types.subst(anyItem.ownerType, from, to),
-                    types.subst(anyItem.memberType, from, to));
-        }
-
         List<Type> params = msym.externalType(types).getParameterTypes();
 
         genArgs(tree.args, params);
         if (!isDynamic(msym)) {
             code.statBegin(tree.pos);
         }
-        result = m.invoke();
+        try {
+            result = m.invoke();
+        } catch (Throwable t) {
+            throw new AssertionError("tree = " + tree);
+        }
     }
     //where
         boolean isDynamic(Symbol s) {
@@ -2065,7 +2078,7 @@
             Symbol s = Descriptor.of(tree.constructor, newType, types);
 
             genArgs(tree.args, s.externalType(types).getParameterTypes());
-            items.makeMethodItem(items.makeStackItem(newType), s, true).invoke();
+            items.makeMethodItem(s, true).invoke();
         }
         result = items.makeStackItem(newType);
     }
@@ -2338,7 +2351,7 @@
             if (!t.isPrimitive() && t.tsym != syms.stringType.tsym) {
                 t = syms.objectType;
             }
-            items.makeInternalMethodItem(getStringBufferAppend(tree, t), false).invoke();
+            items.makeMethodItem(getStringBufferAppend(tree, t), false).invoke();
         }
         Symbol getStringBufferAppend(JCTree tree, Type t) {
             Assert.checkNull(t.constValue());
@@ -2481,7 +2494,8 @@
             if (sym.kind == MTH) {
                 // Generate code to address the constructor.
                 sym = Descriptor.of(sym, res.originalType(), types);
-                res = items.makeMethodItem(res.load(), sym, true);
+                res.load();
+                res = items.makeMethodItem(sym, true);
             }
             result = res;
         } else if (sym.kind == VAR && sym.owner.kind == MTH) {
@@ -2496,9 +2510,9 @@
                     items.makeStaticFieldItem(sym);
         } else {
             Item rcv = items.makeThisItem(env.enclClass.sym.type).load();
-            sym = Descriptor.of(sym, env.enclClass.type, types);
+            sym = Descriptor.of(sym, env.enclClass.sym.type, types);
             result = sym.kind == MTH ?
-                    items.makeMethodItem(rcv, sym, (sym.flags() & PRIVATE) != 0) :
+                    items.makeMethodItem(sym, (sym.flags() & PRIVATE) != 0) :
                     items.makeFieldItem(rcv, sym);
         }
     }
@@ -2565,7 +2579,7 @@
                     result = items.makeStackItem(syms.intType);
                 } else {
                     result = sym.kind == MTH ?
-                            items.makeMethodItem(rcv, sym,
+                            items.makeMethodItem(sym,
                                        (sym.flags() & PRIVATE) != 0 ||
                                        selectSuper || accessSuper) :
                             items.makeFieldItem(rcv, sym);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java	Thu Dec 17 16:28:01 2015 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java	Fri Dec 18 18:24:00 2015 +0000
@@ -29,20 +29,16 @@
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol.BootstrapArgument;
 import com.sun.tools.javac.code.Type.*;
-import com.sun.tools.javac.code.Types.DescriptorAugmentor;
 import com.sun.tools.javac.jvm.Code.*;
 import com.sun.tools.javac.jvm.Gen.Descriptor;
 import com.sun.tools.javac.jvm.Gen.PoolMode;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.util.Assert;
-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.Names;
 
 import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Set;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
@@ -136,9 +132,7 @@
      */
     Item makeDynamicItem(Symbol member) {
         DynamicItem dynItem = new DynamicItem(member);
-        return (isAnyIndy((DynamicMethodSymbol)member)) ?
-            new AnyDynamicItem(dynItem, member.type) :
-            dynItem;
+        return wrapIfNeeded(dynItem, ((DynamicMethodSymbol)member), this::isAnyIndy, ds -> ds.type.getReturnType());
     }
     //where
         private boolean isAnyIndy(DynamicMethodSymbol dynSym) {
@@ -171,14 +165,16 @@
      *  @param member       The represented symbol.
      */
     Item makeStaticMethodItem(Symbol member) {
-        return wrapStaticIfNeeded(new StaticMethodItem(member), t -> t.getReturnType());
+        Item i = new StaticMethodItem(member);
+        return wrapIfNeeded(i, i, Item::isAny, Item::originalType);
     }
 
     /** Make an item representing an static variable.
      *  @param member       The represented symbol.
      */
     Item makeStaticFieldItem(Symbol member) {
-        return wrapStaticIfNeeded(new StaticFieldItem(member), t -> t);
+        Item i = new StaticFieldItem(member);
+        return wrapIfNeeded(i, i, Item::isAny, Item::originalType);
     }
 
     /** Make an item representing an internal method call.
@@ -186,20 +182,9 @@
      *  @param nonvirtual   Is the reference not virtual? (true for constructors
      *                      and private members).
      */
-    Item makeInternalMethodItem(Symbol member, boolean nonvirtual) {
-        return new MethodItem(member, nonvirtual);
-    }
-
-    /** Make an item representing a method.
-     *  @param rcvItem      The receiver item
-     *  @param member       The represented symbol.
-     *  @param nonvirtual   Is the reference not virtual? (true for constructors
-     *                      and private members).
-     */
-    Item makeMethodItem(Item rcvItem, Symbol member, boolean nonvirtual) {
-        return wrapMemberIfNeeded(rcvItem,
-                (MemberItem)makeInternalMethodItem(member, nonvirtual),
-                Type::getReturnType);
+    Item makeMethodItem(Symbol member, boolean nonvirtual) {
+        Item i = new MethodItem(member, nonvirtual);
+        return wrapIfNeeded(i, i, Item::isAny, Item::originalType);
     }
 
     /** Make an item representing an instance variable.
@@ -207,9 +192,8 @@
      *  @param member       The represented symbol.
      */
     Item makeFieldItem(Item rcvItem, Symbol member) {
-        return wrapMemberIfNeeded(rcvItem,
-                new FieldItem(member),
-                t -> t);
+        Item i = new FieldItem(member);
+        return wrapIfNeeded(i, i, Item::isAny, Item::originalType);
     }
 
     /** Make an item representing a literal.
@@ -292,56 +276,6 @@
         }
     }
 
-    /** Wrap a member item within an 'any' member item based on the kind of the receiver item.
-     */
-    private Item wrapMemberIfNeeded(Item rcvItem, MemberItem memberItem, Function<Type, Type> typeFunc) {
-        Symbol member = memberItem.member;
-        Item result = memberItem;
-        if (rcvItem.isAny()) {
-            Type rcvType = rcvItem.originalType();
-            if (member instanceof Descriptor && !types.isSpecializableTypeVar(rcvType)) {
-                //cloned/specialized types must be rolled back - but not Object members!
-                member = member.baseSymbol();
-            }
-            if (rcvType.hasTag(TypeTag.ARRAY)) {
-                //member access on arrays never requires specialization!
-                return memberItem;
-            }
-            Type memberOwner = rcvType;
-            Type memberType = types.memberType(memberOwner, member);
-            Type descType = types.decorateDescriptor(memberType, member.type);
-            if (descType.hasTag(TypeTag.FORALL)) {
-                ForAll fa = (ForAll)descType;
-                List<Type> tvars = fa.tvars;
-                descType = types.subst(descType.asMethodType(), tvars, types.erasure(tvars));
-            }
-            if (member.enclClass().isInner() && member.isConstructor()) {
-                //add synthetic enclosing parameter
-                descType = types.createMethodTypeWithParameters(descType,
-                        descType.getParameterTypes().prepend(memberOwner.getEnclosingType()));
-            }
-            result = new AnyMemberItem(memberItem, typeFunc.apply(descType),
-                    memberOwner, descType);
-        }
-        return result;
-    }
-
-    private Item wrapStaticIfNeeded(StaticItem staticItem, Function<Type, Type> typeFunc) {
-        Symbol staticSym = staticItem.member;
-        if ((staticItem.member.flags() & Flags.SPECIALIZABLE) != 0 &&
-                (types.containsSpecializableTvars(staticSym.type) ||
-                types.containsSpecializableTvars(staticSym.owner.type))) {
-            Type ty = staticSym.type;
-            if (ty.hasTag(TypeTag.FORALL)) {
-                ForAll fa = (ForAll)ty;
-                ty = types.subst(ty.asMethodType(), fa.tvars, types.erasure(fa.tvars));
-            }
-            return new AnyMemberItem(staticItem, typeFunc.apply(ty), staticSym.owner.type, ty);
-        } else {
-            return staticItem;
-        }
-    }
-
     /** The base class of all items, which implements default behavior.
      */
     abstract class Item {
@@ -638,6 +572,56 @@
                         }
                     }
                     break;
+                case TYPE_3:
+                    SymbolicItem symbolicItem = (SymbolicItem)delegatedItem;
+                    if (!poolModes.contains(PoolMode.TYPE3)) {
+                        if (types.needsMangling(symbolicItem.ownerType())) {
+                            code.markAny(pc, names.fromString(String.join("::",
+                                    types.bytecodeMappingSig(symbolicItem.ownerType()),
+                                    types.bytecodeMappingSig(symbolicItem.member.externalType(types)))));
+                        }
+                    }
+                    break;
+                case TYPE_4:
+                    DynamicMethodSymbol dynSym = (DynamicMethodSymbol)((DynamicItem)delegatedItem).member;
+                    if (!poolModes.contains(PoolMode.TYPE4)) {
+                        Type indyType = dynSym.type;
+                        ListBuffer<String> buf = new ListBuffer<>();
+                        outer:
+                        for (int i = 0; i < dynSym.staticArgs.length; i++) {
+                            BootstrapArgument<?> staticArg = dynSym.staticArgs[i];
+                            if ((staticArg.flags & BootstrapArgument.SPECIALIZABLE) != 0 && isAnyBoostrapArg(staticArg)) {
+                                final String argSig;
+                                switch (staticArg.kind) {
+                                    case METHOD_TYPE:
+                                        argSig = types.bytecodeMappingSig(staticArg.asType().get().baseType()).toString();
+                                        break;
+                                    case CLASS:
+                                        argSig = types.bytecodeMappingSig(staticArg.asType().get()).toString();
+                                        break;
+                                    case METHOD_HANDLE:
+                                        Symbol refSym = staticArg.asSymbol().get();
+                                        //Todo: this code doesn't throw away the ForAll
+                                        argSig = names.fromString(String.join("::",
+                                                types.bytecodeMappingSig(refSym.owner.type),
+                                                types.bytecodeMappingSig(refSym.type))).toString();
+                                        break;
+                                    case STRING:
+                                        argSig = (String)staticArg.data;
+                                        break;
+                                    default:
+                                        //other arguments are not supported
+                                        continue outer;
+                                }
+                                buf.add(String.format("%d=%s", i, argSig));
+                            }
+                        }
+                        Name dynDesc = types.bytecodeMappingSig(indyType);
+                        code.markAny(pc, buf.isEmpty() ?
+                                dynDesc :
+                                dynDesc.append(names.fromString(buf.stream().collect(Collectors.joining("&", "::{", "}")))));
+                    }
+                    break;
                 default:
                     Assert.error("Cannot get here!");
             }
@@ -706,97 +690,6 @@
         }
     }
 
-    /**
-     * Item representing an 'any' type-variable related member item. This class keeps track of
-     * additional type information such as (i) instantated member owner type and (ii) instantiated
-     * member type, which are useful for generating the {@code BytecodeMapping} attribute.
-     */
-    class AnyMemberItem extends AnyItem {
-
-        Type ownerType;
-        Type memberType;
-
-        AnyMemberItem(SymbolicItem delegatedItem, Type originalType, Type ownerType, Type memberType) {
-            super(delegatedItem, originalType);
-            this.ownerType = ownerType;
-            this.memberType = memberType;
-        }
-
-        @Override
-        protected void decorateOpcode(int opcode, int pc) {
-            OpcodeKind kind = OpcodeKind.of(opcode);
-            switch (kind) {
-                case TYPE_3:
-                    if (!poolModes.contains(PoolMode.TYPE3)) {
-                        if (types.needsMangling(ownerType)) {
-                            code.markAny(pc, names.fromString(String.join("::",
-                                    types.bytecodeMappingSig(ownerType),
-                                    types.bytecodeMappingSig(memberType))));
-                        }
-                    }
-                    break;
-                default:
-                    super.decorateOpcode(opcode, pc);
-            }
-        }
-    }
-
-    /**
-     * Item representing an 'any' type-variable related dynamic item. This class keeps track of
-     * a synthetic member item that is associated with the underlying generic method call; unlike
-     * standard member items, there's no receiver item here - the receiver type has to be inferred
-     * from the invoked signature.
-     */
-    class AnyDynamicItem extends AnyItem {
-
-        Type indyType;
-
-        AnyDynamicItem(DynamicItem delegatedItem, Type indyType) {
-            super(delegatedItem, indyType.getReturnType());
-            this.indyType = indyType;
-        }
-
-        @Override
-        protected void decorateOpcode(int opcode, int pc) {
-            if (opcode == invokedynamic) {
-                DynamicMethodSymbol dynSym = (DynamicMethodSymbol)((DynamicItem)delegatedItem).member;
-                ListBuffer<String> buf = new ListBuffer<>();
-                outer: for (int i = 0; i < dynSym.staticArgs.length; i++) {
-                    BootstrapArgument<?> staticArg = dynSym.staticArgs[i];
-                    if ((staticArg.flags & BootstrapArgument.SPECIALIZABLE) != 0 && isAnyBoostrapArg(staticArg)) {
-                        final String argSig;
-                        switch (staticArg.kind) {
-                            case METHOD_TYPE:
-                                argSig = types.bytecodeMappingSig(staticArg.asType().get().baseType()).toString();
-                                break;
-                            case CLASS:
-                                argSig = types.bytecodeMappingSig(staticArg.asType().get()).toString();
-                                break;
-                            case METHOD_HANDLE:
-                                Symbol refSym = staticArg.asSymbol().get();
-                                //Todo: this code doesn't throw away the ForAll
-                                argSig = names.fromString(String.join("::",
-                                        types.bytecodeMappingSig(refSym.owner.type),
-                                        types.bytecodeMappingSig(refSym.type))).toString();
-                                break;
-                            case STRING:
-                                argSig = (String)staticArg.data;
-                                break;
-                            default:
-                                //other arguments are not supported
-                                continue outer;
-                        }
-                        buf.add(String.format("%d=%s", i, argSig));
-                    }
-                }
-                Name dynDesc = types.bytecodeMappingSig(indyType);
-                code.markAny(pc, buf.isEmpty() ?
-                        dynDesc :
-                        dynDesc.append(names.fromString(buf.stream().collect(Collectors.joining("&", "::{", "}")))));
-            }
-        }
-    }
-
     /** An item representing a value on stack.
      */
     class StackItem extends Item {
@@ -995,6 +888,11 @@
             super(member);
         }
 
+        @Override
+        Type originalType() {
+            return member.externalType(types);
+        }
+
         Item load() {
             code.emitop2(getstatic, pool.putSymbol(member));
             return stackItem[typecode];
@@ -1011,6 +909,11 @@
             super(member);
         }
 
+        @Override
+        Type originalType() {
+            return member.externalType(types).getReturnType();
+        }
+
         Item invoke() {
             MethodType mtype = (MethodType)member.erasure(types);
             int rescode = Code.typecode(mtype.restype);
@@ -1067,9 +970,21 @@
         }
 
         @Override
+        boolean isAny() {
+            return types.containsSpecializableTvars(ownerType()) &&
+                    (!member.isStatic() || (member.flags() & Flags.SPECIALIZABLE) != 0);
+        }
+
+        @Override
         Symbol member() {
             return member;
         }
+
+        private Type ownerType() {
+            return (member instanceof Descriptor) ?
+                    ((Descriptor)member).site :
+                    member.enclClass().type;
+        }
     }
 
     /** An item representing an instance variable or method.
@@ -1112,6 +1027,11 @@
             return stackItem[typecode];
         }
 
+        @Override
+        Type originalType() {
+            return member.externalType(types);
+        }
+
         void store() {
             code.emitop2(putfield, pool.putSymbol(member));
         }
@@ -1130,12 +1050,17 @@
 
         boolean isInvokeInterface() {
             if (member instanceof Descriptor) {
-                return ((Descriptor)member).site.isInterface();
+                return types.erasure(((Descriptor)member).site).isInterface();
             } else {
                 return member.owner.isInterface();
             }
         }
 
+        @Override
+        Type originalType() {
+            return member.externalType(types).getReturnType();
+        }
+
         Item invoke() {
             MethodType mtype = (MethodType)member.externalType(types);
             int rescode = Code.typecode(mtype.restype);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/ByteBuffer.java	Thu Dec 17 16:28:01 2015 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/ByteBuffer.java	Fri Dec 18 18:24:00 2015 +0000
@@ -146,8 +146,9 @@
     public void appendStream(InputStream is) throws IOException {
         try {
             int start = length;
-            elems = ArrayUtils.ensureCapacity(elems, length + is.available());
-            int r = is.read(elems, start, is.available());
+            int initialSize = is.available();
+            elems = ArrayUtils.ensureCapacity(elems, length + initialSize);
+            int r = is.read(elems, start, initialSize);
             int bp = start;
             while (r != -1) {
                 bp += r;
--- a/test/tools/javac/valhalla/typespec/items/tests/TestRespecialization.java	Thu Dec 17 16:28:01 2015 +0000
+++ b/test/tools/javac/valhalla/typespec/items/tests/TestRespecialization.java	Fri Dec 18 18:24:00 2015 +0000
@@ -79,7 +79,7 @@
     @BytecodeMapping(opcode = Opcodes.INVOKEDYNAMIC,
                      sig = "(LTestRespecialization$MultiBox<ILjava/lang/Object;TC;TD;TE;>;F)LTestRespecialization$MultiBox<ILjava/lang/Object;FTD;TE;>;::{0=LTestRespecialization$MultiBox<ILjava/lang/Object;TC;TD;TE;>;}")
     @BytecodeMapping(opcode = Opcodes.INVOKEVIRTUAL,
-                     sig = "LTestRespecialization$MultiBox<ILjava/lang/Object;FTD;TE;>;::" +
+                     sig = "LTestRespecialization$MultiBox<ILjava/lang/Long;FTD;TE;>;::" +
                            "(Ljava/lang/Object;)LTestRespecialization$MultiBox<ILjava/lang/Object;FLjava/lang/Object;TE;>;")
     @BytecodeMapping(opcode = Opcodes.INVOKEDYNAMIC,
                      sig = "(LTestRespecialization$MultiBox<ILjava/lang/Object;FLjava/lang/Object;TE;>;Z)LTestRespecialization$MultiBox<ILjava/lang/Object;FLjava/lang/Object;Z>;::{0=LTestRespecialization$MultiBox<ILjava/lang/Object;FLjava/lang/Object;TE;>;}")