src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
author vjovanovic
Mon, 28 Oct 2019 15:03:36 +0100
changeset 58871 27c2d2a4b695
parent 53435 ea254e9fc587
permissions -rw-r--r--
8232806: Introduce a system property to disable eager lambda initialization Reviewed-by: briangoetz, mr, psandoz, forax
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;
33674
566777f73c32 8140606: Update library code to use internal Unsafe
chegar
parents: 33525
diff changeset
    30
import jdk.internal.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;
58871
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
    32
import sun.security.action.GetBooleanAction;
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    33
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    34
import java.io.FilePermission;
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
    35
import java.io.Serializable;
18284
e281a0a2583e 8017044: anti-delta fix for 8015402
chegar
parents: 18182
diff changeset
    36
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
    37
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
    38
import java.security.PrivilegedAction;
21353
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
    39
import java.util.LinkedHashSet;
18284
e281a0a2583e 8017044: anti-delta fix for 8015402
chegar
parents: 18182
diff changeset
    40
import java.util.concurrent.atomic.AtomicInteger;
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    41
import java.util.PropertyPermission;
21353
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
    42
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
    43
18284
e281a0a2583e 8017044: anti-delta fix for 8015402
chegar
parents: 18182
diff changeset
    44
import static jdk.internal.org.objectweb.asm.Opcodes.*;
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    45
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    46
/**
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    47
 * 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
    48
 * inner-class-like class per lambda callsite.
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    49
 *
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    50
 * @see LambdaMetafactory
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    51
 */
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    52
/* 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
    53
    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
    54
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
    55
    private static final int CLASSFILE_VERSION = 52;
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    56
    private static final String METHOD_DESCRIPTOR_VOID = Type.getMethodDescriptor(Type.VOID_TYPE);
21300
9a71d04b2d02 8025631: Enhance Lambda construction
rfield
parents: 20748
diff changeset
    57
    private static final String JAVA_LANG_OBJECT = "java/lang/Object";
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    58
    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
    59
    private static final String NAME_FACTORY = "get$Lambda";
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    60
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    61
    //Serialization support
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    62
    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
    63
    private static final String NAME_NOT_SERIALIZABLE_EXCEPTION = "java/io/NotSerializableException";
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    64
    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
    65
    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
    66
    private static final String DESCR_METHOD_READ_OBJECT = "(Ljava/io/ObjectInputStream;)V";
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    67
    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
    68
    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
    69
    private static final String NAME_METHOD_WRITE_OBJECT = "writeObject";
33525
3058b44fd282 8141539: Avoid calculating string constants in InnerClassLambdaMetaFactory
redestad
parents: 29986
diff changeset
    70
3058b44fd282 8141539: Avoid calculating string constants in InnerClassLambdaMetaFactory
redestad
parents: 29986
diff changeset
    71
    private static final String DESCR_CLASS = "Ljava/lang/Class;";
3058b44fd282 8141539: Avoid calculating string constants in InnerClassLambdaMetaFactory
redestad
parents: 29986
diff changeset
    72
    private static final String DESCR_STRING = "Ljava/lang/String;";
3058b44fd282 8141539: Avoid calculating string constants in InnerClassLambdaMetaFactory
redestad
parents: 29986
diff changeset
    73
    private static final String DESCR_OBJECT = "Ljava/lang/Object;";
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    74
    private static final String DESCR_CTOR_SERIALIZED_LAMBDA
33525
3058b44fd282 8141539: Avoid calculating string constants in InnerClassLambdaMetaFactory
redestad
parents: 29986
diff changeset
    75
            = "(" + DESCR_CLASS + DESCR_STRING + DESCR_STRING + DESCR_STRING + "I"
3058b44fd282 8141539: Avoid calculating string constants in InnerClassLambdaMetaFactory
redestad
parents: 29986
diff changeset
    76
            + DESCR_STRING + DESCR_STRING + DESCR_STRING + DESCR_STRING + "[" + DESCR_OBJECT + ")V";
3058b44fd282 8141539: Avoid calculating string constants in InnerClassLambdaMetaFactory
redestad
parents: 29986
diff changeset
    77
3058b44fd282 8141539: Avoid calculating string constants in InnerClassLambdaMetaFactory
redestad
parents: 29986
diff changeset
    78
    private static final String DESCR_CTOR_NOT_SERIALIZABLE_EXCEPTION = "(Ljava/lang/String;)V";
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
    79
    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
    80
53435
ea254e9fc587 8213234: Move LambdaForm.Hidden to jdk.internal.vm.annotation
vlivanov
parents: 47216
diff changeset
    81
    private static final String DESCR_HIDDEN = "Ljdk/internal/vm/annotation/Hidden;";
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    82
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
    83
    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
    84
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    85
    // Used to ensure that each spun class name is unique
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    86
    private static final AtomicInteger counter = new AtomicInteger(0);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    87
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    88
    // 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
    89
    private static final ProxyClassesDumper dumper;
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    90
58871
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
    91
    private static final boolean disableEagerInitialization;
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
    92
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    93
    static {
58871
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
    94
        final String dumpProxyClassesKey = "jdk.internal.lambda.dumpProxyClasses";
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
    95
        String dumpPath = GetPropertyAction.privilegedGetProperty(dumpProxyClassesKey);
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
    96
        dumper = (null == dumpPath) ? null : ProxyClassesDumper.getInstance(dumpPath);
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
    97
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
    98
        final String disableEagerInitializationKey = "jdk.internal.lambda.disableEagerInitialization";
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
    99
        disableEagerInitialization = GetBooleanAction.privilegedGetProperty(disableEagerInitializationKey);
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   100
    }
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   101
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   102
    // See context values in AbstractValidatingLambdaMetafactory
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   103
    private final String implMethodClassName;        // Name of type containing implementation "CC"
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   104
    private final String implMethodName;             // Name of implementation method "impl"
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   105
    private final String implMethodDesc;             // Type descriptor for implementation methods "(I)Ljava/lang/String;"
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   106
    private final MethodType constructorType;        // Generated class constructor type "(CC)void"
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   107
    private final ClassWriter cw;                    // ASM class writer
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   108
    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
   109
    private final String[] argDescs;                 // Type descriptors for the constructor arguments
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   110
    private final String lambdaClassName;            // Generated name for the generated class "X$$Lambda$1"
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   111
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   112
    /**
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   113
     * 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
   114
     * allowing for uncommon options such as serialization or bridging.
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   115
     *
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   116
     * @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
   117
     *               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
   118
     * @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
   119
     *                    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
   120
     *                    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
   121
     *                    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
   122
     *                    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
   123
     *                    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
   124
     *                    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
   125
     * @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
   126
     *                      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
   127
     *                      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
   128
     * @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
   129
     *                      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
   130
     *                      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
   131
     * @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
   132
     *                   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
   133
     *                   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
   134
     *                   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
   135
     * @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
   136
     *                               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
   137
     *                               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
   138
     *                               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
   139
     * @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
   140
     *                       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
   141
     *                       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
   142
     * @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
   143
     *                       should implement.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   144
     * @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
   145
     *                          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
   146
     * @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
   147
     * invariants are violated
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   148
     */
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   149
    public InnerClassLambdaMetafactory(MethodHandles.Lookup caller,
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   150
                                       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
   151
                                       String samMethodName,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   152
                                       MethodType samMethodType,
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   153
                                       MethodHandle implMethod,
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   154
                                       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
   155
                                       boolean isSerializable,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   156
                                       Class<?>[] markerInterfaces,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   157
                                       MethodType[] additionalBridges)
