jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
author chegar
Mon, 18 Aug 2014 10:59:36 +0100
changeset 25991 e48157b42439
parent 25979 jdk/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java@42e5d9f8087e
parent 25859 jdk/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java@3317bb8137f4
child 28972 24af3f3f230e
permissions -rw-r--r--
Merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     1
/*
21618
6632680b0683 8027232: Update j.l.invoke code generating class files to use ASM enhancements for invocation of non-abstract methods on ifaces
ksrini
parents: 21425
diff changeset
     2
 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     4
 *
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    10
 *
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    15
 * accompanied this code).
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    16
 *
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    20
 *
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    23
 * questions.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    24
 */
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    25
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    26
package java.lang.invoke;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    27
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    28
import jdk.internal.org.objectweb.asm.*;
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
    29
import sun.invoke.util.BytecodeDescriptor;
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    30
import sun.misc.Unsafe;
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    31
import sun.security.action.GetPropertyAction;
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    32
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    33
import java.io.FilePermission;
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
    34
import java.io.Serializable;
18284
e281a0a2583e 8017044: anti-delta fix for 8015402
chegar
parents: 18182
diff changeset
    35
import java.lang.reflect.Constructor;
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    36
import java.security.AccessController;
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    37
import java.security.PrivilegedAction;
21353
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
    38
import java.util.LinkedHashSet;
18284
e281a0a2583e 8017044: anti-delta fix for 8015402
chegar
parents: 18182
diff changeset
    39
import java.util.concurrent.atomic.AtomicInteger;
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    40
import java.util.PropertyPermission;
21353
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
    41
import java.util.Set;
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    42
18284
e281a0a2583e 8017044: anti-delta fix for 8015402
chegar
parents: 18182
diff changeset
    43
