Merge
authorjjg
Tue, 22 Oct 2013 17:44:43 -0700
changeset 21491 129a6c9f0f2b
parent 21490 b839b14fe4eb (current diff)
parent 21489 018e34d4045f (diff)
child 21492 e7c8a164d7bd
Merge
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Tue Oct 22 17:42:10 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Tue Oct 22 17:44:43 2013 -0700
@@ -30,7 +30,6 @@
 import com.sun.tools.javac.tree.TreeMaker;
 import com.sun.tools.javac.tree.TreeTranslator;
 import com.sun.tools.javac.code.Attribute;
-import com.sun.tools.javac.code.Flags;
 import com.sun.tools.javac.code.Kinds;
 import com.sun.tools.javac.code.Scope;
 import com.sun.tools.javac.code.Symbol;
@@ -576,10 +575,10 @@
             DiagnosticPosition pos, List<Object> staticArgs, MethodType indyType) {
         String functionalInterfaceClass = classSig(targetType);
         String functionalInterfaceMethodName = samSym.getSimpleName().toString();
-        String functionalInterfaceMethodSignature = methodSig(types.erasure(samSym.type));
+        String functionalInterfaceMethodSignature = typeSig(types.erasure(samSym.type));
         String implClass = classSig(types.erasure(refSym.owner.type));
         String implMethodName = refSym.getQualifiedName().toString();
-        String implMethodSignature = methodSig(types.erasure(refSym.type));
+        String implMethodSignature = typeSig(types.erasure(refSym.type));
 
         JCExpression kindTest = eqTest(syms.intType, deserGetter("getImplMethodKind", syms.intType), make.Literal(implMethodKind));
         ListBuffer<JCExpression> serArgs = new ListBuffer<>();
@@ -1087,8 +1086,21 @@
          * keep the count of lambda expression defined in given context (used to
          * generate unambiguous names for serializable lambdas)
          */
-        private Map<String, Integer> serializableLambdaCounts =
-                new HashMap<String, Integer>();
+        private class SyntheticMethodNameCounter {
+            private Map<String, Integer> map = new HashMap<>();
+            int getIndex(StringBuilder buf) {
+                String temp = buf.toString();
+                Integer count = map.get(temp);
+                if (count == null) {
+                    count = 0;
+                }
+                ++count;
+                map.put(temp, count);
+                return count;
+            }
+        }
+        private SyntheticMethodNameCounter syntheticMethodNameCounts =
+                new SyntheticMethodNameCounter();
 
         private Map<Symbol, JCClassDecl> localClassDefs;
 
@@ -1122,13 +1134,13 @@
         @Override
         public void visitClassDef(JCClassDecl tree) {
             List<Frame> prevStack = frameStack;
-            Map<String, Integer> prevSerializableLambdaCount =
-                    serializableLambdaCounts;
+            SyntheticMethodNameCounter prevSyntheticMethodNameCounts =
+                    syntheticMethodNameCounts;
             Map<ClassSymbol, Symbol> prevClinits = clinits;
             DiagnosticSource prevSource = log.currentSource();
             try {
                 log.useSource(tree.sym.sourcefile);
-                serializableLambdaCounts = new HashMap<String, Integer>();
+                syntheticMethodNameCounts = new SyntheticMethodNameCounter();
                 prevClinits = new HashMap<ClassSymbol, Symbol>();
                 if (tree.sym.owner.kind == MTH) {
                     localClassDefs.put(tree.sym, tree);
@@ -1154,7 +1166,7 @@
             finally {
                 log.useSource(prevSource.getFile());
                 frameStack = prevStack;
-                serializableLambdaCounts = prevSerializableLambdaCount;
+                syntheticMethodNameCounts = prevSyntheticMethodNameCounts;
                 clinits = prevClinits;
             }
         }
@@ -1379,50 +1391,6 @@
             }
         }
 
-        private Name lambdaName() {
-            return names.lambda.append(names.fromString("" + lambdaCount++));
-        }
-
-        /**
-         * For a serializable lambda, generate a name which maximizes name
-         * stability across deserialization.
-         * @param owner
-         * @return Name to use for the synthetic lambda method name
-         */
-        private Name serializedLambdaName(Symbol owner) {
-            StringBuilder buf = new StringBuilder();
-            buf.append(names.lambda);
-            // Append the name of the method enclosing the lambda.
-            String methodName = owner.name.toString();
-            if (methodName.equals("<clinit>"))
-                methodName = "static";
-            else if (methodName.equals("<init>"))
-                methodName = "new";
-            buf.append(methodName);
-            buf.append('$');
-            // Append a hash of the enclosing method signature to differentiate
-            // overloaded enclosing methods.  For lambdas enclosed in lambdas,
-            // the generated lambda method will not have type yet, but the
-            // enclosing method's name will have been generated with this same
-            // method, so it will be unique and never be overloaded.
-            Assert.check(owner.type != null || directlyEnclosingLambda() != null);
-            if (owner.type != null) {
-                int methTypeHash = methodSig(owner.type).hashCode();
-                buf.append(Integer.toHexString(methTypeHash));
-            }
-            buf.append('$');
-            // The above appended name components may not be unique, append a
-            // count based on the above name components.
-            String temp = buf.toString();
-            Integer count = serializableLambdaCounts.get(temp);
-            if (count == null) {
-                count = 0;
-            }
-            buf.append(count++);
-            serializableLambdaCounts.put(temp, count);
-            return names.fromString(buf.toString());
-        }
-
         /**
          * Return a valid owner given the current declaration stack
          * (required to skip synthetic lambda symbols)
@@ -1639,19 +1607,19 @@
         private abstract class TranslationContext<T extends JCFunctionalExpression> {
 
             /** the underlying (untranslated) tree */
-            T tree;
+            final T tree;
 
             /** points to the adjusted enclosing scope in which this lambda/mref expression occurs */
-            Symbol owner;
+            final Symbol owner;
 
             /** the depth of this lambda expression in the frame stack */
-            int depth;
+            final int depth;
 
             /** the enclosing translation context (set for nested lambdas/mref) */
-            TranslationContext<?> prev;
+            final TranslationContext<?> prev;
 
             /** list of methods to be bridged by the meta-factory */
-            List<Symbol> bridges;
+            final List<Symbol> bridges;
 
             TranslationContext(T tree) {
                 this.tree = tree;
@@ -1679,6 +1647,31 @@
                 }
                 return false;
             }
