Merge tag jb8u242-b1644.3

Change-Id: Ia40baedd800ead09fa46d305200843e4e32481fc
diff --git a/src/share/classes/com/sun/tools/javac/code/Symbol.java b/src/share/classes/com/sun/tools/javac/code/Symbol.java
index f84ff83..f9b6b73 100644
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java
+++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java
@@ -1313,9 +1313,6 @@
         /** The parameters of the method. */
         public List<VarSymbol> params = null;
 
-        /** The names of the parameters */
-        public List<Name> savedParameterNames;
-
         /** For an attribute field accessor, its default value if any.
          *  The value is null if none appeared in the method
          *  declaration.
@@ -1551,59 +1548,20 @@
         public List<VarSymbol> params() {
             owner.complete();
             if (params == null) {
-                // If ClassReader.saveParameterNames has been set true, then
-                // savedParameterNames will be set to a list of names that
-                // matches the types in type.getParameterTypes().  If any names
-                // were not found in the class file, those names in the list will
-                // be set to the empty name.
-                // If ClassReader.saveParameterNames has been set false, then
-                // savedParameterNames will be null.
-                List<Name> paramNames = savedParameterNames;
-                savedParameterNames = null;
-                // discard the provided names if the list of names is the wrong size.
-                if (paramNames == null || paramNames.size() != type.getParameterTypes().size()) {
-                    paramNames = List.nil();
-                }
-                ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>();
-                List<Name> remaining = paramNames;
-                // assert: remaining and paramNames are both empty or both
-                // have same cardinality as type.getParameterTypes()
+                ListBuffer<VarSymbol> newParams = new ListBuffer<>();
                 int i = 0;
                 for (Type t : type.getParameterTypes()) {
-                    Name paramName;
-                    if (remaining.isEmpty()) {
-                        // no names for any parameters available
-                        paramName = createArgName(i, paramNames);
-                    } else {
-                        paramName = remaining.head;
-                        remaining = remaining.tail;
-                        if (paramName.isEmpty()) {
-                            // no name for this specific parameter
-                            paramName = createArgName(i, paramNames);
-                        }
-                    }
-                    buf.append(new VarSymbol(PARAMETER, paramName, t, this));
+                    Name paramName = name.table.fromString("arg" + i);
+                    VarSymbol param = new VarSymbol(PARAMETER, paramName, t, this);
+                    newParams.append(param);
                     i++;
                 }
-                params = buf.toList();
+                params = newParams.toList();
             }
+            Assert.checkNonNull(params);
             return params;
         }
 
-        // Create a name for the argument at position 'index' that is not in
-        // the exclude list. In normal use, either no names will have been
-        // provided, in which case the exclude list is empty, or all the names
-        // will have been provided, in which case this method will not be called.
-        private Name createArgName(int index, List<Name> exclude) {
-            String prefix = "arg";
-            while (true) {
-                Name argName = name.table.fromString(prefix + index);
-                if (!exclude.contains(argName))
-                    return argName;
-                prefix += "$";
-            }
-        }
-
         public Symbol asMemberOf(Type site, Types types) {
             return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
         }
diff --git a/src/share/classes/com/sun/tools/javac/code/Types.java b/src/share/classes/com/sun/tools/javac/code/Types.java
index b385f28..fe4cce9 100644
--- a/src/share/classes/com/sun/tools/javac/code/Types.java
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java
@@ -176,6 +176,18 @@
         }
         else return t.unannotatedType();
     }
+
+    /**
+     * Recursively skip type-variables until a class/array type is found; capture conversion is then
+     * (optionally) applied to the resulting type. This is useful for i.e. computing a site that is
+     * suitable for a method lookup.
+     */
+    public Type skipTypeVars(Type site, boolean capture) {
+        while (site.hasTag(TYPEVAR)) {
+            site = site.getUpperBound();
+        }
+        return capture ? capture(site) : site;
+    }
     // </editor-fold>
 
     // <editor-fold defaultstate="collapsed" desc="isUnbounded">
@@ -1810,12 +1822,9 @@
     }
 
     private Type relaxBound(Type t) {
-        if (t.hasTag(TYPEVAR)) {
-            while (t.hasTag(TYPEVAR))
-                t = t.getUpperBound();
-            t = rewriteQuantifiers(t, true, true);
-        }
-        return t;
+        return (t.hasTag(TYPEVAR)) ?
+                rewriteQuantifiers(skipTypeVars(t, false), true, true) :
+                t;
     }
     // </editor-fold>
 
