changeset 2994:761d199068c7

Enhancement: add support for anyfied lambdas * Overhaul boostrap static argument javac support * Add new SpecializerSignature attribute * Enhance BMAs for indy so that it also contains info for specialized static args * Added smoke test
author mcimadamore
date Fri, 29 May 2015 18:51:42 +0100
parents b91634e5f051
children 52d2779ddd19
files src/jdk.compiler/share/classes/com/sun/tools/classfile/Attribute.java src/jdk.compiler/share/classes/com/sun/tools/classfile/ClassWriter.java src/jdk.compiler/share/classes/com/sun/tools/classfile/SpecializerSignature_attribute.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/IndifierTranslator.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/SpecializeTypes.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Pool.java src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java src/jdk.compiler/share/classes/com/sun/tools/javap/AttributeWriter.java test/lib/annotations/annotations/classfile/ClassfileInspector.java test/tools/javac/MethodParameters/AttributeVisitor.java test/tools/javac/lambda/TestInvokeDynamic.java test/tools/javac/valhalla/typespec/items/tests/TestLambda.java
diffstat 18 files changed, 445 insertions(+), 143 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/classfile/Attribute.java	Fri May 29 16:51:55 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/classfile/Attribute.java	Fri May 29 18:51:42 2015 +0100
@@ -63,6 +63,7 @@
     public static final String RuntimeVisibleTypeAnnotations = "RuntimeVisibleTypeAnnotations";
     public static final String RuntimeInvisibleTypeAnnotations = "RuntimeInvisibleTypeAnnotations";
     public static final String Signature                = "Signature";
+    public static final String SpecializerSignature     = "SpecializerSignature";
     public static final String SourceDebugExtension     = "SourceDebugExtension";
     public static final String SourceFile               = "SourceFile";
     public static final String SourceID                 = "SourceID";
@@ -133,6 +134,7 @@
             standardAttributes.put(RuntimeVisibleTypeAnnotations, RuntimeVisibleTypeAnnotations_attribute.class);
             standardAttributes.put(RuntimeInvisibleTypeAnnotations, RuntimeInvisibleTypeAnnotations_attribute.class);
             standardAttributes.put(Signature,         Signature_attribute.class);
+            standardAttributes.put(SpecializerSignature,         SpecializerSignature_attribute.class);
             standardAttributes.put(SourceDebugExtension, SourceDebugExtension_attribute.class);
             standardAttributes.put(SourceFile,        SourceFile_attribute.class);
             standardAttributes.put(SourceID,          SourceID_attribute.class);
@@ -193,6 +195,7 @@
         R visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, P p);
         R visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, P p);
         R visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, P p);
+        R visitSpecializerSignature(SpecializerSignature_attribute attr, P p);
         R visitSignature(Signature_attribute attr, P p);
         R visitSourceDebugExtension(SourceDebugExtension_attribute attr, P p);
         R visitSourceFile(SourceFile_attribute attr, P p);
--- a/src/jdk.compiler/share/classes/com/sun/tools/classfile/ClassWriter.java	Fri May 29 16:51:55 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/classfile/ClassWriter.java	Fri May 29 18:51:42 2015 +0100
@@ -562,6 +562,11 @@
             return null;
         }
 