+
+            /**
+             * @return Name of the enclosing method to be folded into synthetic
+             * method name
+             */
+            String enclosingMethodName() {
+                return syntheticMethodNameComponent(owner.name);
+            }
+
+            /**
+             * @return Method name in a form that can be folded into a
+             * component of a synthetic method name
+             */
+            String syntheticMethodNameComponent(Name name) {
+                if (name == null) {
+                    return "null";
+                }
+                String methodName = name.toString();
+                if (methodName.equals("<clinit>")) {
+                    methodName = "static";
+                } else if (methodName.equals("<init>")) {
+                    methodName = "new";
+                }
+                return methodName;
+            }
         }
 
         /**
@@ -1690,7 +1683,10 @@
         private class LambdaTranslationContext extends TranslationContext<JCLambda> {
 
             /** variable in the enclosing context to which this lambda is assigned */
-            Symbol self;
+            final Symbol self;
+
+            /** variable in the enclosing context to which this lambda is assigned */
+            final Symbol assignedTo;
 
             Map<LambdaSymbolKind, Map<Symbol, Symbol>> translatedSymbols;
 
@@ -1702,11 +1698,22 @@
             LambdaTranslationContext(JCLambda tree) {
                 super(tree);
                 Frame frame = frameStack.head;
-                if (frame.tree.hasTag(VARDEF)) {
-                    self = ((JCVariableDecl)frame.tree).sym;
-                }
-                Name name = isSerializable() ? serializedLambdaName(owner) : lambdaName();
-                this.translatedSym = makePrivateSyntheticMethod(0, name, null, owner.enclClass());
+                switch (frame.tree.getTag()) {
+                    case VARDEF:
+                        assignedTo = self = ((JCVariableDecl) frame.tree).sym;
+                        break;
+                    case ASSIGN:
+                        self = null;
+                        assignedTo = TreeInfo.symbol(((JCAssign) frame.tree).getVariable());
+                        break;
+                    default:
+                        assignedTo = self = null;
+                        break;
+                 }
+
+                // This symbol will be filled-in in complete
+                this.translatedSym = makePrivateSyntheticMethod(0, null, null, owner.enclClass());
+
                 if (dumpLambdaToMethodStats) {
                     log.note(tree, "lambda.stat", needsAltMetafactory(), translatedSym);
                 }
@@ -1719,6 +1726,84 @@
                 translatedSymbols.put(TYPE_VAR, new LinkedHashMap<Symbol, Symbol>());
             }
 