21360
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   158
            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
   159
        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
   160
              implMethod, instantiatedMethodType,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   161
              isSerializable, markerInterfaces, additionalBridges);
43789
43068ea5965e 8174399: LambdaMetafactory should use types in implMethod.type()
dlsmith
parents: 43703
diff changeset
   162
        implMethodClassName = implClass.getName().replace('.', '/');
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   163
        implMethodName = implInfo.getName();
43789
43068ea5965e 8174399: LambdaMetafactory should use types in implMethod.type()
dlsmith
parents: 43703
diff changeset
   164
        implMethodDesc = implInfo.getMethodType().toMethodDescriptorString();
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   165
        constructorType = invokedType.changeReturnType(Void.TYPE);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   166
        lambdaClassName = targetClass.getName().replace('.', '/') + "$$Lambda$" + counter.incrementAndGet();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   167
        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
   168
        int parameterCount = invokedType.parameterCount();
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   169
        if (parameterCount > 0) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   170
            argNames = new String[parameterCount];
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   171
            argDescs = new String[parameterCount];
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   172
            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
   173
                argNames[i] = "arg$" + (i + 1);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   174
                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
   175
            }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   176
        } else {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   177
            argNames = argDescs = EMPTY_STRING_ARRAY;
14323
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
    /**
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   182
     * Build the CallSite. Generate a class file which implements the functional
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   183
     * interface, define the class, if there are no parameters create an instance
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   184
     * of the class which the CallSite will return, otherwise, generate handles
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   185
     * which will call the class' constructor.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   186
     *
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   187
     * @return a CallSite, which, when invoked, will return an instance of the
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   188
     * functional interface
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   189
     * @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
   190
     * @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
   191
     * is not found
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   192
     */
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   193
    @Override
21360
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   194
    CallSite buildCallSite() throws LambdaConversionException {
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   195
        final Class<?> innerClass = spinInnerClass();
58871
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
   196
        if (invokedType.parameterCount() == 0 && !disableEagerInitialization) {
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
   197
            // In the case of a non-capturing lambda, we optimize linkage by pre-computing a single instance,
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
   198
            // unless we've suppressed eager initialization
22297
1c62c67d9dd2 8031373: Lint warnings in java.util.stream
briangoetz
parents: 21618
diff changeset
   199
            final Constructor<?>[] ctrs = AccessController.doPrivileged(
29986
97167d851fc4 8078467: Update core libraries to use diamond with anonymous classes
darcy
parents: 28972
diff changeset
   200
                    new PrivilegedAction<>() {
14762
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   201
                @Override
22297
1c62c67d9dd2 8031373: Lint warnings in java.util.stream
briangoetz
parents: 21618
diff changeset
   202
                public Constructor<?>[] run() {
21425
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   203
                    Constructor<?>[] ctrs = innerClass.getDeclaredConstructors();
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   204
                    if (ctrs.length == 1) {
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   205
                        // The lambda implementing inner class constructor is private, set
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   206
                        // it accessible (by us) before creating the constant sole instance
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   207
                        ctrs[0].setAccessible(true);
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   208
                    }
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   209
                    return ctrs;
14762
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   210
                }
21425
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   211
                    });
14762
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   212
            if (ctrs.length != 1) {
21360
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   213
                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
   214
                        + innerClass.getCanonicalName() + ", got " + ctrs.length);
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   215
            }
21425
2d49fa63ac15 8024633: Lambda linkage performance - initialize generated class earlier
briangoetz
parents: 21424
diff changeset
   216
21360
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   217
            try {
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   218
                Object inst = ctrs[0].newInstance();
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   219
                return new ConstantCallSite(MethodHandles.constant(samBase, inst));
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   220
            }
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   221
            catch (ReflectiveOperationException e) {
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   222
                throw new LambdaConversionException("Exception instantiating lambda object", e);
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   223
            }
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   224
        } else {
21360
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   225
            try {
58871
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
   226
                if (!disableEagerInitialization) {
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
   227
                    UNSAFE.ensureClassInitialized(innerClass);
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
   228
                }
21360
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   229
                return new ConstantCallSite(
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   230
                        MethodHandles.Lookup.IMPL_LOOKUP
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   231
                             .findStatic(innerClass, NAME_FACTORY, invokedType));
21360
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   232
            }
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   233
            catch (ReflectiveOperationException e) {
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   234
                throw new LambdaConversionException("Exception finding constructor", e);
2c2f062cf52f 8019646: Clarify javadoc contract of LambdaMetafactory
briangoetz
parents: 21353
diff changeset
   235
            }
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   236
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   237
    }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   238
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   239
    /**
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   240
     * Generate a class file which implements the functional
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   241
     * interface, define and return the class.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   242
     *
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   243
     * @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
   244
     * 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
   245
     * 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
   246
     * 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
   247
     * 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
   248
     * objects.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   249
     *
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   250
     * @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
   251
     * @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
   252
     * is not found
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   253
     */
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   254
    private Class<?> spinInnerClass() throws LambdaConversionException {
21353
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   255
        String[] interfaces;
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   256
        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
   257
        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
   258
        if (markerInterfaces.length == 0) {
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   259
            interfaces = new String[]{samIntf};
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   260
        } else {
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   261
            // Assure no duplicate interfaces (ClassFormatError)
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   262
            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
   263
            itfs.add(samIntf);
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   264
            for (Class<?> markerInterface : markerInterfaces) {
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   265
                itfs.add(markerInterface.getName().replace('.', '/'));
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   266
                accidentallySerializable |= !isSerializable && Serializable.class.isAssignableFrom(markerInterface);
21353
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   267
            }
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   268
            interfaces = itfs.toArray(new String[itfs.size()]);
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   269
        }
21353
9792667abbf2 8025868: Several lang/LMBD JCK tests fail with java.lang.BootstrapMethodError
rfield
parents: 21300
diff changeset
   270
16859
45fbee947921 8012028: Metafactory-generated lambda classes should be final
rfield
parents: 16854
diff changeset
   271
        cw.visit(CLASSFILE_VERSION, ACC_SUPER + ACC_FINAL + ACC_SYNTHETIC,
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   272
                 lambdaClassName, null,
21300
9a71d04b2d02 8025631: Enhance Lambda construction
rfield
parents: 20748
diff changeset
   273
                 JAVA_LANG_OBJECT, interfaces);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   274
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   275
        // 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
   276
        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
   277
            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
   278
                                            argNames[i],
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   279
                                            argDescs[i],
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   280
                                            null, null);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   281
            fv.visitEnd();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   282
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   283
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   284
        generateConstructor();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   285
58871
27c2d2a4b695 8232806: Introduce a system property to disable eager lambda initialization
vjovanovic
parents: 53435
diff changeset
   286
        if (invokedType.parameterCount() != 0 || disableEagerInitialization) {
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   287
            generateFactory();
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   288
        }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   289
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   290
        // 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
   291
        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
   292
                                          samMethodType.toMethodDescriptorString(), null, null);