+        public Void visitSpecializerSignature(SpecializerSignature_attribute attr, ClassOutputStream out) {
+            out.writeShort(attr.signature_index);
+            return null;
+        }
+
         public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, ClassOutputStream out) {
             out.write(attr.debug_extension, 0, attr.debug_extension.length);
             return null;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/classfile/SpecializerSignature_attribute.java	Fri May 29 18:51:42 2015 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2007, 2008, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.tools.classfile;
+
+import java.io.IOException;
+
+/**
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class SpecializerSignature_attribute extends Signature_attribute {
+    SpecializerSignature_attribute(ClassReader cr, int name_index, int length) throws IOException {
+        super(cr, name_index, length);
+    }
+
+    public SpecializerSignature_attribute(ConstantPool constant_pool, int signature_index)
+            throws ConstantPoolException {
+        super(constant_pool.getUTF8Index(Attribute.SpecializerSignature), signature_index);
+    }
+
+    public SpecializerSignature_attribute(int name_index, int signature_index) {
+        super(name_index, signature_index);
+    }
+
+    public <R, D> R accept(Visitor<R, D> visitor, D data) {
+        return visitor.visitSpecializerSignature(this, data);
+    }
+}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Fri May 29 16:51:55 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Fri May 29 18:51:42 2015 +0100
@@ -27,6 +27,7 @@
 
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Inherited;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.regex.Matcher;
@@ -48,6 +49,7 @@
 import com.sun.tools.javac.comp.Env;
 import com.sun.tools.javac.comp.SpecializeTypes;
 import com.sun.tools.javac.jvm.*;
+import com.sun.tools.javac.jvm.Pool.MethodHandle;
 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.DefinedBy.Api;
@@ -1801,11 +1803,109 @@
      */
     public static class DynamicMethodSymbol extends MethodSymbol {
 
-        public Object[] staticArgs;
+        /**
+         * A class representing a static argument in an indy call.
+         */
+        public static class BootstrapArgument<D> {
+
+            /**
+             * Static argument kind.
+             */
+            public enum Kind {
+                CLASS(ClassSymbol.class),
+                INT(Integer.class),
+                LONG(Long.class),
+                FLOAT(Float.class),
+                DOUBLE(Double.class),
+                STRING(String.class),
+                METHOD_HANDLE(Pool.MethodHandle.class),
+                METHOD_TYPE(MethodType.class);
+
+                final Class<?> clazz;
+
+                Kind(Class<?> clazz) {
+                    this.clazz = clazz;
+                }
+
+                public Type asType(Symtab syms) {
+                    switch (this) {
+                        case CLASS:
+                            return syms.classType;
+                        case INT:
+                            return syms.intType;
+                        case LONG:
+                            return syms.longType;
+                        case FLOAT:
+                            return syms.floatType;
+                        case DOUBLE:
+                            return syms.doubleType;
+                        case STRING:
+                            return syms.stringType;
+                        case METHOD_HANDLE:
+                            return syms.methodHandleType;
+                        case METHOD_TYPE:
+                            return syms.methodTypeType;
+                        default:
+                            Assert.error("Unexpected kind " + this);
+                            return null;
+                    }
+                }
+            }
+
+            public final Kind kind;
+            public final D data;
+
+            public BootstrapArgument(Kind kind, D data) {
+                this.kind = kind;
+                this.data = data;
+                Assert.check(kind.clazz.isAssignableFrom(data.getClass()));
+            }
+
+            /**
+             * Map a static argument to a type (where possible).
+             */
+            public Optional<Type> asType() {
+                switch (kind) {
+                    case METHOD_TYPE:
+                        return Optional.of(((MethodType)data));
+                    case CLASS:
+                        return Optional.of(((Symbol)data).type);
+                    case METHOD_HANDLE:
+                        return Optional.of(((MethodHandle)data).refSym.owner.type);
+                    default:
+                        return Optional.empty();
+                }
+            }
+
+            /**
+             * Map a static argument to a symbol (where possible).
+             */
+            public Optional<Symbol> asSymbol() {
+                switch (kind) {
+                    case CLASS:
+                        return Optional.of(((Symbol)data));
+                    case METHOD_HANDLE:
+                        return Optional.of(((MethodHandle)data).refSym);
+                    default:
+                        return Optional.empty();
+                }
+            }
+
+            //factory methods
+            public static BootstrapArgument<ClassSymbol> Class(ClassSymbol data) { return new BootstrapArgument<>(Kind.CLASS, data); }
+            public static BootstrapArgument<Integer> Int(Integer data) { return new BootstrapArgument<>(Kind.INT, data); }
+            public static BootstrapArgument<Float> Float(Float data) { return new BootstrapArgument<>(Kind.FLOAT, data); }
+            public static BootstrapArgument<Double> Double(Double data) { return new BootstrapArgument<>(Kind.DOUBLE, data); }
+            public static BootstrapArgument<String> String(String data) { return new BootstrapArgument<>(Kind.STRING, data); }
+            public static BootstrapArgument<Pool.MethodHandle> MethodHandle(Pool.MethodHandle data) { return new BootstrapArgument<>(Kind.METHOD_HANDLE, data); }
+            public static BootstrapArgument<MethodType> MethodType(MethodType data) { return new BootstrapArgument<>(Kind.METHOD_TYPE, data); }
+        }
+
+        public BootstrapArgument<?>[] staticArgs;
         public Symbol bsm;
         public int bsmKind;
 
-        public DynamicMethodSymbol(Name name, Symbol owner, int bsmKind, MethodSymbol bsm, Type type, Object[] staticArgs) {
+        public DynamicMethodSymbol(Name name, Symbol owner, int bsmKind, MethodSymbol bsm, Type type, BootstrapArgument<?>[] staticArgs) {
             super(0, name, type, owner);
             this.bsm = bsm;
             this.bsmKind = bsmKind;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Fri May 29 16:51:55 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Fri May 29 18:51:42 2015 +0100
@@ -284,6 +284,24 @@
         }
     }
 
+    public void synthesizeEmptyGenericMethodSpecializerIfMissing(final Type type) {
+        final Completer completer = type.tsym.completer;
+        if (completer != null) {
+            type.tsym.completer = new Completer() {
+                public void complete(Symbol sym) throws CompletionFailure {
+                    try {
+                        completer.complete(sym);
+                    } catch (CompletionFailure e) {
+                        sym.flags_field |= (PUBLIC | INTERFACE);
+                        ((ClassType) sym.type).supertype_field = objectType;
+                        sym.members().enter(new MethodSymbol(STATIC | PUBLIC | VARARGS, names.metafactory, new MethodType(List.of(methodHandleLookupType, stringType, methodTypeType, new ArrayType(objectType
+                        , arrayClass)), callSiteType, List.nil(), methodClass), sym));
+                    }
+                }
+            };
+        }
+    }
+
     public void synthesizeBoxTypeIfMissing(final Type type) {
         ClassSymbol sym = enterClass(boxedName[type.getTag().ordinal()]);
         final Completer completer = sym.completer;
@@ -497,7 +515,7 @@
         synthesizeEmptyInterfaceIfMissing(cloneableType);
         synthesizeEmptyInterfaceIfMissing(serializableType);
         synthesizeEmptyInterfaceIfMissing(lambdaMetafactory);
-        synthesizeEmptyInterfaceIfMissing(genericMethodSpecialzer);
+        synthesizeEmptyGenericMethodSpecializerIfMissing(genericMethodSpecialzer);
         synthesizeEmptyInterfaceIfMissing(serializedLambdaType);
         synthesizeBoxTypeIfMissing(doubleType);
         synthesizeBoxTypeIfMissing(floatType);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Fri May 29 16:51:55 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Fri May 29 18:51:42 2015 +0100
@@ -46,6 +46,7 @@
 import com.sun.tools.javac.code.Type.UndetVar.*;
 import com.sun.tools.javac.code.Type.UndetVar.Flag;
 import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
+import com.sun.tools.javac.code.Types.SignatureGenerator.SigMode;
 import com.sun.tools.javac.comp.AttrContext;
 import com.sun.tools.javac.comp.Check;
 import com.sun.tools.javac.comp.Enter;
@@ -370,6 +371,11 @@
             public Boolean visitCapturedType(CapturedType t, Predicate<Type> typePredicate) {
                 return visitWildcardType(t.wildcard, typePredicate);
             }
+
+            @Override
+            public Boolean visitMethodType(MethodType t, Predicate<Type> typePredicate) {
+                return t.getParameterTypes().prepend(t.getReturnType()).stream().anyMatch(p -> visit(p, typePredicate));
+            }
         };
 
         Predicate<Type> containsAnyRecursive = t -> true;
@@ -5479,6 +5485,11 @@
 
     public static abstract class SignatureGenerator {
 
+        public enum SigMode {
+            NORMAL,
+            SPECIALIZER;
+        }
+
         private final Types types;
 
         protected abstract void append(char ch);
@@ -5493,11 +5504,14 @@
         /**
          * Assemble signature of given type in string buffer.
          */
-        public void assembleSig(Type type) {
+        public void assembleSig(Type type, SigMode mode) {
+            if (mode == SigMode.SPECIALIZER) {
+                type = normalize(type);
+            }
             switch (type.getTag()) {
                 case ANY_BOUND:
                     //for compatibility
-                    assembleSig(types.syms.objectType);
+                    assembleSig(types.syms.objectType, mode);
                     break;
                 case BYTE:
                     append('B');
@@ -5531,24 +5545,24 @@
                         append('Q');
                     else
                         append('L');
-                    assembleClassSig(type);
+                    assembleClassSig(type, mode);
                     append(';');
                     break;
                 case ARRAY:
                     ArrayType at = (ArrayType) type;
                     append('[');
-                    assembleSig(at.elemtype);
+                    assembleSig(at.elemtype, mode);
                     break;
                 case METHOD:
                     MethodType mt = (MethodType) type;
                     append('(');
-                    assembleSig(mt.argtypes);
+                    assembleSig(mt.argtypes, mode);
                     append(')');
-                    assembleSig(mt.restype);
+                    assembleSig(mt.restype, mode);
                     if (hasTypeVar(mt.thrown)) {
                         for (List<Type> l = mt.thrown; l.nonEmpty(); l = l.tail) {
                             append('^');
-                            assembleSig(l.head);
+                            assembleSig(l.head, mode);
                         }
                     }
                     break;
@@ -5557,11 +5571,11 @@
                     switch (ta.kind) {
                         case SUPER:
                             append('-');
-                            assembleSig(ta.type);
+                            assembleSig(ta.type, mode);
                             break;
                         case EXTENDS:
                             append('+');
-                            assembleSig(ta.type);
+                            assembleSig(ta.type, mode);
                             break;
                         case UNBOUND:
                             append('*');
@@ -5578,13 +5592,30 @@
                     break;
                 case FORALL:
                     Type.ForAll ft = (Type.ForAll) type;
-                    assembleParamsSig(ft.tvars);
-                    assembleSig(ft.qtype);
+                    assembleParamsSig(ft.tvars, mode);
+                    assembleSig(ft.qtype, mode);
                     break;
                 default:
                     throw new AssertionError("typeSig " + type.getTag());
             }
         }
+        //where
+            private Type normalize(Type t) {
+                switch (t.getTag()) {
+                    case TYPEVAR:
+                        TypeVar tv = (TypeVar)t;
+                        return ((TypeVar)t).isCaptured() ?
+                                normalize(((CapturedType)t).wildcard) : tv;
+                    case CLASS:
+                        ClassType ct = (ClassType)t;
+                        return ct.isCompound() ?
+                                ((IntersectionClassType)ct).getExplicitComponents().head :
+                                ct;
+                    default:
+                        return t;
+                }
+            }
+
 
         public boolean hasTypeVar(List<Type> l) {
             while (l.nonEmpty()) {
@@ -5596,7 +5627,7 @@
             return false;
         }
 
-        public void assembleClassSig(Type type) {
+        public void assembleClassSig(Type type, SigMode mode) {
             ClassType ct = (ClassType) type;
             ClassSymbol c = (ClassSymbol) ct.tsym;
             classReference(c);
@@ -5607,7 +5638,7 @@
                         c.name == types.names.empty; // or anonymous
                 assembleClassSig(rawOuter
                         ? types.erasure(outer)
-                        : outer);
+                        : outer, mode);
                 append(rawOuter ? '$' : '.');
                 Assert.check(c.flatname.startsWith(c.owner.enclClass().flatname));
                 append(rawOuter
@@ -5618,12 +5649,12 @@
             }
             if (ct.getTypeArguments().nonEmpty()) {
                 append('<');
-                assembleSig(ct.getTypeArguments());
+                assembleSig(ct.getTypeArguments(), mode);
                 append('>');
             }
         }
 
-        public void assembleParamsSig(List<Type> typarams) {
+        public void assembleParamsSig(List<Type> typarams, SigMode mode) {
             append('<');
             for (List<Type> ts = typarams; ts.nonEmpty(); ts = ts.tail) {
                 Type.TypeVar tvar = (Type.TypeVar) ts.head;
@@ -5634,15 +5665,15 @@
                 }
                 for (List<Type> l = bounds; l.nonEmpty(); l = l.tail) {
                     append(':');
-                    assembleSig(l.head);
+                    assembleSig(l.head, mode);
                 }
             }
             append('>');
         }
 
-        private void assembleSig(List<Type> types) {
+        private void assembleSig(List<Type> types, SigMode mode) {
             for (List<Type> ts = types; ts.nonEmpty(); ts = ts.tail) {
-                assembleSig(ts.head);
+                assembleSig(ts.head, mode);
             }
         }
     }
@@ -5685,29 +5716,13 @@
      */
     public Name typeSig(Type type) {
         SignatureGenerator sg = new BuilderSignatureGenerator(this);
-        sg.assembleSig(type);
+        sg.assembleSig(type, SigMode.NORMAL);
         return names.fromString(sg.toString());
    }
 
     public Name specializerSig(Type type) {
-        SignatureGenerator sg = new BuilderSignatureGenerator(this) {
-            @Override
-            public void assembleSig(Type type) {
-                super.assembleSig(normalize(type));
-            }
-
-            private Type normalize(Type t) {
-                switch (t.getTag()) {
-                    case TYPEVAR:
-                        TypeVar tv = (TypeVar)t;
-                        return ((TypeVar)t).isCaptured() ?
-                                normalize(((CapturedType)t).wildcard) : tv;
-                    default:
-                        return t;
-                }
-            }
-        };
-        sg.assembleSig(type);
+        SignatureGenerator sg = new BuilderSignatureGenerator(this);
+        sg.assembleSig(type, SigMode.SPECIALIZER);
         return names.fromString(sg.toString());
     }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/IndifierTranslator.java	Fri May 29 16:51:55 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/IndifierTranslator.java	Fri May 29 18:51:42 2015 +0100
@@ -28,6 +28,7 @@
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol;
+import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol.BootstrapArgument;
 import com.sun.tools.javac.code.Symbol.MethodSymbol;
 import com.sun.tools.javac.code.Symbol.VarSymbol;
 import com.sun.tools.javac.code.Symtab;
@@ -82,17 +83,17 @@
      * arguments types
      */
     protected JCMethodInvocation makeIndyCall(DiagnosticPosition pos, Type site, Name bsmName,
-                                        List<Object> staticArgs, MethodType indyType, List<JCExpression> indyArgs,
+                                        List<BootstrapArgument<?>> staticArgs, MethodType indyType, List<JCExpression> indyArgs,
                                         Name methName) {
         return makeIndyCall(pos, syms.noSymbol, site, bsmName, staticArgs, indyType, indyArgs, methName);
     }
 
     protected JCMethodInvocation makeIndyCall(DiagnosticPosition pos, Symbol owner, Type site, Name bsmName,
-                                      List<Object> staticArgs, MethodType indyType, List<JCExpression> indyArgs,
+                                      List<BootstrapArgument<?>> staticArgs, MethodType indyType, List<JCExpression> indyArgs,
                                       Name methName) {
         List<Type> bsm_staticArgs = List.of(syms.methodHandleLookupType,
                 syms.stringType,
-                syms.methodTypeType).appendList(bsmStaticArgToTypes(staticArgs));
+                syms.methodTypeType).appendList(staticArgs.map(a -> a.kind.asType(syms)));
 
         Symbol bsm = rs.resolveInternalMethod(pos, attrEnv, site,
                 bsmName, bsm_staticArgs, List.<Type>nil());
@@ -102,54 +103,22 @@
                 referenceKind(bsm),
                 (MethodSymbol)bsm,
                 indyType,
-                staticArgs.toArray());
+                staticArgs.toArray(new BootstrapArgument<?>[staticArgs.length()]));
         int prevPos = make.pos;
         try {
             make.at(pos);
             JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), bsmName);
             qualifier.sym = dynSym;
-            qualifier.type = indyType.getReturnType();
+            qualifier.type = rs.types.erasure(indyType.getReturnType());
 
             JCMethodInvocation proxyCall = make.Apply(List.<JCExpression>nil(), qualifier, indyArgs);
-            proxyCall.type = indyType.getReturnType();
+            proxyCall.type = rs.types.erasure(indyType.getReturnType());
             return proxyCall;
         } finally {
             make.at(prevPos);
         }
     }
 
-    protected List<Type> bsmStaticArgToTypes(List<Object> args) {
-        ListBuffer<Type> argtypes = new ListBuffer<>();
-        for (Object arg : args) {
-            argtypes.append(bsmStaticArgToType(arg));
-        }
-        return argtypes.toList();
-    }
-
-    protected Type bsmStaticArgToType(Object arg) {
-        Assert.checkNonNull(arg);
-        if (arg instanceof ClassSymbol) {
-            return syms.classType;
-        } else if (arg instanceof Integer) {
-            return syms.intType;
-        } else if (arg instanceof Long) {
-            return syms.longType;
-        } else if (arg instanceof Float) {
-            return syms.floatType;
-        } else if (arg instanceof Double) {
-            return syms.doubleType;
-        } else if (arg instanceof String) {
-            return syms.stringType;
-        } else if (arg instanceof Pool.MethodHandle) {
-            return syms.methodHandleType;
-        } else if (arg instanceof MethodType) {
-            return syms.methodTypeType;
-        } else {
-            Assert.error("bad static arg " + arg.getClass());
-            return null;
-        }
-    }
-
     /**
      * Get the opcode associated with this method reference
      */
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Fri May 29 16:51:55 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Fri May 29 18:51:42 2015 +0100
@@ -24,8 +24,11 @@
  */
 package com.sun.tools.javac.comp;
 
+import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol.BootstrapArgument;
 import com.sun.tools.javac.code.Type.ForAll;
+import com.sun.tools.javac.code.Types.AsSuperKind;
 import com.sun.tools.javac.code.Types.BuilderSignatureGenerator;
+import com.sun.tools.javac.code.Types.SignatureGenerator.SigMode;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
@@ -591,7 +594,7 @@
      }
 
     private void addDeserializationCase(int implMethodKind, Symbol refSym, Type targetType, MethodSymbol samSym,
-            DiagnosticPosition pos, List<Object> staticArgs, MethodType indyType) {
+            DiagnosticPosition pos, List<BootstrapArgument<?>> staticArgs, MethodType indyType) {
         String functionalInterfaceClass = classSig(targetType);
         String functionalInterfaceMethodName = samSym.getSimpleName().toString();
         String functionalInterfaceMethodSignature = typeSig(types.erasure(samSym.type));
@@ -761,6 +764,7 @@
                 slam.targets = tree.targets;
                 slam.type = tree.type;
                 slam.pos = tree.pos;
+                slam.unerasedType = tree.unerasedType;
                 return slam;
             } finally {
                 make.at(prevPos);
@@ -929,7 +933,26 @@
         return new MethodType(type.getParameterTypes(),
                         type.getReturnType(),
                         type.getThrownTypes(),
-                        syms.methodClass);
+                        syms.methodClass) {
+            @Override
+            public Type baseType() {
+                return mt;
+            }
+        };
+    }
+
+    private MethodType erasedDescType(JCTree tree, Symbol desc, Type site) {
+        Type type = desc.erasure(types);
+        Type instType = types.memberType(types.specialize(site), desc, AsSuperKind.PARTIAL_ERASURE);
+        return new MethodType(type.getParameterTypes(),
+                type.getReturnType(),
+                type.getThrownTypes(),
+                syms.methodClass) {
+            @Override
+            public Type baseType() {
+                return instType;
+            }
+        };
     }
 
     /**
@@ -940,10 +963,10 @@
         JCFunctionalExpression tree = context.tree;
         //determine the static bsm args
         MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.type.tsym);
-        List<Object> staticArgs = List.<Object>of(
-                typeToMethodType(samSym.type),
-                new Pool.MethodHandle(refKind, refSym, types),
-                typeToMethodType(tree.getDescriptorType(types)));
+        List<BootstrapArgument<?>> staticArgs = List.of(
+                BootstrapArgument.MethodType(erasedDescType(tree, samSym, tree.targets.head)),
+                BootstrapArgument.MethodHandle(new Pool.MethodHandle(refKind, refSym, types)),
+                BootstrapArgument.MethodType(typeToMethodType(tree.getDescriptorType(types))));
 
         //computed indy arg types
         ListBuffer<Type> indy_args_types = new ListBuffer<>();
@@ -953,7 +976,7 @@
 
         //finally, compute the type of the indy call
         MethodType indyType = new MethodType(indy_args_types.toList(),
-                tree.type,
+                tree.unerasedType,
                 List.<Type>nil(),
                 syms.methodClass);
 
@@ -961,10 +984,10 @@
                 names.altMetafactory : names.metafactory;
 
         if (context.needsAltMetafactory()) {
-            ListBuffer<Object> markers = new ListBuffer<>();
+            ListBuffer<ClassSymbol> markers = new ListBuffer<>();
             for (Type t : tree.targets.tail) {
                 if (t.tsym != syms.serializableType.tsym) {
-                    markers.append(t.tsym);
+                    markers.append((ClassSymbol)t.tsym);
                 }
             }
             int flags = context.isSerializable() ? FLAG_SERIALIZABLE : 0;
@@ -976,17 +999,17 @@
             if (hasBridges) {
                 flags |= FLAG_BRIDGES;
             }
-            staticArgs = staticArgs.append(flags);
+            staticArgs = staticArgs.append(BootstrapArgument.Int(flags));
             if (hasMarkers) {
-                staticArgs = staticArgs.append(markers.length());
-                staticArgs = staticArgs.appendList(markers.toList());
+                staticArgs = staticArgs.append(BootstrapArgument.Int(markers.length()));
+                staticArgs = staticArgs.appendList(markers.toList().map(BootstrapArgument::Class));
             }
             if (hasBridges) {
-                staticArgs = staticArgs.append(context.bridges.length() - 1);
+                staticArgs = staticArgs.append(BootstrapArgument.Int(context.bridges.length() - 1));
                 for (Symbol s : context.bridges) {
                     Type s_erasure = s.erasure(types);
                     if (!types.isSameType(s_erasure, samSym.erasure(types))) {
-                        staticArgs = staticArgs.append(s.erasure(types));
+                        staticArgs = staticArgs.append(BootstrapArgument.MethodType((MethodType)s.erasure(types)));
                     }
                 }
             }
@@ -2051,13 +2074,13 @@
 
     private String typeSig(Type type) {
         BuilderSignatureGenerator sg = new BuilderSignatureGenerator(types);
-        sg.assembleSig(type);
+        sg.assembleSig(type, SigMode.NORMAL);
         return sg.toString();
     }
 
     private String classSig(Type type) {
         BuilderSignatureGenerator sg = new BuilderSignatureGenerator(types);
-        sg.assembleClassSig(type);
+        sg.assembleClassSig(type, SigMode.NORMAL);
         return sg.toString();
     }
 }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/SpecializeTypes.java	Fri May 29 16:51:55 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/SpecializeTypes.java	Fri May 29 18:51:42 2015 +0100
@@ -29,6 +29,7 @@
 import com.sun.tools.javac.code.Kinds;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol.BootstrapArgument;
 import com.sun.tools.javac.code.Symbol.MethodSymbol;
 import com.sun.tools.javac.code.Symbol.VarSymbol;
 import com.sun.tools.javac.code.Type;
@@ -51,7 +52,9 @@
 import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
 import com.sun.tools.javac.tree.JCTree.JCIdent;
 import com.sun.tools.javac.tree.JCTree.JCInstanceOf;
+import com.sun.tools.javac.tree.JCTree.JCLambda;
 import com.sun.tools.javac.tree.JCTree.JCLiteral;
+import com.sun.tools.javac.tree.JCTree.JCMemberReference;
 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
 import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
 import com.sun.tools.javac.tree.JCTree.JCNewArray;
@@ -204,14 +207,15 @@
             if (typeargs.stream().anyMatch(types::isTypeArgumentSpecializable)) {
                 receiverType = types.referenceArgTypesAsErasedFormals(receiverType);
 
-                List<Object> staticArgs = typeargs.stream()
-                        .map(ta -> types.isTypeArgumentSpecializable(ta) ? types.specializerSig(ta).toString() : "")
+                List<BootstrapArgument<?>> staticArgs = typeargs.stream()
+                        .map(ta -> BootstrapArgument.String(types.isTypeArgumentSpecializable(ta) ?
+                                types.specializerSig(ta).toString() : ""))
                         .collect(List.collector());
 
                 Symbol unspecializedMeth = msym.baseSymbol();
 
-                staticArgs = staticArgs.prepend(new MethodHandle(referenceKind(unspecializedMeth), unspecializedMeth, types));
-                staticArgs = staticArgs.prepend(types.specializerSig(types.specialize(receiverType)).toString());
+                staticArgs = staticArgs.prepend(BootstrapArgument.MethodHandle(new MethodHandle(referenceKind(unspecializedMeth), unspecializedMeth, types)));
+                staticArgs = staticArgs.prepend(BootstrapArgument.String(types.specializerSig(types.specialize(receiverType)).toString()));
 
                 ForAll uninstantiatedMethodType = !receiverType.hasTag(TypeTag.NONE) ?
                         (ForAll)types.memberType(receiverType, msym) :
@@ -292,6 +296,18 @@
     }
 
     @Override
+    public void visitLambda(JCLambda tree) {
+        tree.unerasedType = tree.type;
+        super.visitLambda(tree);
+    }
+
+    @Override
+    public void visitReference(JCMemberReference tree) {
+        tree.unerasedType = tree.type;
+        super.visitReference(tree);
+    }
+
+    @Override
     public void visitNewArray(JCNewArray tree) {
         tree.elemtype = translate(tree.elemtype);
         tree.elems = translate(tree.elems);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri May 29 16:51:55 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri May 29 18:51:42 2015 +0100
@@ -38,7 +38,9 @@
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
 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.SignatureGenerator.SigMode;
 import com.sun.tools.javac.code.Types.UnaryVisitor;
 import com.sun.tools.javac.code.Types.UniqueType;
 import com.sun.tools.javac.file.BaseFileObject;
@@ -294,16 +296,16 @@
          * Check for uninitialized types before calling the general case.
          */
         @Override