+             /**
+             * For a serializable lambda, generate a disambiguating string
+             * which maximizes stability across deserialization.
+             *
+             * @return String to differentiate synthetic lambda method names
+             */
+            private String serializedLambdaDisambiguation() {
+                StringBuilder buf = new StringBuilder();
+                // Append the enclosing method signature to differentiate
+                // overloaded enclosing methods.  For lambdas enclosed in
+                // lambdas, the generated lambda method will not have type yet,
+                // but the enclosing method's name will have been generated
+                // with this same method, so it will be unique and never be
+                // overloaded.
+                Assert.check(
+                        owner.type != null ||
+                        directlyEnclosingLambda() != null);
+                if (owner.type != null) {
+                    buf.append(typeSig(owner.type));
+                    buf.append(":");
+                }
+
+                // Add target type info
+                buf.append(types.findDescriptorSymbol(tree.type.tsym).owner.flatName());
+                buf.append(" ");
+
+                // Add variable assigned to
+                if (assignedTo != null) {
+                    buf.append(assignedTo.flatName());
+                    buf.append("=");
+                }
+                //add captured locals info: type, name, order
+                for (Symbol fv : getSymbolMap(CAPTURED_VAR).keySet()) {
+                    if (fv != self) {
+                        buf.append(typeSig(fv.type));
+                        buf.append(" ");
+                        buf.append(fv.flatName());
+                        buf.append(",");
+                    }
+                }
+
+                return buf.toString();
+            }
+
+            /**
+             * For a non-serializable lambda, generate a simple method.
+             *
+             * @return Name to use for the synthetic lambda method name
+             */
+            private Name lambdaName() {
+                return names.lambda.append(names.fromString(enclosingMethodName() + "$" + lambdaCount++));
+            }
+
+            /**
+             * For a serializable lambda, generate a method name which maximizes
+             * name stability across deserialization.
+             *
+             * @return Name to use for the synthetic lambda method name
+             */
+            private Name serializedLambdaName() {
+                StringBuilder buf = new StringBuilder();
+                buf.append(names.lambda);
+                // Append the name of the method enclosing the lambda.
+                buf.append(enclosingMethodName());
+                buf.append('$');
+                // Append a hash of the disambiguating string : enclosing method
+                // signature, etc.
+                String disam = serializedLambdaDisambiguation();
+                buf.append(Integer.toHexString(disam.hashCode()));
+                buf.append('$');
+                // The above appended name components may not be unique, append
+                // a count based on the above name components.
+                buf.append(syntheticMethodNameCounts.getIndex(buf));
+                String result = buf.toString();
+                //System.err.printf("serializedLambdaName: %s -- %s\n", result, disam);
+                return names.fromString(result);
+            }
+
             /**
              * Translate a symbol of a given kind into something suitable for the
              * synthetic lambda body
@@ -1847,6 +1932,11 @@
                 }
                 syntheticParams = params.toList();
 
+                // Compute and set the lambda name
+                translatedSym.name = isSerializable()
+                        ? serializedLambdaName()
+                        : lambdaName();
+
                 //prepend synthetic args to translated lambda method signature
                 translatedSym.type = types.createMethodTypeWithParameters(
                         generatedLambdaSig(),
@@ -1874,7 +1964,7 @@
                 this.isSuper = tree.hasKind(ReferenceKind.SUPER);
                 this.bridgeSym = needsBridge()
                         ? makePrivateSyntheticMethod(isSuper ? 0 : STATIC,
-                                              lambdaName().append(names.fromString("$bridge")), null,
+                                              referenceBridgeName(), null,
                                               owner.enclClass())
                         : null;
                 if (dumpLambdaToMethodStats) {
@@ -1888,7 +1978,9 @@
              * Get the opcode associated with this method reference
              */
             int referenceKind() {
-                return LambdaToMethod.this.referenceKind(needsBridge() ? bridgeSym : tree.sym);
+                return LambdaToMethod.this.referenceKind(needsBridge()
+                        ? bridgeSym
+                        : tree.sym);
             }
 
             boolean needsVarArgsConversion() {
@@ -1896,6 +1988,62 @@
             }
 
             /**
+             * Generate a disambiguating string to increase stability (important
+             * if serialized)
+             *
+             * @return String to differentiate synthetic lambda method names
+             */
+            private String referenceBridgeDisambiguation() {
+                StringBuilder buf = new StringBuilder();
+                // Append the enclosing method signature to differentiate
+                // overloaded enclosing methods.
+                if (owner.type != null) {
+                    buf.append(typeSig(owner.type));
+                    buf.append(":");
+                }
+
+                // Append qualifier type
+                buf.append(classSig(tree.sym.owner.type));
+
+                // Note static/instance
+                buf.append(tree.sym.isStatic()? " S " : " I ");
+
+                // Append referenced signature
+                buf.append(typeSig(tree.sym.erasure(types)));
+
+                return buf.toString();
+            }
+
+            /**
+             * Construct a unique stable name for the method reference bridge
+             *
+             * @return Name to use for the synthetic method name
+             */
+            private Name referenceBridgeName() {
+                StringBuilder buf = new StringBuilder();
+                // Append lambda ID, this is semantically significant
+                buf.append(names.lambda);
+                // Note that it is a method reference bridge
+                buf.append("MR$");
+                // Append the enclosing method name
+                buf.append(enclosingMethodName());
+                buf.append('$');
+                // Append the referenced method name
+                buf.append(syntheticMethodNameComponent(tree.sym.name));
+                buf.append('$');
+                // Append a hash of the disambiguating string : enclosing method
+                // signature, etc.
+                String disam = referenceBridgeDisambiguation();
+                buf.append(Integer.toHexString(disam.hashCode()));
+                buf.append('$');
+                // The above appended name components may not be unique, append
+                // a count based on the above name components.
+                buf.append(syntheticMethodNameCounts.getIndex(buf));
+                String result = buf.toString();
+                return names.fromString(result);
+            }
+
+            /**
              * @return Is this an array operation like clone()
              */
             boolean isArrayOp() {
@@ -1954,7 +2102,7 @@
      * ****************************************************************
      */
 
-    private String methodSig(Type type) {
+    private String typeSig(Type type) {
         L2MSignatureGenerator sg = new L2MSignatureGenerator();
         sg.assembleSig(type);
         return sg.toString();
--- a/langtools/test/tools/javac/MethodParameters/LambdaTest.out	Tue Oct 22 17:42:10 2013 -0700
+++ b/langtools/test/tools/javac/MethodParameters/LambdaTest.out	Tue Oct 22 17:44:43 2013 -0700
@@ -1,7 +1,7 @@
 class LambdaTest -- 
 LambdaTest.<init>()
 LambdaTest.foo(i)
-LambdaTest.lambda$1(arg0, arg1)/*synthetic*/
-LambdaTest.lambda$0(arg0)/*synthetic*/
+LambdaTest.lambda$static$1(arg0)/*synthetic*/
+LambdaTest.lambda$null$0(arg0, arg1)/*synthetic*/
 static interface LambdaTest$I -- inner
-LambdaTest$I.m(x)
\ No newline at end of file
+LambdaTest$I.m(x)
--- a/langtools/test/tools/javac/T8019486/WrongLVTForLambdaTest.java	Tue Oct 22 17:42:10 2013 -0700
+++ b/langtools/test/tools/javac/T8019486/WrongLVTForLambdaTest.java	Tue Oct 22 17:44:43 2013 -0700
@@ -61,8 +61,6 @@
         {9,           0},       //number -> number / 1
     };
 
-    static final String methodToLookFor = "lambda$0";
-
     public static void main(String[] args) throws Exception {
         new WrongLVTForLambdaTest().run();
     }
@@ -70,7 +68,7 @@
     void run() throws Exception {
         compileTestClass();
         checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
-                "Foo.class").toUri()), methodToLookFor);
+                "Foo.class").toUri()));
     }
 
     void compileTestClass() throws Exception {
@@ -79,12 +77,12 @@
         ToolBox.javac(javacSuccessArgs);
     }
 