53435
ea254e9fc587 8213234: Move LambdaForm.Hidden to jdk.internal.vm.annotation
vlivanov
parents: 47216
diff changeset
   293
        mv.visitAnnotation(DESCR_HIDDEN, true);
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   294
        new ForwardingMethodGenerator(mv).generate(samMethodType);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   295
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   296
        // 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
   297
        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
   298
            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
   299
                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
   300
                                    mt.toMethodDescriptorString(), null, null);
53435
ea254e9fc587 8213234: Move LambdaForm.Hidden to jdk.internal.vm.annotation
vlivanov
parents: 47216
diff changeset
   301
                mv.visitAnnotation(DESCR_HIDDEN, true);
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   302
                new ForwardingMethodGenerator(mv).generate(mt);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   303
            }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   304
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   305
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   306
        if (isSerializable)
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   307
            generateSerializationFriendlyMethods();
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   308
        else if (accidentallySerializable)
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   309
            generateSerializationHostileMethods();
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   310
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   311
        cw.visitEnd();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   312
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   313
        // Define the generated class in this VM.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   314
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   315
        final byte[] classBytes = cw.toByteArray();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   316
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   317
        // 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
   318
        if (dumper != null) {
29986
97167d851fc4 8078467: Update core libraries to use diamond with anonymous classes
darcy
parents: 28972
diff changeset
   319
            AccessController.doPrivileged(new PrivilegedAction<>() {
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   320
                @Override
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   321
                public Void run() {
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   322
                    dumper.dumpClass(lambdaClassName, classBytes);
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   323
                    return null;
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   324
                }
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   325
            }, null,
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   326
            new FilePermission("<<ALL FILES>>", "read, write"),
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   327
            // createDirectories may need it
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   328
            new PropertyPermission("user.dir", "read"));
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   329
        }
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   330
21300
9a71d04b2d02 8025631: Enhance Lambda construction
rfield
parents: 20748
diff changeset
   331
        return UNSAFE.defineAnonymousClass(targetClass, classBytes, null);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   332
    }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   333
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   334
    /**
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   335
     * 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
   336
     */
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   337
    private void generateFactory() {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   338
        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
   339
        m.visitCode();
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   340
        m.visitTypeInsn(NEW, lambdaClassName);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   341
        m.visitInsn(Opcodes.DUP);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   342
        int parameterCount = invokedType.parameterCount();
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   343
        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
   344
            Class<?> argType = invokedType.parameterType(typeIndex);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   345
            m.visitVarInsn(getLoadOpcode(argType), varIndex);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   346
            varIndex += getParameterSize(argType);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   347
        }