import static jdk.internal.org.objectweb.asm.Opcodes.*;
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    44
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    45
/**
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    46
 * Lambda metafactory implementation which dynamically creates an
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    47
 * inner-class-like class per lambda callsite.
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    48
 *
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    49
 * @see LambdaMetafactory
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    50
 */
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    51
/* package */ final class InnerClassLambdaMetafactory extends AbstractValidatingLambdaMetafactory {
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    52
    private static final Unsafe UNSAFE = Unsafe.getUnsafe();
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    53
21618
6632680b0683 8027232: Update j.l.invoke code generating class files to use ASM enhancements for invocation of non-abstract methods on ifaces
ksrini
parents: 21425
diff changeset
    54
    private static final int CLASSFILE_VERSION = 52;
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    55
    private static final String METHOD_DESCRIPTOR_VOID = Type.getMethodDescriptor(Type.VOID_TYPE);
21300
9a71d04b2d02 8025631: Enhance Lambda construction
rfield
parents: 20748
diff changeset
    56
    private static final String JAVA_LANG_OBJECT = "java/lang/Object";
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    57
    private static final String NAME_CTOR = "<init>";
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
    58
    private static final String NAME_FACTORY = "get$Lambda";
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    59
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    60
    //Serialization support
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    61
    private static final String NAME_SERIALIZED_LAMBDA = "java/lang/invoke/SerializedLambda";
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
    62
    private static final String NAME_NOT_SERIALIZABLE_EXCEPTION = "java/io/NotSerializableException";
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    63
    private static final String DESCR_METHOD_WRITE_REPLACE = "()Ljava/lang/Object;";
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
    64
    private static final String DESCR_METHOD_WRITE_OBJECT = "(Ljava/io/ObjectOutputStream;)V";
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
    65
    private static final String DESCR_METHOD_READ_OBJECT = "(Ljava/io/ObjectInputStream;)V";
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    66
    private static final String NAME_METHOD_WRITE_REPLACE = "writeReplace";
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
    67
    private static final String NAME_METHOD_READ_OBJECT = "readObject";
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
    68
    private static final String NAME_METHOD_WRITE_OBJECT = "writeObject";
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    69
    private static final String DESCR_CTOR_SERIALIZED_LAMBDA
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    70
            = MethodType.methodType(void.class,
16034
cb5fbea1ecec 8008770: SerializedLambda incorrect class loader for lambda deserializing class
rfield
parents: 16001
diff changeset
    71
                                    Class.class,
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    72
                                    String.class, String.class, String.class,
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    73
                                    int.class, String.class, String.class, String.class,
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    74
                                    String.class,
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    75
                                    Object[].class).toMethodDescriptorString();
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
    76
    private static final String DESCR_CTOR_NOT_SERIALIZABLE_EXCEPTION
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
    77
            = MethodType.methodType(void.class, String.class).toMethodDescriptorString();
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
    78
    private static final String[] SER_HOSTILE_EXCEPTIONS = new String[] {NAME_NOT_SERIALIZABLE_EXCEPTION};
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
    79
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    80
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
    81
    private static final String[] EMPTY_STRING_ARRAY = new String[0];
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
    82
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    83
    // Used to ensure that each spun class name is unique
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    84
    private static final AtomicInteger counter = new AtomicInteger(0);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    85
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    86
    // For dumping generated classes to disk, for debugging purposes
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    87
    private static final ProxyClassesDumper dumper;
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    88
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    89
    static {
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    90
        final String key = "jdk.internal.lambda.dumpProxyClasses";
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    91
        String path = AccessController.doPrivileged(
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    92
                new GetPropertyAction(key), null,
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    93
                new PropertyPermission(key , "read"));
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    94
        dumper = (null == path) ? null : ProxyClassesDumper.getInstance(path);
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    95
    }
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    96
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    97
    // See context values in AbstractValidatingLambdaMetafactory
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    98
    private final String implMethodClassName;        // Name of type containing implementation "CC"
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    99
    private final String implMethodName;             // Name of implementation method "impl"
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   100
    private final String implMethodDesc;             // Type descriptor for implementation methods "(I)Ljava/lang/String;"
25979
42e5d9f8087e 8054857: Fix typos in java.lang.** packages
prappo
parents: 22297
diff changeset
   101
    private final Class<?> implMethodReturnClass;    // class for implementation method return type "Ljava/lang/String;"
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   102
    private final MethodType constructorType;        // Generated class constructor type "(CC)void"
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   103
    private final ClassWriter cw;                    // ASM class writer
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   104
    private final String[] argNames;                 // Generated names for the constructor arguments
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   105
    private final String[] argDescs;                 // Type descriptors for the constructor arguments
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   106
    private final String lambdaClassName;            // Generated name for the generated class "X$$Lambda$1"
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   107
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   108
    /**
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   109
     * General meta-factory constructor, supporting both standard cases and
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   110
     * allowing for uncommon options such as serialization or bridging.
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   111
     *
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   112
     * @param caller Stacked automatically by VM; represents a lookup context
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   113
     *               with the accessibility privileges of the caller.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   114
     * @param invokedType Stacked automatically by VM; the signature of the
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   115
     *                    invoked method, which includes the expected static
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   116
     *                    type of the returned lambda object, and the static
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   117
     *                    types of the captured arguments for the lambda.  In
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   118
     *                    the event that the implementation method is an
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   119
     *                    instance method, the first argument in the invocation
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   120
     *                    signature will correspond to the receiver.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   121
     * @param samMethodName Name of the method in the functional interface to
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   122
     *                      which the lambda or method reference is being
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   123
     *                      converted, represented as a String.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   124
     * @param samMethodType Type of the method in the functional interface to
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   125
     *                      which the lambda or method reference is being
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   126
     *                      converted, represented as a MethodType.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   127
     * @param implMethod The implementation method which should be called (with
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   128
     *                   suitable adaptation of argument types, return types,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   129
     *                   and adjustment for captured arguments) when methods of
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   130
     *                   the resulting functional interface instance are invoked.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   131
     * @param instantiatedMethodType The signature of the primary functional
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   132
     *                               interface method after type variables are
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   133
     *                               substituted with their instantiation from
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   134
     *                               the capture site
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   135
     * @param isSerializable Should the lambda be made serializable?  If set,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   136
     *                       either the target type or one of the additional SAM
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   137
     *                       types must extend {@code Serializable}.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   138
     * @param markerInterfaces Additional interfaces which the lambda object
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   139
     *                       should implement.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   140
     * @param additionalBridges Method types for additional signatures to be
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   141
     *                          bridged to the implementation method
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   142
     * @throws LambdaConversionException If any of the meta-factory protocol
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   143
     * invariants are violated
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   144
     */
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   145
    public InnerClassLambdaMetafactory(MethodHandles.Lookup caller,
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   146
                                       MethodType invokedType,
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   147
                                       String samMethodName,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   148
                                       MethodType samMethodType,
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   149
                                       MethodHandle implMethod,
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   150
                                       MethodType instantiatedMethodType,
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   151
                                       boolean isSerializable,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   152
                                       Class<?>[] markerInterfaces,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   153
                                       MethodType[] additionalBridges)
21360
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   154
            throws LambdaConversionException {
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   155
        super(caller, invokedType, samMethodName, samMethodType,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   156
              implMethod, instantiatedMethodType,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   157
              isSerializable, markerInterfaces, additionalBridges);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   158
        implMethodClassName = implDefiningClass.getName().replace('.', '/');
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   159
        implMethodName = implInfo.getName();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   160
        implMethodDesc = implMethodType.toMethodDescriptorString();
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   161
        implMethodReturnClass = (implKind == MethodHandleInfo.REF_newInvokeSpecial)
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   162
                ? implDefiningClass
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   163
                : implMethodType.returnType();
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   164
        constructorType = invokedType.changeReturnType(Void.TYPE);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   165
        lambdaClassName = targetClass.getName().replace('.', '/') + "$$Lambda$" + counter.incrementAndGet();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   166
        cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   167
        int parameterCount = invokedType.parameterCount();
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   168
        if (parameterCount > 0) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   169
            argNames = new String[parameterCount];
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   170
            argDescs = new String[parameterCount];
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   171
            for (int i = 0; i < parameterCount; i++) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   172
                argNames[i] = "arg$" + (i + 1);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   173
                argDescs[i] = BytecodeDescriptor.unparse(invokedType.parameterType(i));
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   174
            }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   175
        } else {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   176
            argNames = argDescs = EMPTY_STRING_ARRAY;
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   177
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   178
    }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   179
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   180
    /**
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   181
     * Build the CallSite. Generate a class file which implements the functional
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   182
     * interface, define the class, if there are no parameters create an instance
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   183
     * of the class which the CallSite will return, otherwise, generate handles
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   184
     * which will call the class' constructor.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   185
     *
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   186
     * @return a CallSite, which, when invoked, will return an instance of the
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   187
     * functional interface
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   188
     * @throws ReflectiveOperationException
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   189
     * @throws LambdaConversionException If properly formed functional interface
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   190
     * is not found
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   191
     */
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   192
    @Override