-    void checkClassFile(final File cfile, String methodToFind) throws Exception {
+    void checkClassFile(final File cfile) throws Exception {
         ClassFile classFile = ClassFile.read(cfile);
-        boolean methodFound = false;
+        int methodsFound = 0;
         for (Method method : classFile.methods) {
-            if (method.getName(classFile.constant_pool).equals(methodToFind)) {
-                methodFound = true;
+            if (method.getName(classFile.constant_pool).startsWith("lambda$")) {
+                ++methodsFound;
                 Code_attribute code = (Code_attribute) method.attributes.get("Code");
                 LineNumberTable_attribute lnt =
                         (LineNumberTable_attribute) code.attributes.get("LineNumberTable");
@@ -101,7 +99,7 @@
                 }
             }
         }
-        Assert.check(methodFound, "The seek method was not found");
+        Assert.check(methodsFound == 1, "Expected to find one lambda method, found " + methodsFound);
     }
 
     void error(String msg) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaNaming/TestSerializedLambdaNameStability.java	Tue Oct 22 17:44:43 2013 -0700
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2013, 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 8023668
+ * @summary Desugar serializable lambda bodies using more robust naming scheme
+ * @library /tools/javac/lib
+ * @build ToolBox
+ * @run main TestSerializedLambdaNameStability
+ */
+
+import java.io.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.file.*;
+
+public class TestSerializedLambdaNameStability {
+
+    final ClassLoader writingClassLoader;
+    final ClassLoader clonedClassLoader;
+    final ClassLoader checkingClassLoader;
+
+    TestSerializedLambdaNameStability()  {
+        writingClassLoader = new TestClassLoader("before");
+        clonedClassLoader = new TestClassLoader("before");
+        checkingClassLoader = new TestClassLoader("after");
+    }
+
+    public static void main(String... args) throws Exception {
+        new TestSerializedLambdaNameStability().doit("NameOfCapturedArgs", true);
+        new TestSerializedLambdaNameStability().doit("TypesOfCapturedArgs", true);
+        new TestSerializedLambdaNameStability().doit("OrderOfCapturedArgs", true);
+        new TestSerializedLambdaNameStability().doit("VariableAssignmentTarget", false);
+        new TestSerializedLambdaNameStability().doit("TargetName", true);
+        new TestSerializedLambdaNameStability().doit("TargetType", true);
+    }
+
+    public void doit(String name, boolean expectFail) throws Exception {
+        String iName = "I" + name;
+        String testName = "TEST" + name;
+        Class<?> kw = writingClassLoader.loadClass(testName);
+        Object instw = getInstance(kw);
+        Method mw = getMethod(kw, "write", ObjectOutput.class);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (ObjectOutput out = new ObjectOutputStream(baos)) {
+            mw.invoke(instw, out);
+        }
+        byte[] ser = baos.toByteArray();
+
+        // Read and check clone
+        readCheck(iName, testName, clonedClassLoader, ser);
+        System.err.printf("cloned test readCheck %s\n", testName);
+
+        // Read and check other
+        if (expectFail) {
+            try {
+                readCheck(iName, testName, checkingClassLoader, ser);
+            } catch (InvocationTargetException ite) {
+                Throwable underlying = ite;
+                while (underlying != null && !(underlying instanceof IllegalArgumentException)) {
+                    underlying = underlying.getCause();
+                }
+                if (underlying != null) {
+                    if (underlying.getMessage().contains("deserialization")) {
+                        System.err.printf("PASS: other test %s got expected exception %s\n", testName, underlying);
+                        return;
+                    }
+                }
+                System.err.printf("FAIL: other test %s got unexpected exception %s\n", testName, ite);
+                throw new Exception("unexpected exception ", ite);
+            }
+            System.err.printf("FAIL: other test %s expected an exception", testName);
+            throw new Exception("expected an exception" + testName);
+        } else {
+            readCheck(iName, testName, checkingClassLoader, ser);
+            System.err.printf("PASS: other test %s readCheck\n", testName);
+        }
+    }
+
+    void readCheck(String iName, String testName, ClassLoader loader, byte[] ser) throws Exception {
+        Class<?> k = loader.loadClass(testName);
+        Object inst = getInstance(k);
+        Method mrc = getMethod(k, "readCheck", ObjectInput.class);
+        ByteArrayInputStream bais = new ByteArrayInputStream(ser);
+        try (ObjectInput in = new ObjectInputStream(bais)) {
+            mrc.invoke(inst, in);
+        }
+    }
+
+    Method getMethod(Class<?> k, String name, Class<?> argTypes) throws Exception {
+        Method meth = k.getDeclaredMethod(name, argTypes);
+        meth.setAccessible(true);
+        return meth;
+    }
+
+    Object getInstance(Class<?> k) throws Exception {
+        Constructor<?> cons = k.getConstructors()[0];
+        cons.setAccessible(true);
+        return cons.newInstance();
+    }
+
+    static class TestClassLoader extends ClassLoader  {
+        static final String compiledDir = System.getProperty("user.dir");
+        static final String sourceBaseDir = System.getProperty("test.src");
+
+        final String context;
+
+        public TestClassLoader(String context) {
+            super();
+            this.context = context;
+        }
+
+        @Override
+        public Class findClass(String name) throws ClassNotFoundException {
+            byte[] b;
+
+            try {
+                b = loadClassData(name);
+            } catch (Throwable th) {
+                // th.printStackTrace();
+                throw new ClassNotFoundException("Loading error", th);
+            }
+            return defineClass(name, b, 0, b.length);
+        }
+
+        private byte[] loadClassData(String name) throws Exception {
+            String srcName;
+            if (name.startsWith("TEST"))
+                srcName = name;
+            else if (name.startsWith("I"))
+                srcName = "TEST" + name.substring(1);
+            else
+                throw new Exception("Did not expect to load " + name);
+            Path srcFile = Paths.get(sourceBaseDir, context, srcName + ".java");
+            String testSource = new String(Files.readAllBytes(srcFile));
+            ToolBox.JavaToolArgs javacSuccessArgs =
+                    new ToolBox.JavaToolArgs().setSources(testSource);
+            ToolBox.javac(javacSuccessArgs);
+            Path cfFile = Paths.get(compiledDir, name + ".class");
+            byte[] bytes = Files.readAllBytes(cfFile);
+            return bytes;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaNaming/after/TESTNameOfCapturedArgs.java	Tue Oct 22 17:44:43 2013 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.io.*;
+
+interface INameOfCapturedArgs extends Serializable {
+    int get();
+}
+
+class TESTNameOfCapturedArgs {
+
+    public TESTNameOfCapturedArgs() {
+    }
+
+    public void write(ObjectOutput out) throws IOException {
+        int y = 44;
+        INameOfCapturedArgs res = () -> y;
+        out.writeObject(res);
+    }
+
+    public void readCheck(ObjectInput in) throws Exception {
+        INameOfCapturedArgs lam = (INameOfCapturedArgs) in.readObject();
+        int val = lam.get();
+        if (val != 44) {
+            throw new IllegalArgumentException("Expected 44");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaNaming/after/TESTOrderOfCapturedArgs.java	Tue Oct 22 17:44:43 2013 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.io.*;
+
+interface IOrderOfCapturedArgs extends Serializable {
+    String get();
+}
+
+class TESTOrderOfCapturedArgs {
+
+    public TESTOrderOfCapturedArgs() {
+    }
+
+    public void write(ObjectOutput out) throws IOException {
+        String a = "fu";
+        String b = "bar";
+        IOrderOfCapturedArgs res = () -> b + a;
+        out.writeObject(res);
+    }
+
+    public void readCheck(ObjectInput in) throws Exception {
+        IOrderOfCapturedArgs lam = (IOrderOfCapturedArgs) in.readObject();
+        Object val = lam.get();
+        if (!val.equals("fubar")) {
+            throw new IllegalArgumentException("Expected 'fubar'");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaNaming/after/TESTTargetName.java	Tue Oct 22 17:44:43 2013 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.io.*;
+
+interface ITargetName extends Serializable {
+    String get();
+}
+
+class TESTTargetName {
+
+    public TESTTargetName() {
+    }
+
+    public void write(ObjectOutput out) throws IOException {
+        ITargetName resist = () -> "fubar";
+        out.writeObject(resist);
+    }
+
+    public void readCheck(ObjectInput in) throws Exception {
+        ITargetName lam = (ITargetName) in.readObject();
+        Object val = lam.get();
+        if (!val.equals("fubar")) {
+            throw new IllegalArgumentException("Expected 'fubar'");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaNaming/after/TESTTargetType.java	Tue Oct 22 17:44:43 2013 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.io.*;
+import java.util.function.*;
+
+class TESTTargetType {
+
+    public TESTTargetType() {
+    }
+
+    public void write(ObjectOutput out) throws IOException {
+        Object res = (Predicate<String> & Serializable) ((str) -> str.length() > 3);
+        out.writeObject(res);
+    }
+
+    public void readCheck(ObjectInput in) throws Exception {
+        in.readObject();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaNaming/after/TESTTypesOfCapturedArgs.java	Tue Oct 22 17:44:43 2013 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.io.*;
+
+interface ITypesOfCapturedArgs extends Serializable {
+    Object get();
+}
+
+class TESTTypesOfCapturedArgs {
+
+    public TESTTypesOfCapturedArgs() {
+    }
+
+    public void write(ObjectOutput out) throws IOException {
+        Object x = "hi";
+        ITypesOfCapturedArgs res = () -> x;
+        out.writeObject(res);
+    }
+
+    public void readCheck(ObjectInput in) throws Exception {
+        ITypesOfCapturedArgs lam = (ITypesOfCapturedArgs) in.readObject();
+        Object val = lam.get();
+        if (!val.equals("hi")) {
+            throw new IllegalArgumentException("Expected 'hi'");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaNaming/after/TESTVariableAssignmentTarget.java	Tue Oct 22 17:44:43 2013 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.io.*;
+
+interface IVariableAssignmentTarget extends Serializable {
+    String get();
+}
+
+class TESTVariableAssignmentTarget {
+
+    public TESTVariableAssignmentTarget() {
+    }
+
+    public void write(ObjectOutput out) throws IOException {
+        IVariableAssignmentTarget res2 = () -> "bar";
+        IVariableAssignmentTarget res1 = () -> "fu";
+        out.writeObject(res1);
+        out.writeObject(res2);
+    }
+
+    public void readCheck(ObjectInput in) throws Exception {
+        IVariableAssignmentTarget lam = (IVariableAssignmentTarget) in.readObject();
+        Object val = lam.get();
+        if (!val.equals("fu")) {
+            throw new IllegalArgumentException("Expected 'fu'");
+        }
+        lam = (IVariableAssignmentTarget) in.readObject();
+        val = lam.get();
+        if (!val.equals("bar")) {
+            throw new IllegalArgumentException("Expected 'bar'");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaNaming/before/TESTNameOfCapturedArgs.java	Tue Oct 22 17:44:43 2013 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.io.*;
+
+interface INameOfCapturedArgs extends Serializable {
+    int get();
+}
+
+class TESTNameOfCapturedArgs {
+
+    public TESTNameOfCapturedArgs() {
+    }
+
+    public void write(ObjectOutput out) throws IOException {
+        int x = 44;
+        INameOfCapturedArgs res = () -> x;
+        out.writeObject(res);
+    }
+
+    public void readCheck(ObjectInput in) throws Exception {
+        INameOfCapturedArgs lam = (INameOfCapturedArgs) in.readObject();
+        int val = lam.get();
+        if (val != 44) {
+            throw new IllegalArgumentException("Expected 44");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaNaming/before/TESTOrderOfCapturedArgs.java	Tue Oct 22 17:44:43 2013 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.io.*;
+
+interface IOrderOfCapturedArgs extends Serializable {
+    String get();
+}
+
+class TESTOrderOfCapturedArgs {
+
+    public TESTOrderOfCapturedArgs() {
+    }
+
+    public void write(ObjectOutput out) throws IOException {
+        String a = "fu";
+        String b = "bar";
+        IOrderOfCapturedArgs res = () -> a + b;
+        out.writeObject(res);
+    }
+
+    public void readCheck(ObjectInput in) throws Exception {
+        IOrderOfCapturedArgs lam = (IOrderOfCapturedArgs) in.readObject();
+        Object val = lam.get();
+        if (!val.equals("fubar")) {
+            throw new IllegalArgumentException("Expected 'fubar'");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaNaming/before/TESTTargetName.java	Tue Oct 22 17:44:43 2013 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.io.*;
+
+interface ITargetName extends Serializable {
+    String get();
+}
+
+class TESTTargetName {
+
+    public TESTTargetName() {
+    }
+
+    public void write(ObjectOutput out) throws IOException {
+        ITargetName res = () -> "fubar";
+        out.writeObject(res);
+    }
+
+    public void readCheck(ObjectInput in) throws Exception {
+        ITargetName lam = (ITargetName) in.readObject();
+        Object val = lam.get();
+        if (!val.equals("fubar")) {
+            throw new IllegalArgumentException("Expected 'fubar'");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaNaming/before/TESTTargetType.java	Tue Oct 22 17:44:43 2013 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.io.*;
+import java.util.function.*;
+
+class TESTTargetType {
+
+    public TESTTargetType() {
+    }
+
+    public void write(ObjectOutput out) throws IOException {
+        Object res = (Function<String, Boolean> & Serializable) ((str) -> str.length() > 3);
+        out.writeObject(res);
+    }
+
+    public void readCheck(ObjectInput in) throws Exception {
+        in.readObject();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaNaming/before/TESTTypesOfCapturedArgs.java	Tue Oct 22 17:44:43 2013 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.io.*;
+
+interface ITypesOfCapturedArgs extends Serializable {
+    Object get();
+}
+
+class TESTTypesOfCapturedArgs {
+
+    public TESTTypesOfCapturedArgs() {
+    }
+
+    public void write(ObjectOutput out) throws IOException {
+        String x = "hi";
+        ITypesOfCapturedArgs res = () -> x;
+        out.writeObject(res);
+    }
+
+    public void readCheck(ObjectInput in) throws Exception {
+        ITypesOfCapturedArgs lam = (ITypesOfCapturedArgs) in.readObject();
+        Object val = lam.get();
+        if (!val.equals("hi")) {
+            throw new IllegalArgumentException("Expected 'hi'");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaNaming/before/TESTVariableAssignmentTarget.java	Tue Oct 22 17:44:43 2013 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.io.*;
+
+interface IVariableAssignmentTarget extends Serializable {
+    String get();
+}
+
+class TESTVariableAssignmentTarget {
+
+    public TESTVariableAssignmentTarget() {
+    }
+
+    public void write(ObjectOutput out) throws IOException {
+        IVariableAssignmentTarget res1 = () -> "fu";
+        IVariableAssignmentTarget res2 = () -> "bar";
+        out.writeObject(res1);
+        out.writeObject(res2);
+    }
+
+    public void readCheck(ObjectInput in) throws Exception {
+        IVariableAssignmentTarget lam = (IVariableAssignmentTarget) in.readObject();
+        Object val = lam.get();
+        if (!val.equals("fu")) {
+            throw new IllegalArgumentException("Expected 'fu'");
+        }
+        lam = (IVariableAssignmentTarget) in.readObject();
+        val = lam.get();
+        if (!val.equals("bar")) {
+            throw new IllegalArgumentException("Expected 'bar'");
+        }
+    }
+}