22297
1c62c67d9dd2 8031373: Lint warnings in java.util.stream
briangoetz
parents: 21618
diff changeset
   348
        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
   349
        m.visitInsn(ARETURN);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   350
        m.visitMaxs(-1, -1);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   351
        m.visitEnd();
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   352
    }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   353
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   354
    /**
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   355
     * Generate the constructor for the class
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   356
     */
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   357
    private void generateConstructor() {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   358
        // 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
   359
        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
   360
                                            constructorType.toMethodDescriptorString(), null, null);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   361
        ctor.visitCode();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   362
        ctor.visitVarInsn(ALOAD, 0);
21300
9a71d04b2d02 8025631: Enhance Lambda construction
rfield
parents: 20748
diff changeset
   363
        ctor.visitMethodInsn(INVOKESPECIAL, JAVA_LANG_OBJECT, NAME_CTOR,
22297
1c62c67d9dd2 8031373: Lint warnings in java.util.stream
briangoetz
parents: 21618
diff changeset
   364
                             METHOD_DESCRIPTOR_VOID, false);
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   365
        int parameterCount = invokedType.parameterCount();
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   366
        for (int i = 0, lvIndex = 0; i < parameterCount; i++) {
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   367
            ctor.visitVarInsn(ALOAD, 0);
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   368
            Class<?> argType = invokedType.parameterType(i);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   369
            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
   370
            lvIndex += getParameterSize(argType);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   371
            ctor.visitFieldInsn(PUTFIELD, lambdaClassName, argNames[i], argDescs[i]);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   372
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   373
        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
   374
        // 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
   375
        ctor.visitMaxs(-1, -1);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   376
        ctor.visitEnd();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   377
    }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   378
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   379
    /**
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   380
     * Generate a writeReplace method that supports serialization
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   381
     */
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   382
    private void generateSerializationFriendlyMethods() {
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   383
        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
   384
                = new TypeConvertingMethodAdapter(
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   385
                    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
   386
                    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
   387
                    null, null));
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   388
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   389
        mv.visitCode();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   390
        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
   391
        mv.visitInsn(DUP);