@@ -1896,10 +1905,7 @@
      */
     private Mapping elemTypeFun = new Mapping ("elemTypeFun") {
         public Type apply(Type t) {
-            while (t.hasTag(TYPEVAR)) {
-                t = t.getUpperBound();
-            }
-            return elemtype(t);
+            return elemtype(skipTypeVars(t, false));
         }
     };
 
@@ -2683,8 +2689,7 @@
 
         private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
             for (Type t = origin.type; t.hasTag(CLASS) || t.hasTag(TYPEVAR); t = supertype(t)) {
-                while (t.hasTag(TYPEVAR))
-                    t = t.getUpperBound();
+                t = skipTypeVars(t, false);
                 TypeSymbol c = t.tsym;
                 for (Scope.Entry e = c.members().lookup(ms.name, implFilter);
                      e.scope != null;
diff --git a/src/share/classes/com/sun/tools/javac/comp/Attr.java b/src/share/classes/com/sun/tools/javac/comp/Attr.java
index 96148f0..16babcd 100644
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java
@@ -3288,8 +3288,7 @@
         tree.sym = sym;
 
         if (site.hasTag(TYPEVAR) && !isType(sym) && sym.kind != ERR) {
-            while (site.hasTag(TYPEVAR)) site = site.getUpperBound();
-            site = capture(site);
+            site = types.skipTypeVars(site, true);
         }
 
         // If that symbol is a variable, ...
diff --git a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
index c67715e..17b046c 100644
--- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
+++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
@@ -1336,11 +1336,7 @@
                 site = env.enclClass.sym.type;
             }
 
-            while (site.hasTag(TYPEVAR)) {
-                site = site.getUpperBound();
-            }
-
-            site = types.capture(site);
+            site = types.skipTypeVars(site, true);
 
             List<Type> args = rs.dummyArgs(tree.args.length());
             Name name = TreeInfo.name(tree.meth);
diff --git a/src/share/classes/com/sun/tools/javac/comp/Lower.java b/src/share/classes/com/sun/tools/javac/comp/Lower.java
index 717a316..acfb89a 100644
--- a/src/share/classes/com/sun/tools/javac/comp/Lower.java
+++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java
@@ -3485,10 +3485,7 @@
                                               syms.iterableType.tsym);
             if (iterableType.getTypeArguments().nonEmpty())
                 iteratorTarget = types.erasure(iterableType.getTypeArguments().head);
-            Type eType = tree.expr.type;
-            while (eType.hasTag(TYPEVAR)) {
-                eType = eType.getUpperBound();
-            }
+            Type eType = types.skipTypeVars(tree.expr.type, false);
             tree.expr.type = types.erasure(eType);
             if (eType.isCompound())
                 tree.expr = make.TypeCast(types.erasure(iterableType), tree.expr);
diff --git a/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/share/classes/com/sun/tools/javac/comp/Resolve.java
index 064b3bb..e0ac3ac 100644
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java
@@ -1802,8 +1802,7 @@
                                 !t.hasTag(TYPEVAR)) {
                             return null;
                         }
-                        while (t.hasTag(TYPEVAR))
-                            t = t.getUpperBound();
+                        t = types.skipTypeVars(t, false);
                         if (seen.contains(t.tsym)) {
                             //degenerate case in which we have a circular
                             //class hierarchy - because of ill-formed classfiles
@@ -2779,11 +2778,10 @@
                                   InferenceContext inferenceContext) {
 
         boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names);
-        site = types.capture(site);
 
+        //step 1 - bound lookup
         ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
                 referenceTree, site, name, argtypes, null, VARARITY);
-        //step 1 - bound lookup
         Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
         Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym,
                 arityMethodCheck, boundLookupHelper);
@@ -3182,9 +3180,13 @@
      */
     class MethodReferenceLookupHelper extends ReferenceLookupHelper {
 
+        /** The original method reference lookup site. */
+        Type originalSite;
+
         MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
-            super(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
+            super(referenceTree, name, types.skipTypeVars(site, true), argtypes, typeargtypes, maxPhase);
+            this.originalSite = site;
         }
 
         @Override
@@ -3200,7 +3202,7 @@
                     (argtypes.head.hasTag(NONE) ||
                     types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), site))) {
                 return new UnboundMethodReferenceLookupHelper(referenceTree, name,
-                        site, argtypes, typeargtypes, maxPhase);
+                    originalSite, argtypes, typeargtypes, maxPhase);
             } else {
                 return super.unboundLookup(inferenceContext);
             }