-        public void assembleSig(Type type) {
+        public void assembleSig(Type type, SigMode mode) {
             switch (type.getTag()) {
                 case UNINITIALIZED_THIS:
                 case UNINITIALIZED_OBJECT:
                     // we don't yet have a spec for uninitialized types in the
                     // local variable table
-                    assembleSig(types.erasure(((UninitializedType)type).qtype));
+                    assembleSig(types.erasure(((UninitializedType)type).qtype), mode);
                     break;
                 default:
-                    super.assembleSig(type);
+                    super.assembleSig(type, mode);
             }
         }
 
@@ -344,9 +346,13 @@
      * Return signature of given type
      */
     Name typeSig(Type type) {
+        return typeSig(type, SigMode.NORMAL);
+    }
+
+    Name typeSig(Type type, SigMode mode) {
         Assert.check(signatureGen.isEmpty());
         //- System.out.println(" ? " + type);
-        signatureGen.assembleSig(type);
+        signatureGen.assembleSig(type, mode);
         Name n = signatureGen.toName();
         signatureGen.reset();
         //- System.out.println("   " + n);
@@ -415,8 +421,8 @@
                     //init cp entries
                     pool.put(names.BootstrapMethods);
                     pool.put(handle);
-                    for (Object staticArg : dynSym.staticArgs) {
-                        pool.put(staticArg);
+                    for (BootstrapArgument<?> staticArg : dynSym.staticArgs) {
+                        pool.put(staticArg.data);
                     }
                     poolbuf.appendByte(CONSTANT_InvokeDynamic);
                     poolbuf.appendChar(bootstrapMethods.size() - 1);
@@ -613,15 +619,22 @@
     int writeMemberAttrs(Symbol sym) {
         int acount = writeFlagAttrs(sym.flags());
         long flags = sym.flags();
-        if ((flags & (SYNTHETIC | BRIDGE)) != SYNTHETIC &&
-            (flags & ANONCONSTR) == 0 &&
-            (!types.isSameType(sym.type, sym.erasure(types)) ||
+        if (!types.isSameType(sym.type, sym.erasure(types)) ||
 		     containsSpecialized(sym.type) ||
-             signatureGen.hasTypeVar(sym.type.getThrownTypes()))) {
+             signatureGen.hasTypeVar(sym.type.getThrownTypes())) {
+
+            //if member is synthetic, pick SpecialzierSignature instead
+            boolean regularSig = ((flags & (SYNTHETIC | BRIDGE)) != SYNTHETIC &&
+                    (flags & ANONCONSTR) == 0);
+            Name sigName = regularSig ?
+                    names.Signature :
+                    names.SpecializerSignature;
+
             // note that a local class with captured variables
             // will get a signature attribute
-            int alenIdx = writeAttr(names.Signature);
-            databuf.appendChar(pool.put(typeSig(sym.type)));
+            int alenIdx = writeAttr(sigName);
+
+            databuf.appendChar(pool.put(typeSig(sym.type, regularSig ? SigMode.NORMAL : SigMode.SPECIALIZER)));
             endAttr(alenIdx);
             acount++;
         }
@@ -1814,10 +1827,10 @@
             sigReq = l.head.allparams().length() != 0 || containsSpecialized(l.head);
         if (sigReq) {
             int alenIdx = writeAttr(names.Signature);
-            if (typarams.length() != 0) signatureGen.assembleParamsSig(typarams);
-            signatureGen.assembleSig(types.unspecialize(supertype));
+            if (typarams.length() != 0) signatureGen.assembleParamsSig(typarams, SigMode.NORMAL);
+            signatureGen.assembleSig(types.unspecialize(supertype), SigMode.NORMAL);
             for (List<Type> l = interfaces; l.nonEmpty(); l = l.tail)
-                signatureGen.assembleSig(types.unspecialize(l.head));
+                signatureGen.assembleSig(types.unspecialize(l.head), SigMode.NORMAL);
             databuf.appendChar(pool.put(signatureGen.toName()));
             signatureGen.reset();
             endAttr(alenIdx);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java	Fri May 29 16:51:55 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java	Fri May 29 18:51:42 2015 +0100
@@ -27,6 +27,7 @@
 
 import com.sun.tools.javac.code.*;
 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.UnaryVisitor;
 import com.sun.tools.javac.jvm.Code.*;
@@ -34,12 +35,16 @@
 import com.sun.tools.javac.jvm.Pool.MethodHandle;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Name;
 import com.sun.tools.javac.util.Names;
 
+import java.util.Optional;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import static com.sun.tools.javac.jvm.ByteCodes.*;
 
@@ -123,16 +128,23 @@
      *  @param member   The represented symbol.
      */
     Item makeDynamicItem(Symbol member) {
-        DynamicMethodSymbol dynSym = (DynamicMethodSymbol)member;
         DynamicItem dynItem = new DynamicItem(member);
-        if (dynSym.bsm.owner.type == syms.genericMethodSpecialzer) {
-            Symbol invokedSymbol = ((MethodHandle)dynSym.staticArgs[1]).refSym;
-            return new AnyDynamicItem(dynItem,
-                    invokedSymbol,
-                    member.type);
+        return (isAnyIndy((DynamicMethodSymbol)member)) ?
+            new AnyDynamicItem(dynItem, member.type) :
+            dynItem;
+    }
+    //where
+        private boolean isAnyIndy(DynamicMethodSymbol dynSym) {
+            return dynSym.bsm.owner.type == syms.genericMethodSpecialzer ||
+                    types.containsSpecializableTvars(dynSym.type) ||
+                    Stream.of(dynSym.staticArgs).anyMatch(this::isAnyBoostrapArg);
         }
-        return dynItem;
-    }
+
+        private boolean isAnyBoostrapArg(BootstrapArgument<?> staticArg) {
+            return staticArg.asType()
+                    .map(t -> types.containsSpecializableTvars(t.baseType()))
+                    .orElse(false);
+        }
 
     /** Make an item representing an indexed expression.
      *  @param type    The expression's type.
@@ -211,7 +223,7 @@
      */
     Item makeAssignItem(Item lhs) {
         return wrapIfNeeded(new AssignItem(lhs), lhs, Item::isAny,
-                it-> it.originalType());
+                Item::originalType);
     }
 
     /** Make an item representing a conditional or unconditional jump.
@@ -257,7 +269,7 @@
         return wrapIfNeeded(condItem, item,
                 i -> i != null && i.isAny() &&
                         types.isSpecializableTypeVar(i.originalType()),
-                i -> i.originalType());
+                Item::originalType);
     }
 
     /** Wrap an item within an 'any' item based on the given input type.
@@ -636,16 +648,53 @@
 
         Type indyType;
 
-        AnyDynamicItem(DynamicItem delegatedItem, Symbol member, Type inferredType) {
-            super(delegatedItem, inferredType.getReturnType());
-            indyType = inferredType;
+        AnyDynamicItem(DynamicItem delegatedItem, Type indyType) {
+            super(delegatedItem, indyType.getReturnType());
+            this.indyType = indyType;
         }
 
         @Override
         protected Name getSig(int opcode) {
-            return needsMapping(opcode) ?
-                    types.specializerSig(indyType) :
-                    super.getSig(opcode);
+            DynamicMethodSymbol dynSym = (DynamicMethodSymbol)((DynamicItem)delegatedItem).member;
+            if (needsMapping(opcode)) {
+                ListBuffer<String> buf = new ListBuffer<>();
+                if (dynSym.bsm.owner.type != syms.genericMethodSpecialzer) {
+                    //structural info is not required for the generic specialized call case
+                    //as there, we should leave the method handle unspecialized, as it should point
+                    //to the original version of the method in the template class.
+                    for (int i = 0; i < dynSym.staticArgs.length; i++) {
+                        BootstrapArgument<?> staticArg = dynSym.staticArgs[i];
+                        if (isAnyBoostrapArg(staticArg)) {
+                            final String argSig;
+                            switch (staticArg.kind) {
+                                case METHOD_TYPE:
+                                    argSig = types.specializerSig(staticArg.asType().get().baseType()).toString();
+                                    break;
+                                case CLASS:
+                                    argSig = types.specializerSig(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.specializerSig(refSym.owner.type),
+                                            types.specializerSig(refSym.type))).toString();
+                                    break;
+                                default:
+                                    Assert.error("Cannot get here");
+                                    argSig = null;
+                            }
+                            buf.add(String.format("%d=%s", i, argSig));
+                        }
+                    }
+                }
+                Name dynDesc = types.specializerSig(indyType);
+                return buf.isEmpty() ?
+                        dynDesc :
+                        dynDesc.append(names.fromString(buf.stream().collect(Collectors.joining("&", "::{", "}"))));
+            } else {
+                return super.getSig(opcode);
+            }
         }
 
         @Override
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Pool.java	Fri May 29 16:51:55 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Pool.java	Fri May 29 18:51:42 2015 +0100
@@ -39,6 +39,7 @@
 import com.sun.tools.javac.util.Name;
 
 import java.util.*;
+import java.util.stream.Stream;
 
 import com.sun.tools.javac.util.DefinedBy;
 import com.sun.tools.javac.util.DefinedBy.Api;
@@ -189,7 +190,7 @@
 
         DynamicMethod(DynamicMethodSymbol m, Types types) {
             super(m, types);
-            uniqueStaticArgs = getUniqueTypeArray(m.staticArgs, types);
+            uniqueStaticArgs = getUniqueTypeArray(Stream.of(m.staticArgs).map(a -> a.data).toArray(), types);
         }
 
         @Override @DefinedBy(Api.LANGUAGE_MODEL)
@@ -258,10 +259,10 @@
     public static class MethodHandle {
 
         /** Reference kind - see ClassFile */
-        int refKind;
+        public int refKind;
 
         /** Reference symbol */
-        Symbol refSym;
+        public Symbol refSym;
 
         UniqueType uniqueType;
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java	Fri May 29 16:51:55 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java	Fri May 29 18:51:42 2015 +0100
@@ -142,6 +142,7 @@
     public final Name RuntimeVisibleParameterAnnotations;
     public final Name RuntimeVisibleTypeAnnotations;
     public final Name Signature;
+    public final Name SpecializerSignature;
     public final Name SourceFile;
     public final Name SourceID;
     public final Name StackMap;
@@ -282,6 +283,7 @@
         RuntimeVisibleParameterAnnotations = fromString("RuntimeVisibleParameterAnnotations");
         RuntimeVisibleTypeAnnotations = fromString("RuntimeVisibleTypeAnnotations");
         Signature = fromString("Signature");
+        SpecializerSignature = fromString("SpecializerSignature");
         SourceFile = fromString("SourceFile");
         SourceID = fromString("SourceID");
         StackMap = fromString("StackMap");
--- a/src/jdk.compiler/share/classes/com/sun/tools/javap/AttributeWriter.java	Fri May 29 16:51:55 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javap/AttributeWriter.java	Fri May 29 18:51:42 2015 +0100
@@ -59,6 +59,7 @@
 import com.sun.tools.classfile.SourceDebugExtension_attribute;
 import com.sun.tools.classfile.SourceFile_attribute;
 import com.sun.tools.classfile.SourceID_attribute;
+import com.sun.tools.classfile.SpecializerSignature_attribute;
 import com.sun.tools.classfile.StackMapTable_attribute;
 import com.sun.tools.classfile.StackMap_attribute;
 import com.sun.tools.classfile.Synthetic_attribute;
@@ -559,6 +560,13 @@
         }
     }
 
+    public Void visitSpecializerSignature(SpecializerSignature_attribute attr, Void ignore) {
+        print("SpecializerSignature: #" + attr.signature_index);
+        tab();
+        println("// " + getSignature(attr));
+        return null;
+    }
+
     public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, Void ignore) {
         println("SourceDebugExtension:");
         indent(+1);
--- a/test/lib/annotations/annotations/classfile/ClassfileInspector.java	Fri May 29 16:51:55 2015 +0100
+++ b/test/lib/annotations/annotations/classfile/ClassfileInspector.java	Fri May 29 18:51:42 2015 +0100
@@ -1300,6 +1300,12 @@
         }
 
         @Override
+        public Void visitSpecializerSignature(SpecializerSignature_attribute attr,
+                                   ExpectedTypeAnnotation expected) {
+            return null;
+        }
+
+        @Override
         public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr,
                                               ExpectedTypeAnnotation expected) {
             return null;
@@ -1508,6 +1514,12 @@
             }
 
             @Override
+                public Void visitSpecializerSignature(SpecializerSignature_attribute attr,
+                                       ExpectedAnnotation expected) {
+                return null;
+            }
+
+            @Override
                 public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr,
                                                       ExpectedAnnotation expected) {
                 return null;
@@ -1717,6 +1729,12 @@
             }
 
             @Override