16034
cb5fbea1ecec 8008770: SerializedLambda incorrect class loader for lambda deserializing class
rfield
parents: 16001
diff changeset
   392
        mv.visitLdcInsn(Type.getType(targetClass));
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   393
        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
   394
        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
   395
        mv.visitLdcInsn(samMethodType.toMethodDescriptorString());
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   396
        mv.visitLdcInsn(implInfo.getReferenceKind());
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   397
        mv.visitLdcInsn(implInfo.getDeclaringClass().getName().replace('.', '/'));
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   398
        mv.visitLdcInsn(implInfo.getName());
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   399
        mv.visitLdcInsn(implInfo.getMethodType().toMethodDescriptorString());
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   400
        mv.visitLdcInsn(instantiatedMethodType.toMethodDescriptorString());
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   401
        mv.iconst(argDescs.length);
21300
9a71d04b2d02 8025631: Enhance Lambda construction
rfield
parents: 20748
diff changeset
   402
        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
   403
        for (int i = 0; i < argDescs.length; i++) {
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   404
            mv.visitInsn(DUP);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   405
            mv.iconst(i);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   406
            mv.visitVarInsn(ALOAD, 0);
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   407
            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
   408
            mv.boxIfTypePrimitive(Type.getType(argDescs[i]));
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   409
            mv.visitInsn(AASTORE);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   410
        }
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   411
        mv.visitMethodInsn(INVOKESPECIAL, NAME_SERIALIZED_LAMBDA, NAME_CTOR,
22297
1c62c67d9dd2 8031373: Lint warnings in java.util.stream
briangoetz
parents: 21618
diff changeset
   412
                DESCR_CTOR_SERIALIZED_LAMBDA, false);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   413
        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
   414
        // 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
   415
        mv.visitMaxs(-1, -1);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   416
        mv.visitEnd();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   417
    }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   418
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   419
    /**
21417
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   420
     * 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
   421
     */
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   422
    private void generateSerializationHostileMethods() {
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   423
        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
   424
                                          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
   425
                                          null, SER_HOSTILE_EXCEPTIONS);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   426
        mv.visitCode();
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   427
        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
   428
        mv.visitInsn(DUP);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   429
        mv.visitLdcInsn("Non-serializable lambda");
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   430
        mv.visitMethodInsn(INVOKESPECIAL, NAME_NOT_SERIALIZABLE_EXCEPTION, NAME_CTOR,
22297
1c62c67d9dd2 8031373: Lint warnings in java.util.stream
briangoetz
parents: 21618
diff changeset
   431
                           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
   432
        mv.visitInsn(ATHROW);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   433
        mv.visitMaxs(-1, -1);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   434
        mv.visitEnd();
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   435
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   436
        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
   437
                            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
   438
                            null, SER_HOSTILE_EXCEPTIONS);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   439
        mv.visitCode();
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   440
        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
   441
        mv.visitInsn(DUP);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   442
        mv.visitLdcInsn("Non-serializable lambda");
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   443
        mv.visitMethodInsn(INVOKESPECIAL, NAME_NOT_SERIALIZABLE_EXCEPTION, NAME_CTOR,
22297
1c62c67d9dd2 8031373: Lint warnings in java.util.stream
briangoetz
parents: 21618
diff changeset
   444
                           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
   445
        mv.visitInsn(ATHROW);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   446
        mv.visitMaxs(-1, -1);
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   447
        mv.visitEnd();
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   448
    }
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   449
58b329cea7f2 8027318: Lambda Metafactory: generate serialization-hostile read/writeObject methods for non-serializable lambdas
briangoetz
parents: 21360
diff changeset
   450
    /**
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   451
     * This class generates a method body which calls the lambda implementation
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   452
     * method, converting arguments, as needed.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   453
     */
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   454
    private class ForwardingMethodGenerator extends TypeConvertingMethodAdapter {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   455
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   456
        ForwardingMethodGenerator(MethodVisitor mv) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   457
            super(mv);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   458
        }
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
        void generate(MethodType methodType) {
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   461
            visitCode();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   462
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   463
            if (implKind == MethodHandleInfo.REF_newInvokeSpecial) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   464
                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
   465
                visitInsn(DUP);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   466
            }
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   467
            for (int i = 0; i < argNames.length; i++) {
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   468
                visitVarInsn(ALOAD, 0);
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   469
                visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], argDescs[i]);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   470
            }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   471
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   472
            convertArgumentTypes(methodType);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   473
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   474
            // 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
   475
            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
   476
                            implMethodName, implMethodDesc,