@@ -3233,7 +3235,7 @@
             super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
             if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
                 Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
-                this.site = types.capture(asSuperSite);
+                this.site = types.skipTypeVars(asSuperSite, true);
             }
         }
 
diff --git a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java
index ad00b78..fbbff9c 100644
--- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java
+++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java
@@ -31,6 +31,7 @@
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.List;
@@ -81,6 +82,8 @@
 
     private final CompileStates compileStates;
 
+    private final boolean skipDuplicateBridges;
+
     protected TransTypes(Context context) {
         context.put(transTypesKey, this);
         compileStates = CompileStates.instance(context);
@@ -93,6 +96,7 @@
         allowEnums = source.allowEnums();
         addBridges = source.addBridges();
         allowInterfaceBridges = source.allowDefaultMethods();
+        skipDuplicateBridges = Options.instance(context).getBoolean("skipDuplicateBridges", false);
         types = Types.instance(context);
         make = TreeMaker.instance(context);
         resolve = Resolve.instance(context);
@@ -405,6 +409,9 @@
                                        MethodSymbol impl,
                                        Type dest) {
             if (impl != method) {
+                if (skipBridge(method, impl, dest)) {
+                    return false;
+                }
                 // If either method or impl have different erasures as
                 // members of dest, a bridge is needed.
                 Type method_erasure = method.erasure(types);
@@ -445,6 +452,41 @@
             return types.isSameType(erasure(types.memberType(type, method)),
                                     erasure);
         }
+        /**
+         * Returns true if a bridge should be skipped because we expect it to be declared in
+         * a super-type.
+         *
+         * @param method The symbol for which a bridge might have to be added
+         * @param impl The implementation of method
+         * @param dest The type in which the bridge would go
+         */
+        private boolean skipBridge(MethodSymbol method,
+                                   MethodSymbol impl,
+                                   Type dest) {
+            if (!skipDuplicateBridges) {
+                return false;
+            }
+            if (dest.tsym == impl.owner) {
+                // the method is implemented in the current class; we need to bridge it here
+                return false;
+            }
+            if (!types.isSubtype(
+                    types.erasure(impl.owner.type), types.erasure(method.owner.type))) {
+                // the method is implemented in some supertype that is not a subtype of
+                // the declaring type, so the bridge will not have been created in the
+                // implementing class
+                return false;
+            }
+            if (!impl.overrides(method, (TypeSymbol) impl.owner, types, true)) {
+                // the method is implementing in a supertype that is also a subtype
+                // of the declaring type, but the method's signature in the implementing
+                // class does not override its signature in the declaring class
+                return false;
+            }
+            // we don't need to consider visibility for accessibility bridges, because
+            // that happens on a separate code path
+            return true;
+        }
 
     void addBridges(DiagnosticPosition pos,
                     TypeSymbol i,
@@ -804,9 +846,7 @@
     }
 
     public void visitSelect(JCFieldAccess tree) {
-        Type t = tree.selected.type;
-        while (t.hasTag(TYPEVAR))
-            t = t.getUpperBound();
+        Type t = types.skipTypeVars(tree.selected.type, false);
         if (t.isCompound()) {
             if ((tree.sym.flags() & IPROXY) != 0) {
                 tree.sym = ((MethodSymbol)tree.sym).
@@ -833,7 +873,14 @@
     }
 
     public void visitReference(JCMemberReference tree) {
-        tree.expr = translate(tree.expr, erasure(tree.expr.type));
+        Type t = types.skipTypeVars(tree.expr.type, false);
+        Type receiverTarget = t.isCompound() ? erasure(tree.sym.owner.type) : erasure(t);
+        if (tree.kind == ReferenceKind.UNBOUND) {
+            tree.expr = make.Type(receiverTarget);
+        } else {
+            tree.expr = translate(tree.expr, receiverTarget);
+        }
+
         tree.type = erasure(tree.type);
         if (tree.varargsElement != null)
             tree.varargsElement = erasure(tree.varargsElement);
diff --git a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
index 4024892..2e2de79 100644
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
@@ -215,6 +215,26 @@
     int[] parameterNameIndices;
 
     /**
+     * A table to hold annotations for method parameters.
+     */
+    ParameterAnnotations[] parameterAnnotations;
+
+    /**
+     * A holder for parameter annotations.
+     */
+    static class ParameterAnnotations {
+        List<CompoundAnnotationProxy> proxies;
+
+        void add(List<CompoundAnnotationProxy> newAnnotations) {
+            if (proxies == null) {
+                proxies = newAnnotations;
+            } else {
+                proxies = proxies.prependList(newAnnotations);
+            }
+        }
+    }
+
+    /**
      * Whether or not any parameter names have been found.
      */
     boolean haveParameterNameIndices;
@@ -1086,10 +1106,14 @@
                         int numEntries = nextByte();
                         parameterNameIndices = new int[numEntries];
                         haveParameterNameIndices = true;
+                        int index = 0;
                         for (int i = 0; i < numEntries; i++) {
                             int nameIndex = nextChar();
                             int flags = nextChar();
-                            parameterNameIndices[i] = nameIndex;
+                            if ((flags & (Flags.MANDATED | Flags.SYNTHETIC)) != 0) {
+                                continue;
+                            }
+                            parameterNameIndices[index++] = nameIndex;
                         }
                     }
                     bp = newbp;
@@ -1180,7 +1204,7 @@
 
             new AttributeReader(names.RuntimeInvisibleParameterAnnotations, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
                 protected void read(Symbol sym, int attrLen) {
-                    attachParameterAnnotations(sym);
+                    readParameterAnnotations(sym);
                 }
             },
 
@@ -1192,7 +1216,7 @@
 
             new AttributeReader(names.RuntimeVisibleParameterAnnotations, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
                 protected void read(Symbol sym, int attrLen) {
-                    attachParameterAnnotations(sym);
+                    readParameterAnnotations(sym);
                 }
             },
 
@@ -1413,50 +1437,67 @@
  * Reading Java-language annotations
  ***********************************************************************/
 
+    /**
+     * Save annotations.
+     */
+    List<CompoundAnnotationProxy> readAnnotations() {
+        int numAttributes = nextChar();
+        ListBuffer<CompoundAnnotationProxy> annotations = new ListBuffer<>();
+        for (int i = 0; i < numAttributes; i++) {
+            annotations.append(readCompoundAnnotation());
+        }
+        return annotations.toList();
+    }
+
     /** Attach annotations.
      */
     void attachAnnotations(final Symbol sym) {
-        int numAttributes = nextChar();
-        if (numAttributes != 0) {
-            ListBuffer<CompoundAnnotationProxy> proxies =
-                new ListBuffer<CompoundAnnotationProxy>();
-            for (int i = 0; i<numAttributes; i++) {
-                CompoundAnnotationProxy proxy = readCompoundAnnotation();
-                if (proxy.type.tsym == syms.proprietaryType.tsym)
-                    sym.flags_field |= PROPRIETARY;
-                else if (proxy.type.tsym == syms.profileType.tsym) {
-                    if (profile != Profile.DEFAULT) {
-                        for (Pair<Name,Attribute> v: proxy.values) {
-                            if (v.fst == names.value && v.snd instanceof Attribute.Constant) {
-                                Attribute.Constant c = (Attribute.Constant) v.snd;
-                                if (c.type == syms.intType && ((Integer) c.value) > profile.value) {
-                                    sym.flags_field |= NOT_IN_PROFILE;
-                                }
+        attachAnnotations(sym, readAnnotations());
+    }
+
+    /**
+     * Attach annotations.
+     */
+    void attachAnnotations(final Symbol sym, List<CompoundAnnotationProxy> annotations) {
+        if (annotations.isEmpty()) {
+            return;
+        }
+        ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
+        for (CompoundAnnotationProxy proxy : annotations) {
+            if (proxy.type.tsym == syms.proprietaryType.tsym)
+                sym.flags_field |= PROPRIETARY;
+            else if (proxy.type.tsym == syms.profileType.tsym) {
+                if (profile != Profile.DEFAULT) {
+                    for (Pair<Name, Attribute> v : proxy.values) {
+                        if (v.fst == names.value && v.snd instanceof Attribute.Constant) {
+                            Attribute.Constant c = (Attribute.Constant)v.snd;
+                            if (c.type == syms.intType && ((Integer)c.value) > profile.value) {
+                                sym.flags_field |= NOT_IN_PROFILE;
                             }
                         }
                     }
-                } else
-                    proxies.append(proxy);
-            }
-            annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
+                }
+            } else
+                proxies.append(proxy);
         }
+        annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
     }
 
-    /** Attach parameter annotations.
+    /** Read parameter annotations.
      */
-    void attachParameterAnnotations(final Symbol method) {
-        final MethodSymbol meth = (MethodSymbol)method;
+    void readParameterAnnotations(Symbol meth) {
         int numParameters = buf[bp++] & 0xFF;
-        List<VarSymbol> parameters = meth.params();
-        int pnum = 0;
-        while (parameters.tail != null) {
-            attachAnnotations(parameters.head);
-            parameters = parameters.tail;
-            pnum++;
-        }
-        if (pnum != numParameters) {
+        if (parameterAnnotations == null) {
+            parameterAnnotations = new ParameterAnnotations[numParameters];
+        } else if (parameterAnnotations.length != numParameters) {
             throw badClassFile("bad.runtime.invisible.param.annotations", meth);
         }
+        for (int pnum = 0; pnum < numParameters; pnum++) {
+            if (parameterAnnotations[pnum] == null) {
+                parameterAnnotations[pnum] = new ParameterAnnotations();
+            }
+            parameterAnnotations[pnum].add(readAnnotations());
+        }
     }
 
     void attachTypeAnnotations(final Symbol sym) {
@@ -2046,7 +2087,11 @@
             currentOwner = prevOwner;
         }
         if (saveParameterNames)
-            setParameterNames(m, type);
+            setParameters(m, type);
+        // clean parameter annotations and names between methods
+        parameterAnnotations = null;
+        parameterNameIndices = null;
+
         return m;
     }
 
@@ -2090,22 +2135,17 @@
     }
 
     /**
-     * Set the parameter names for a symbol from the name index in the
-     * parameterNameIndicies array. The type of the symbol may have changed
-     * while reading the method attributes (see the Signature attribute).
-     * This may be because of generic information or because anonymous
-     * synthetic parameters were added.   The original type (as read from
-     * the method descriptor) is used to help guess the existence of
+     * Set the parameters for a method symbol, including any names and
+     * annotations that were read.
+     *
+     * <p>The type of the symbol may have changed while reading the
+     * method attributes (see the Signature attribute). This may be
+     * because of generic information or because anonymous synthetic
+     * parameters were added.   The original type (as read from the
+     * method descriptor) is used to help guess the existence of
      * anonymous synthetic parameters.
-     * On completion, sym.savedParameter names will either be null (if
-     * no parameter names were found in the class file) or will be set to a
-     * list of names, one per entry in sym.type.getParameterTypes, with
-     * any missing names represented by the empty name.
      */
-    void setParameterNames(MethodSymbol sym, Type jvmType) {
-        // if no names were found in the class file, there's nothing more to do
-        if (!haveParameterNameIndices)
-            return;
+    void setParameters(MethodSymbol sym, Type jvmType) {
         // If we get parameter names from MethodParameters, then we
         // don't need to skip.
         int firstParam = 0;
@@ -2116,40 +2156,73 @@
             // make a corresponding allowance here for the position of
             // the first parameter.  Note that this assumes the
             // skipped parameter has a width of 1 -- i.e. it is not
-        // a double width type (long or double.)
-        if (sym.name == names.init && currentOwner.hasOuterInstance()) {
-            // Sometimes anonymous classes don't have an outer
-            // instance, however, there is no reliable way to tell so
-            // we never strip this$n
-            if (!currentOwner.name.isEmpty())
-                firstParam += 1;
-        }
+            // a double width type (long or double.)
 
-        if (sym.type != jvmType) {
-                // reading the method attributes has caused the
-                // symbol's type to be changed. (i.e. the Signature
-                // attribute.)  This may happen if there are hidden
-                // (synthetic) parameters in the descriptor, but not
-                // in the Signature.  The position of these hidden
-                // parameters is unspecified; for now, assume they are
-                // at the beginning, and so skip over them. The
-                // primary case for this is two hidden parameters
-                // passed into Enum constructors.
-            int skip = Code.width(jvmType.getParameterTypes())
-                    - Code.width(sym.type.getParameterTypes());
-            firstParam += skip;
-        }
+            if (sym.name == names.init && currentOwner.hasOuterInstance()) {
+                // Sometimes anonymous classes don't have an outer
+                // instance, however, there is no reliable way to tell so
+                // we never strip this$n
+                if (!currentOwner.name.isEmpty())
+                    firstParam += 1;
+            }
+
+            if (sym.type != jvmType) {
+                    // reading the method attributes has caused the
+                    // symbol's type to be changed. (i.e. the Signature
+                    // attribute.)  This may happen if there are hidden
+                    // (synthetic) parameters in the descriptor, but not
+                    // in the Signature.  The position of these hidden
+                    // parameters is unspecified; for now, assume they are
+                    // at the beginning, and so skip over them. The
+                    // primary case for this is two hidden parameters
+                    // passed into Enum constructors.
+                int skip = Code.width(jvmType.getParameterTypes())
+                        - Code.width(sym.type.getParameterTypes());
+                firstParam += skip;
+            }
         }
         List<Name> paramNames = List.nil();
-        int index = firstParam;
+        ListBuffer<VarSymbol> params = new ListBuffer<>();
+        int nameIndex = firstParam;
+        int annotationIndex = 0;
         for (Type t: sym.type.getParameterTypes()) {
-            int nameIdx = (index < parameterNameIndices.length
-                    ? parameterNameIndices[index] : 0);
-            Name name = nameIdx == 0 ? names.empty : readName(nameIdx);
+            Name name = parameterName(nameIndex, paramNames);
             paramNames = paramNames.prepend(name);
-            index += Code.width(t);
+            VarSymbol param = new VarSymbol(PARAMETER, name, t, sym);
+            params.append(param);
+            if (parameterAnnotations != null) {
+                ParameterAnnotations annotations = parameterAnnotations[annotationIndex];
+                if (annotations != null && annotations.proxies != null
+                        && !annotations.proxies.isEmpty()) {
+                    annotate.normal(new AnnotationCompleter(param, annotations.proxies));
+                }
+            }
+            nameIndex += sawMethodParameters ? 1 : Code.width(t);
+            annotationIndex++;
         }
-        sym.savedParameterNames = paramNames.reverse();
+        if (parameterAnnotations != null && parameterAnnotations.length != annotationIndex) {
+            throw badClassFile("bad.runtime.invisible.param.annotations", sym);
+        }
+        Assert.checkNull(sym.params);
+        sym.params = params.toList();
+    }
+
+
+    // Returns the name for the parameter at position 'index', either using
+    // names read from the MethodParameters, or by synthesizing a name that
+    // is not on the 'exclude' list.
+    private Name parameterName(int index, List<Name> exclude) {
+        if (parameterNameIndices != null && index < parameterNameIndices.length
+                && parameterNameIndices[index] != 0) {
+            return readName(parameterNameIndices[index]);
+        }
+        String prefix = "arg";
+        while (true) {
+            Name argName = names.fromString(prefix + exclude.size());
+            if (!exclude.contains(argName))
+                return argName;
+            prefix += "$";
+        }
     }
 
     /**
diff --git a/test/tools/javac/lambda/8073842/T8073842.java b/test/tools/javac/lambda/8073842/T8073842.java
new file mode 100644
index 0000000..f2dde5c
--- /dev/null
+++ b/test/tools/javac/lambda/8073842/T8073842.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/*
+ * @test
+ * @bug 8073842
+ * @summary Invalid method reference when referencing a method on a wildcard type
+ * @compile T8073842.java
+ */
+
+import java.util.stream.Stream;
+
+class T8073842 {
+
+    static class Chunck {
+        public void work() { }
+    }
+
+    void test(Stream<? extends Chunck> s) {
+        Stream<Runnable> r = s.map(o -> o::work);
+    }
+}
\ No newline at end of file
diff --git a/test/tools/javac/lambda/methodReference/IntersectionTypeReceiverTest2.java b/test/tools/javac/lambda/methodReference/IntersectionTypeReceiverTest2.java
new file mode 100644
index 0000000..e02763b
--- /dev/null
+++ b/test/tools/javac/lambda/methodReference/IntersectionTypeReceiverTest2.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8142476
+ * @summary Test that Call site initialization exception is not thrown when the method
+   reference receiver is of intersection type.
+ * @run main IntersectionTypeReceiverTest2
+ */
+
+public class IntersectionTypeReceiverTest2 {
+    interface I {
+    }
+
+    interface J {
+        void foo();
+    }
+
+    static <T extends I & J> void bar(T t) {
+        Runnable r = t::foo;
+    }
+
+    public static void main(String[] args) {
+        class A implements I, J {
+            public void foo() {
+            }
+        }
+        bar(new A());
+    }
+}
\ No newline at end of file