21360
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   193
    CallSite buildCallSite() throws LambdaConversionException {
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   194
        final Class<?> innerClass = spinInnerClass();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   195
        if (invokedType.parameterCount() == 0) {
22297
1c62c67d9dd2 8031373: Lint warnings in java.util.stream
briangoetz
parents: 21618
diff changeset
   196
            final Constructor<?>[] ctrs = AccessController.doPrivileged(
1c62c67d9dd2 8031373: Lint warnings in java.util.stream
briangoetz
parents: 21618
diff changeset
   197
                    new PrivilegedAction<Constructor<?>[]>() {
14762
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   198
                @Override
22297
1c62c67d9dd2 8031373: Lint warnings in java.util.stream
briangoetz
parents: 21618
diff changeset
   199
                public Constructor<?>[] run() {
21425
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   200
                    Constructor<?>[] ctrs = innerClass.getDeclaredConstructors();
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   201
                    if (ctrs.length == 1) {
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   202
                        // The lambda implementing inner class constructor is private, set
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   203
                        // it accessible (by us) before creating the constant sole instance
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   204
                        ctrs[0].setAccessible(true);
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   205
                    }
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   206
                    return ctrs;
14762
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   207
                }
21425
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   208
                    });
14762
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   209
            if (ctrs.length != 1) {
21360
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   210
                throw new LambdaConversionException("Expected one lambda constructor for "
14762
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   211
                        + innerClass.getCanonicalName() + ", got " + ctrs.length);
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   212
            }
21425
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   213
21360
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   214
            try {
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   215
                Object inst = ctrs[0].newInstance();
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   216
                return new ConstantCallSite(MethodHandles.constant(samBase, inst));
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   217
            }
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   218
            catch (ReflectiveOperationException e) {
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   219
                throw new LambdaConversionException("Exception instantiating lambda object", e);
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   220
            }
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   221
        } else {
21360
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   222
            try {
21425
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   223
                UNSAFE.ensureClassInitialized(innerClass);
21360
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   224
                return new ConstantCallSite(
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   225
                        MethodHandles.Lookup.IMPL_LOOKUP
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   226
                             .findStatic(innerClass, NAME_FACTORY, invokedType));
21360
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   227
            }
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   228
            catch (ReflectiveOperationException e) {
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   229
                throw new LambdaConversionException("Exception finding constructor", e);
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   230
            }
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   231
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   232
    }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   233
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   234
    /**
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   235
     * Generate a class file which implements the functional
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   236
     * interface, define and return the class.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   237
     *
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   238
     * @implNote The class that is generated does not include signature
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   239
     * information for exceptions that may be present on the SAM method.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   240
     * This is to reduce classfile size, and is harmless as checked exceptions
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   241
     * are erased anyway, no one will ever compile against this classfile,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   242
     * and we make no guarantees about the reflective properties of lambda
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   243
     * objects.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   244
     *
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   245
     * @return a Class which implements the functional interface
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   246
     * @throws LambdaConversionException If properly formed functional interface
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   247
     * is not found
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   248
     */
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   249
    private Class<?> spinInnerClass() throws LambdaConversionException {
21353
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   250
        String[] interfaces;
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   251
        String samIntf = samBase.getName().replace('.', '/');
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   252
        boolean accidentallySerializable = !isSerializable && Serializable.class.isAssignableFrom(samBase);
21353
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   253
        if (markerInterfaces.length == 0) {
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   254
            interfaces = new String[]{samIntf};
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   255
        } else {
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   256
            // Assure no duplicate interfaces (ClassFormatError)
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   257
            Set<String> itfs = new LinkedHashSet<>(markerInterfaces.length + 1);
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   258
            itfs.add(samIntf);
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   259
            for (Class<?> markerInterface : markerInterfaces) {
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   260
                itfs.add(markerInterface.getName().replace('.', '/'));
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   261
                accidentallySerializable |= !isSerializable && Serializable.class.isAssignableFrom(markerInterface);
21353
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   262
            }
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   263
            interfaces = itfs.toArray(new String[itfs.size()]);
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   264
        }
21353
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   265
16859
45fbee947921 8012028: Metafactory-generated lambda classes should be final
rfield
parents: 16854
diff changeset
   266
        cw.visit(CLASSFILE_VERSION, ACC_SUPER + ACC_FINAL + ACC_SYNTHETIC,
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   267
                 lambdaClassName, null,
21300
9a71d04b2d02 8025631: Enhance Lambda construction
rfield
parents: 20748
diff changeset
   268
                 JAVA_LANG_OBJECT, interfaces);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   269
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   270
        // Generate final fields to be filled in by constructor
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   271
        for (int i = 0; i < argDescs.length; i++) {
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   272
            FieldVisitor fv = cw.visitField(ACC_PRIVATE + ACC_FINAL,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   273
                                            argNames[i],
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   274
                                            argDescs[i],
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   275
                                            null, null);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   276
            fv.visitEnd();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   277
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   278
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   279
        generateConstructor();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   280
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   281
        if (invokedType.parameterCount() != 0) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   282
            generateFactory();
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   283
        }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   284
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   285
        // Forward the SAM method
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   286
        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, samMethodName,
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   287
                                          samMethodType.toMethodDescriptorString(), null, null);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   288
        new ForwardingMethodGenerator(mv).generate(samMethodType);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   289
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   290
        // Forward the bridges
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   291
        if (additionalBridges != null) {
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   292
            for (MethodType mt : additionalBridges) {
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   293
                mv = cw.visitMethod(ACC_PUBLIC|ACC_BRIDGE, samMethodName,
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   294
                                    mt.toMethodDescriptorString(), null, null);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   295
                new ForwardingMethodGenerator(mv).generate(mt);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   296
            }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   297
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   298
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   299
        if (isSerializable)
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   300
            generateSerializationFriendlyMethods();
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   301
        else if (accidentallySerializable)
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   302
            generateSerializationHostileMethods();
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   303
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   304
        cw.visitEnd();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   305
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   306
        // Define the generated class in this VM.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   307
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   308
        final byte[] classBytes = cw.toByteArray();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   309
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   310
        // If requested, dump out to a file for debugging purposes
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   311
        if (dumper != null) {
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   312
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   313
                @Override
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   314
                public Void run() {
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   315
                    dumper.dumpClass(lambdaClassName, classBytes);
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   316
                    return null;
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   317
                }
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   318
            }, null,
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   319
            new FilePermission("<<ALL FILES>>", "read, write"),
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   320
            // createDirectories may need it
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   321
            new PropertyPermission("user.dir", "read"));
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   322
        }
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   323
21300
9a71d04b2d02 8025631: Enhance Lambda construction
rfield
parents: 20748
diff changeset
   324
        return UNSAFE.defineAnonymousClass(targetClass, classBytes, null);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   325
    }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   326
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   327
    /**
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   328
     * Generate the factory method for the class
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   329
     */
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   330
    private void generateFactory() {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   331
        MethodVisitor m = cw.visitMethod(ACC_PRIVATE | ACC_STATIC, NAME_FACTORY, invokedType.toMethodDescriptorString(), null, null);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   332
        m.visitCode();
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   333
        m.visitTypeInsn(NEW, lambdaClassName);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   334
        m.visitInsn(Opcodes.DUP);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   335
        int parameterCount = invokedType.parameterCount();
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   336
        for (int typeIndex = 0, varIndex = 0; typeIndex < parameterCount; typeIndex++) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   337
            Class<?> argType = invokedType.parameterType(typeIndex);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   338
            m.visitVarInsn(getLoadOpcode(argType), varIndex);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   339
            varIndex += getParameterSize(argType);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   340
        }