+                public Void visitSpecializerSignature(SpecializerSignature_attribute attr,
+                                           ExpectedParameterAnnotation expected) {
+                    return null;
+            }
+
+            @Override
                 public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr,
                                                       ExpectedParameterAnnotation expected) {
                 return null;
--- a/test/tools/javac/MethodParameters/AttributeVisitor.java	Fri May 29 16:51:55 2015 +0100
+++ b/test/tools/javac/MethodParameters/AttributeVisitor.java	Fri May 29 18:51:42 2015 +0100
@@ -54,6 +54,7 @@
     public R visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, P p) { return null; }
     public R visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, P p) { return null; }
     public R visitSignature(Signature_attribute attr, P p) { return null; }
+    public R visitSpecializerSignature(SpecializerSignature_attribute attr, P p) { return null; }
     public R visitSourceDebugExtension(SourceDebugExtension_attribute attr, P p) { return null; }
     public R visitSourceFile(SourceFile_attribute attr, P p) { return null; }
     public R visitSourceID(SourceID_attribute attr, P p) { return null; }
--- a/test/tools/javac/lambda/TestInvokeDynamic.java	Fri May 29 16:51:55 2015 +0100
+++ b/test/tools/javac/lambda/TestInvokeDynamic.java	Fri May 29 18:51:42 2015 +0100
@@ -62,6 +62,8 @@
 
 import com.sun.tools.javac.api.JavacTaskImpl;
 import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol.BootstrapArgument;