43789
43068ea5965e 8174399: LambdaMetafactory should use types in implMethod.type()
dlsmith
parents: 43703
diff changeset
   477
                            implClass.isInterface());
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   478
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   479
            // 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
   480
            // 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
   481
            // instruction will pop the unneeded result
43789
43068ea5965e 8174399: LambdaMetafactory should use types in implMethod.type()
dlsmith
parents: 43703
diff changeset
   482
            Class<?> implReturnClass = implMethodType.returnType();
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   483
            Class<?> samReturnClass = methodType.returnType();
43789
43068ea5965e 8174399: LambdaMetafactory should use types in implMethod.type()
dlsmith
parents: 43703
diff changeset
   484
            convertType(implReturnClass, samReturnClass, samReturnClass);
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   485
            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
   486
            // 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
   487
            visitMaxs(-1, -1);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   488
            visitEnd();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   489
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   490
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   491
        private void convertArgumentTypes(MethodType samType) {
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   492
            int lvIndex = 0;
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   493
            int samParametersLength = samType.parameterCount();
43789
43068ea5965e 8174399: LambdaMetafactory should use types in implMethod.type()
dlsmith
parents: 43703
diff changeset
   494
            int captureArity = invokedType.parameterCount();
43068ea5965e 8174399: LambdaMetafactory should use types in implMethod.type()
dlsmith
parents: 43703
diff changeset
   495
            for (int i = 0; i < samParametersLength; i++) {
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   496
                Class<?> argType = samType.parameterType(i);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   497
                visitVarInsn(getLoadOpcode(argType), lvIndex + 1);
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   498
                lvIndex += getParameterSize(argType);
43789
43068ea5965e 8174399: LambdaMetafactory should use types in implMethod.type()
dlsmith
parents: 43703
diff changeset
   499
                convertType(argType, implMethodType.parameterType(captureArity + i), instantiatedMethodType.parameterType(i));
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   500
            }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   501
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   502
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   503
        private int invocationOpcode() throws InternalError {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   504
            switch (implKind) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   505
                case MethodHandleInfo.REF_invokeStatic:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   506
                    return INVOKESTATIC;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   507
                case MethodHandleInfo.REF_newInvokeSpecial:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   508
                    return INVOKESPECIAL;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   509
                 case MethodHandleInfo.REF_invokeVirtual:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   510
                    return INVOKEVIRTUAL;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   511
                case MethodHandleInfo.REF_invokeInterface:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   512
                    return INVOKEINTERFACE;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   513
                case MethodHandleInfo.REF_invokeSpecial:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   514
                    return INVOKESPECIAL;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   515
                default:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   516
                    throw new InternalError("Unexpected invocation kind: " + implKind);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   517
            }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   518
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   519
    }
21424
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   520
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   521
    static int getParameterSize(Class<?> c) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   522
        if (c == Void.TYPE) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   523
            return 0;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   524
        } 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
   525
            return 2;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   526
        }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   527
        return 1;
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
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   530
    static int getLoadOpcode(Class<?> c) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   531
        if(c == Void.TYPE) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   532
            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
   533
        }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   534
        return ILOAD + getOpcodeOffset(c);
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
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   537
    static int getReturnOpcode(Class<?> c) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   538
        if(c == Void.TYPE) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   539
            return RETURN;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   540
        }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   541
        return IRETURN + getOpcodeOffset(c);
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
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   544
    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
   545
        if (c.isPrimitive()) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   546
            if (c == Long.TYPE) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   547
                return 1;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   548
            } else if (c == Float.TYPE) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   549
                return 2;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   550
            } else if (c == Double.TYPE) {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   551
                return 3;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   552
            }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   553
            return 0;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   554
        } else {
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   555
            return 4;
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   556
        }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   557
    }
47236f604347 8024637: Lambda linkage performance - use reflection instead of ASM to manipulate parameter types
briangoetz
parents: 21417
diff changeset
   558
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   559
}