22297
1c62c67d9dd2 8031373: Lint warnings in java.util.stream
briangoetz
parents: 21618
diff changeset
   341
        m.visitMethodInsn(INVOKESPECIAL, lambdaClassName, NAME_CTOR, constructorType.toMethodDescriptorString(), false);
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   342
        m.visitInsn(ARETURN);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   343
        m.visitMaxs(-1, -1);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   344
        m.visitEnd();
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   345
    }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   346
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   347
    /**
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   348
     * Generate the constructor for the class
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   349
     */
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   350
    private void generateConstructor() {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   351
        // Generate constructor
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   352
        MethodVisitor ctor = cw.visitMethod(ACC_PRIVATE, NAME_CTOR,
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   353
                                            constructorType.toMethodDescriptorString(), null, null);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   354
        ctor.visitCode();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   355
        ctor.visitVarInsn(ALOAD, 0);
21300
9a71d04b2d02 8025631: Enhance Lambda construction
rfield
parents: 20748
diff changeset
   356
        ctor.visitMethodInsn(INVOKESPECIAL, JAVA_LANG_OBJECT, NAME_CTOR,
22297
1c62c67d9dd2 8031373: Lint warnings in java.util.stream
briangoetz
parents: 21618
diff changeset
   357
                             METHOD_DESCRIPTOR_VOID, false);
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   358
        int parameterCount = invokedType.parameterCount();
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   359
        for (int i = 0, lvIndex = 0; i < parameterCount; i++) {
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   360
            ctor.visitVarInsn(ALOAD, 0);
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   361
            Class<?> argType = invokedType.parameterType(i);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   362
            ctor.visitVarInsn(getLoadOpcode(argType), lvIndex + 1);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   363
            lvIndex += getParameterSize(argType);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   364
            ctor.visitFieldInsn(PUTFIELD, lambdaClassName, argNames[i], argDescs[i]);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   365
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   366
        ctor.visitInsn(RETURN);
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   367
        // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   368
        ctor.visitMaxs(-1, -1);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   369
        ctor.visitEnd();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   370
    }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   371
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   372
    /**
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   373
     * Generate a writeReplace method that supports serialization
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   374
     */
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   375
    private void generateSerializationFriendlyMethods() {
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   376
        TypeConvertingMethodAdapter mv
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   377
                = new TypeConvertingMethodAdapter(
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   378
                    cw.visitMethod(ACC_PRIVATE + ACC_FINAL,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   379
                    NAME_METHOD_WRITE_REPLACE, DESCR_METHOD_WRITE_REPLACE,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   380
                    null, null));
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   381
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   382
        mv.visitCode();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   383
        mv.visitTypeInsn(NEW, NAME_SERIALIZED_LAMBDA);
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   384
        mv.visitInsn(DUP);
16034
cb5fbea1ecec 8008770: SerializedLambda incorrect class loader for lambda deserializing class
rfield
parents: 16001
diff changeset
   385
        mv.visitLdcInsn(Type.getType(targetClass));
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   386
        mv.visitLdcInsn(invokedType.returnType().getName().replace('.', '/'));
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   387
        mv.visitLdcInsn(samMethodName);
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   388
        mv.visitLdcInsn(samMethodType.toMethodDescriptorString());
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   389
        mv.visitLdcInsn(implInfo.getReferenceKind());
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   390
        mv.visitLdcInsn(implInfo.getDeclaringClass().getName().replace('.', '/'));
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   391
        mv.visitLdcInsn(implInfo.getName());
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   392
        mv.visitLdcInsn(implInfo.getMethodType().toMethodDescriptorString());
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   393
        mv.visitLdcInsn(instantiatedMethodType.toMethodDescriptorString());
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   394
        mv.iconst(argDescs.length);
21300
9a71d04b2d02 8025631: Enhance Lambda construction
rfield
parents: 20748
diff changeset
   395
        mv.visitTypeInsn(ANEWARRAY, JAVA_LANG_OBJECT);
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   396
        for (int i = 0; i < argDescs.length; i++) {
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   397
            mv.visitInsn(DUP);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   398
            mv.iconst(i);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   399
            mv.visitVarInsn(ALOAD, 0);
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   400
            mv.visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], argDescs[i]);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   401
            mv.boxIfTypePrimitive(Type.getType(argDescs[i]));
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   402
            mv.visitInsn(AASTORE);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   403
        }
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   404
        mv.visitMethodInsn(INVOKESPECIAL, NAME_SERIALIZED_LAMBDA, NAME_CTOR,
22297
1c62c67d9dd2 8031373: Lint warnings in java.util.stream
briangoetz
parents: 21618
diff changeset
   405
                DESCR_CTOR_SERIALIZED_LAMBDA, false);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   406
        mv.visitInsn(ARETURN);
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   407
        // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   408
        mv.visitMaxs(-1, -1);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   409
        mv.visitEnd();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   410
    }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   411
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   412
    /**
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   413
     * Generate a readObject/writeObject method that is hostile to serialization
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   414
     */
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   415
    private void generateSerializationHostileMethods() {
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   416
        MethodVisitor mv = cw.visitMethod(ACC_PRIVATE + ACC_FINAL,
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   417
                                          NAME_METHOD_WRITE_OBJECT, DESCR_METHOD_WRITE_OBJECT,
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   418
                                          null, SER_HOSTILE_EXCEPTIONS);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   419
        mv.visitCode();
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   420
        mv.visitTypeInsn(NEW, NAME_NOT_SERIALIZABLE_EXCEPTION);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   421
        mv.visitInsn(DUP);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   422
        mv.visitLdcInsn("Non-serializable lambda");
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   423
        mv.visitMethodInsn(INVOKESPECIAL, NAME_NOT_SERIALIZABLE_EXCEPTION, NAME_CTOR,
22297
1c62c67d9dd2 8031373: Lint warnings in java.util.stream
briangoetz
parents: 21618
diff changeset
   424
                           DESCR_CTOR_NOT_SERIALIZABLE_EXCEPTION, false);
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   425
        mv.visitInsn(ATHROW);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   426
        mv.visitMaxs(-1, -1);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   427
        mv.visitEnd();
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   428
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   429
        mv = cw.visitMethod(ACC_PRIVATE + ACC_FINAL,
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   430
                            NAME_METHOD_READ_OBJECT, DESCR_METHOD_READ_OBJECT,
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   431
                            null, SER_HOSTILE_EXCEPTIONS);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   432
        mv.visitCode();
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   433
        mv.visitTypeInsn(NEW, NAME_NOT_SERIALIZABLE_EXCEPTION);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   434
        mv.visitInsn(DUP);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   435
        mv.visitLdcInsn("Non-serializable lambda");
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   436
        mv.visitMethodInsn(INVOKESPECIAL, NAME_NOT_SERIALIZABLE_EXCEPTION, NAME_CTOR,
22297
1c62c67d9dd2 8031373: Lint warnings in java.util.stream
briangoetz
parents: 21618
diff changeset
   437
                           DESCR_CTOR_NOT_SERIALIZABLE_EXCEPTION, false);
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   438
        mv.visitInsn(ATHROW);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   439
        mv.visitMaxs(-1, -1);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   440
        mv.visitEnd();
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   441
    }
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   442
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   443
    /**
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   444
     * This class generates a method body which calls the lambda implementation
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   445
     * method, converting arguments, as needed.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   446
     */
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   447
    private class ForwardingMethodGenerator extends TypeConvertingMethodAdapter {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   448
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   449
        ForwardingMethodGenerator(MethodVisitor mv) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   450
            super(mv);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   451
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   452
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   453
        void generate(MethodType methodType) {
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   454
            visitCode();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   455
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   456
            if (implKind == MethodHandleInfo.REF_newInvokeSpecial) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   457
                visitTypeInsn(NEW, implMethodClassName);
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   458
                visitInsn(DUP);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   459
            }
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   460
            for (int i = 0; i < argNames.length; i++) {
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   461
                visitVarInsn(ALOAD, 0);
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   462
                visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], argDescs[i]);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   463
            }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   464
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   465
            convertArgumentTypes(methodType);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   466
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   467
            // Invoke the method we want to forward to