+import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol.BootstrapArgument.Kind;
 import com.sun.tools.javac.code.Symbol.MethodSymbol;
 import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.code.Types;
@@ -79,7 +81,7 @@
     implements Runnable {
 
     enum StaticArgumentKind {
-        STRING("Hello!", "String", "Ljava/lang/String;") {
+        STRING("Hello!", "String", "Ljava/lang/String;", Kind.STRING) {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
                 return (cpInfo instanceof CONSTANT_String_info) &&
@@ -87,7 +89,7 @@
                         .equals(value);
             }
         },
-        CLASS(null, "Class<?>", "Ljava/lang/Class;") {
+        CLASS(null, "Class<?>", "Ljava/lang/Class;", Kind.CLASS) {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
                 return (cpInfo instanceof CONSTANT_Class_info) &&
@@ -95,7 +97,7 @@
                         .equals("java/lang/String");
             }
         },
-        INTEGER(1, "int", "I") {
+        INTEGER(1, "int", "I", Kind.INT) {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
                 return (cpInfo instanceof CONSTANT_Integer_info) &&
@@ -103,7 +105,7 @@
                         ((Integer)value).intValue();
             }
         },
-        LONG(1L, "long", "J") {
+        LONG(1L, "long", "J", Kind.LONG) {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
                 return (cpInfo instanceof CONSTANT_Long_info) &&
@@ -111,7 +113,7 @@
                         ((Long)value).longValue();
             }
         },
-        FLOAT(1.0f, "float", "F") {
+        FLOAT(1.0f, "float", "F", Kind.FLOAT) {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
                 return (cpInfo instanceof CONSTANT_Float_info) &&
@@ -119,7 +121,7 @@
                         ((Float)value).floatValue();
             }
         },
-        DOUBLE(1.0, "double","D") {
+        DOUBLE(1.0, "double","D", Kind.DOUBLE) {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
                 return (cpInfo instanceof CONSTANT_Double_info) &&
@@ -127,7 +129,7 @@
                         ((Double)value).doubleValue();
             }
         },
-        METHOD_HANDLE(null, "MethodHandle", "Ljava/lang/invoke/MethodHandle;") {
+        METHOD_HANDLE(null, "MethodHandle", "Ljava/lang/invoke/MethodHandle;", Kind.METHOD_HANDLE) {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
                 if (!(cpInfo instanceof CONSTANT_MethodHandle_info))
@@ -142,7 +144,7 @@
                         .getNameAndTypeInfo().getType().equals("()Ljava/lang/Object;");
             }
         },
-        METHOD_TYPE(null, "MethodType", "Ljava/lang/invoke/MethodType;") {
+        METHOD_TYPE(null, "MethodType", "Ljava/lang/invoke/MethodType;", Kind.METHOD_TYPE) {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
                 return (cpInfo instanceof CONSTANT_MethodType_info) &&
@@ -154,12 +156,14 @@
         Object value;
         String sourceTypeStr;
         String bytecodeTypeStr;
+        Kind kind;
 
         StaticArgumentKind(Object value, String sourceTypeStr,
-                String bytecodeTypeStr) {
+                String bytecodeTypeStr, Kind kind) {
             this.value = value;
             this.sourceTypeStr = sourceTypeStr;
             this.bytecodeTypeStr = bytecodeTypeStr;
+            this.kind = kind;
         }
 
         abstract boolean check(CPInfo cpInfo) throws Exception;
@@ -450,9 +454,9 @@
             JCIdent ident = (JCIdent)apply.meth;
             Symbol oldSym = ident.sym;
             if (!oldSym.isConstructor()) {
-                Object[] staticArgs = new Object[arity.arity];
+                BootstrapArgument<?>[] staticArgs = new BootstrapArgument<?>[arity.arity];
                 for (int i = 0; i < arity.arity ; i++) {
-                    staticArgs[i] = saks[i].getValue(syms, names, types);
+                    staticArgs[i] = new BootstrapArgument<>(saks[i].kind, saks[i].getValue(syms, names, types));
                 }
                 ident.sym = new Symbol.DynamicMethodSymbol(oldSym.name,
                         oldSym.owner, REF_invokeStatic, bsm, oldSym.type, staticArgs);
--- a/test/tools/javac/valhalla/typespec/items/tests/TestLambda.java	Fri May 29 16:51:55 2015 +0100
+++ b/test/tools/javac/valhalla/typespec/items/tests/TestLambda.java	Fri May 29 18:51:42 2015 +0100
@@ -28,13 +28,17 @@
 	    R apply(A a);
     }
 
+    @BytecodeMapping(opcode=Opcodes.INVOKEDYNAMIC, sig="()LTestLambda$Function<TZ;TZ;>;::{0=(TZ;)TZ;&2=(TZ;)TZ;}")
+    @BytecodeMapping(opcode=Opcodes.INVOKEDYNAMIC, sig="(Z)LTestLambda$Function<TZ;TZ;>;::{0=(TZ;)TZ;&2=(TZ;)TZ;}")
     <any Z> void test(boolean cond) {
 		Function<Z, Z> fzz1 = x -> x;
 		Function<Z, Z> fzz2 = (x) -> { if (cond) { return x; } else { return x; } };
     }
 
     @BytecodeMapping(opcode=Opcodes.ALOAD_2)
+    @BytecodeMapping(opcode=Opcodes.INVOKEDYNAMIC, sig="(TZ;)LTestLambda$Function<TZ;TZ;>;::{0=(TZ;)TZ;&2=(TZ;)TZ;}")
     @BytecodeMapping(opcode=Opcodes.ALOAD_2)
+    @BytecodeMapping(opcode=Opcodes.INVOKEDYNAMIC, sig="(ZTZ;)LTestLambda$Function<TZ;TZ;>;::{0=(TZ;)TZ;&2=(TZ;)TZ;}")
     <any Z> void testCapture(boolean cond, Z z) {
 		Function<Z, Z> fzz1 = x -> z;
 		Function<Z, Z> fzz2 = (x) -> { if (cond) { return z; } else { return z; } };