21618
6632680b0683 8027232: Update j.l.invoke code generating class files to use ASM enhancements for invocation of non-abstract methods on ifaces
ksrini
parents: 21425
diff changeset
   468
            visitMethodInsn(invocationOpcode(), implMethodClassName,
6632680b0683 8027232: Update j.l.invoke code generating class files to use ASM enhancements for invocation of non-abstract methods on ifaces
ksrini
parents: 21425
diff changeset
   469
                            implMethodName, implMethodDesc,
6632680b0683 8027232: Update j.l.invoke code generating class files to use ASM enhancements for invocation of non-abstract methods on ifaces
ksrini
parents: 21425
diff changeset
   470
                            implDefiningClass.isInterface());
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   471
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   472
            // Convert the return value (if any) and return it
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   473
            // Note: if adapting from non-void to void, the 'return'
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   474
            // instruction will pop the unneeded result
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   475
            Class<?> samReturnClass = methodType.returnType();
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   476
            convertType(implMethodReturnClass, samReturnClass, samReturnClass);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   477
            visitInsn(getReturnOpcode(samReturnClass));
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   478
            // Maxs computed by ClassWriter.COMPUTE_MAXS,these arguments ignored
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   479
            visitMaxs(-1, -1);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   480
            visitEnd();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   481
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   482
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   483
        private void convertArgumentTypes(MethodType samType) {
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   484
            int lvIndex = 0;
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   485
            boolean samIncludesReceiver = implIsInstanceMethod &&
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   486
                                                   invokedType.parameterCount() == 0;
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   487
            int samReceiverLength = samIncludesReceiver ? 1 : 0;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   488
            if (samIncludesReceiver) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   489
                // push receiver
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   490
                Class<?> rcvrType = samType.parameterType(0);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   491
                visitVarInsn(getLoadOpcode(rcvrType), lvIndex + 1);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   492
                lvIndex += getParameterSize(rcvrType);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   493
                convertType(rcvrType, implDefiningClass, instantiatedMethodType.parameterType(0));
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   494
            }
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   495
            int samParametersLength = samType.parameterCount();
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   496
            int argOffset = implMethodType.parameterCount() - samParametersLength;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   497
            for (int i = samReceiverLength; i < samParametersLength; i++) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   498
                Class<?> argType = samType.parameterType(i);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   499
                visitVarInsn(getLoadOpcode(argType), lvIndex + 1);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   500
                lvIndex += getParameterSize(argType);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   501
                convertType(argType, implMethodType.parameterType(argOffset + i), instantiatedMethodType.parameterType(i));
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   502
            }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   503
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   504
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   505
        private int invocationOpcode() throws InternalError {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   506
            switch (implKind) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   507
                case MethodHandleInfo.REF_invokeStatic:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   508
                    return INVOKESTATIC;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   509
                case MethodHandleInfo.REF_newInvokeSpecial:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   510
                    return INVOKESPECIAL;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   511
                 case MethodHandleInfo.REF_invokeVirtual:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   512
                    return INVOKEVIRTUAL;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   513
                case MethodHandleInfo.REF_invokeInterface:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   514
                    return INVOKEINTERFACE;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   515
                case MethodHandleInfo.REF_invokeSpecial:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   516
                    return INVOKESPECIAL;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   517
                default:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   518
                    throw new InternalError("Unexpected invocation kind: " + implKind);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   519
            }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   520
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   521
    }
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   522
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   523
    static int getParameterSize(Class<?> c) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   524
        if (c == Void.TYPE) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   525
            return 0;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   526
        } else if (c == Long.TYPE || c == Double.TYPE) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   527
            return 2;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   528
        }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   529
        return 1;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   530
    }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   531
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   532
    static int getLoadOpcode(Class<?> c) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   533
        if(c == Void.TYPE) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   534
            throw new InternalError("Unexpected void type of load opcode");
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   535
        }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   536
        return ILOAD + getOpcodeOffset(c);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   537
    }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   538
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   539
    static int getReturnOpcode(Class<?> c) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   540
        if(c == Void.TYPE) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   541
            return RETURN;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   542
        }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   543
        return IRETURN + getOpcodeOffset(c);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   544
    }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   545
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   546
    private static int getOpcodeOffset(Class<?> c) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   547
        if (c.isPrimitive()) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   548
            if (c == Long.TYPE) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   549
                return 1;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   550
            } else if (c == Float.TYPE) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   551
                return 2;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   552
            } else if (c == Double.TYPE) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   553
                return 3;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   554
            }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   555
            return 0;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   556
        } else {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   557
            return 4;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   558
        }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   559
    }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   560
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   561
}