src/java.base/share/classes/java/lang/invoke/BootstrapMethodInvoker.java
author redestad
Tue, 20 Feb 2018 17:49:15 +0100
changeset 48921 576e024f10b6
parent 48895 7a1916641c0c
child 48930 b1a5b4ad7427
permissions -rw-r--r--
8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker Reviewed-by: briangoetz, forax, vlivanov
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
48826
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
     1
/*
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
     2
 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
     4
 *
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    10
 *
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    15
 * accompanied this code).
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    16
 *
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    20
 *
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    23
 * questions.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    24
 */
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    25
package java.lang.invoke;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    26
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    27
import sun.invoke.util.Wrapper;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    28
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    29
import java.lang.invoke.AbstractConstantGroup.BSCIWithCache;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    30
import java.util.Arrays;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    31
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    32
import static java.lang.invoke.BootstrapCallInfo.makeBootstrapCallInfo;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    33
import static java.lang.invoke.ConstantGroup.makeConstantGroup;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    34
import static java.lang.invoke.MethodHandleNatives.*;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    35
import static java.lang.invoke.MethodHandleStatics.TRACE_METHOD_LINKAGE;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    36
import static java.lang.invoke.MethodHandles.Lookup;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    37
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    38
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    39
final class BootstrapMethodInvoker {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    40
    /**
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    41
     * Factored code for invoking a bootstrap method for invokedynamic
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    42
     * or a dynamic constant.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    43
     * @param resultType the expected return type (either CallSite or a constant type)
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    44
     * @param bootstrapMethod the BSM to call
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    45
     * @param name the method name or constant name
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    46
     * @param type the method type or constant type
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    47
     * @param info information passed up from the JVM, to derive static arguments
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    48
     * @param callerClass the class containing the resolved method call or constant load
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    49
     * @param <T> the expected return type
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    50
     * @return the expected value, either a CallSite or a constant value
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    51
     */
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    52
    static <T> T invoke(Class<T> resultType,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    53
                        MethodHandle bootstrapMethod,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    54
                        // Callee information:
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    55
                        String name, Object type,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    56
                        // Extra arguments for BSM, if any:
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    57
                        Object info,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    58
                        // Caller information:
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    59
                        Class<?> callerClass) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    60
        MethodHandles.Lookup caller = IMPL_LOOKUP.in(callerClass);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    61
        Object result;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    62
        boolean pullMode = isPullModeBSM(bootstrapMethod);  // default value is false
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    63
        boolean vmIsPushing = !staticArgumentsPulled(info); // default value is true
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    64
        MethodHandle pullModeBSM;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    65
        // match the VM with the BSM
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    66
        if (vmIsPushing) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    67
            // VM is pushing arguments at us
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    68
            pullModeBSM = null;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    69
            if (pullMode) {
48895
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
    70
                bootstrapMethod = pushMePullYou(bootstrapMethod, true);
48826
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    71
            }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    72
        } else {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    73
            // VM wants us to pull args from it
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    74
            pullModeBSM = pullMode ? bootstrapMethod :
48895
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
    75
                    pushMePullYou(bootstrapMethod, false);
48826
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    76
            bootstrapMethod = null;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    77
        }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    78
        try {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    79
            info = maybeReBox(info);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    80
            if (info == null) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    81
                // VM is allowed to pass up a null meaning no BSM args
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    82
                result = bootstrapMethod.invoke(caller, name, type);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    83
            }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    84
            else if (!info.getClass().isArray()) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    85
                // VM is allowed to pass up a single BSM arg directly
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    86
                result = bootstrapMethod.invoke(caller, name, type, info);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    87
            }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    88
            else if (info.getClass() == int[].class) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    89
                // VM is allowed to pass up a pair {argc, index}
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    90
                // referring to 'argc' BSM args at some place 'index'
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    91
                // in the guts of the VM (associated with callerClass).
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    92
                // The format of this index pair is private to the
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    93
                // handshake between the VM and this class only.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    94
                // This supports "pulling" of arguments.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    95
                // The VM is allowed to do this for any reason.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    96
                // The code in this method makes up for any mismatches.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    97
                BootstrapCallInfo<Object> bsci
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    98
                    = new VM_BSCI<>(bootstrapMethod, name, type, caller, (int[])info);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
    99
                // Pull-mode API is (Lookup, BootstrapCallInfo) -> Object
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   100
                result = pullModeBSM.invoke(caller, bsci);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   101
            }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   102
            else {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   103
                // VM is allowed to pass up a full array of resolved BSM args
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   104
                Object[] argv = (Object[]) info;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   105
                maybeReBoxElements(argv);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   106
                switch (argv.length) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   107
                    case 0:
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   108
                        result = bootstrapMethod.invoke(caller, name, type);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   109
                        break;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   110
                    case 1:
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   111
                        result = bootstrapMethod.invoke(caller, name, type,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   112
                                                        argv[0]);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   113
                        break;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   114
                    case 2:
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   115
                        result = bootstrapMethod.invoke(caller, name, type,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   116
                                                        argv[0], argv[1]);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   117
                        break;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   118
                    case 3:
48921
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   119
                        // Special case the LambdaMetafactory::metafactory BSM
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   120
                        //
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   121
                        // By invoking exactly, we can avoid generating a number of
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   122
                        // classes on first (and subsequent) lambda initialization,
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   123
                        // most of which won't be shared with other invoke uses.
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   124
                        MethodType bsmType = bootstrapMethod.type();
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   125
                        if (isLambdaMetafactoryIndyBSM(bsmType)) {
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   126
                            result = (CallSite)bootstrapMethod
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   127
                                    .invokeExact(caller, name, (MethodType)type, (MethodType)argv[0],
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   128
                                                 (MethodHandle)argv[1], (MethodType)argv[2]);
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   129
                        } else if (isLambdaMetafactoryCondyBSM(bsmType)) {
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   130
                            result = bootstrapMethod
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   131
                                    .invokeExact(caller, name, (Class<?>)type, (MethodType)argv[0],
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   132
                                                 (MethodHandle)argv[1], (MethodType)argv[2]);
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   133
                        } else {
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   134
                            result = bootstrapMethod.invoke(caller, name, type,
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   135
                                                            argv[0], argv[1], argv[2]);
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   136
                        }
48826
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   137
                        break;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   138
                    case 4:
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   139
                        result = bootstrapMethod.invoke(caller, name, type,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   140
                                                        argv[0], argv[1], argv[2], argv[3]);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   141
                        break;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   142
                    case 5:
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   143
                        result = bootstrapMethod.invoke(caller, name, type,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   144
                                                        argv[0], argv[1], argv[2], argv[3], argv[4]);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   145
                        break;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   146
                    case 6:
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   147
                        result = bootstrapMethod.invoke(caller, name, type,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   148
                                                        argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   149
                        break;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   150
                    default:
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   151
                        final int NON_SPREAD_ARG_COUNT = 3;  // (caller, name, type)
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   152
                        final int MAX_SAFE_SIZE = MethodType.MAX_MH_ARITY / 2 - NON_SPREAD_ARG_COUNT;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   153
                        if (argv.length >= MAX_SAFE_SIZE) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   154
                            // to be on the safe side, use invokeWithArguments which handles jumbo lists
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   155
                            Object[] newargv = new Object[NON_SPREAD_ARG_COUNT + argv.length];
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   156
                            newargv[0] = caller;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   157
                            newargv[1] = name;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   158
                            newargv[2] = type;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   159
                            System.arraycopy(argv, 0, newargv, NON_SPREAD_ARG_COUNT, argv.length);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   160
                            result = bootstrapMethod.invokeWithArguments(newargv);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   161
                            break;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   162
                        }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   163
                        MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argv.length);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   164
                        MethodHandle typedBSM = bootstrapMethod.asType(invocationType);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   165
                        MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   166
                        result = spreader.invokeExact(typedBSM, (Object) caller, (Object) name, type, argv);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   167
                }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   168
            }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   169
            if (resultType.isPrimitive()) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   170
                // Non-reference conversions are more than just plain casts.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   171
                // By pushing the value through a funnel of the form (T x)->x,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   172
                // the boxed result can be widened as needed.  See MH::asType.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   173
                MethodHandle funnel = MethodHandles.identity(resultType);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   174
                result = funnel.invoke(result);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   175
                // Now it is the wrapper type for resultType.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   176
                resultType = Wrapper.asWrapperType(resultType);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   177
            }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   178
            return resultType.cast(result);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   179
        }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   180
        catch (Error e) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   181
            // Pass through an Error, including BootstrapMethodError, any other
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   182
            // form of linkage error, such as IllegalAccessError if the bootstrap
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   183
            // method is inaccessible, or say ThreadDeath/OutOfMemoryError
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   184
            // See the "Linking Exceptions" section for the invokedynamic
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   185
            // instruction in JVMS 6.5.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   186
            throw e;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   187
        }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   188
        catch (Throwable ex) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   189
            // Wrap anything else in BootstrapMethodError
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   190
            throw new BootstrapMethodError("bootstrap method initialization exception", ex);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   191
        }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   192
    }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   193
48921
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   194
    private static final MethodType LMF_INDY_MT = MethodType.methodType(CallSite.class,
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   195
            Lookup.class, String.class, MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   196
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   197
    private static final MethodType LMF_CONDY_MT = MethodType.methodType(Object.class,
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   198
            Lookup.class, String.class, Class.class, MethodType.class, MethodHandle.class, MethodType.class);
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   199
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   200
    /**
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   201
     * @return true iff the BSM method type exactly matches
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   202
     *         {@see java.lang.invoke.LambdaMetafactory#metafactory(
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   203
     *          MethodHandles.Lookup,String,Class,MethodType,MethodHandle,MethodType)}
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   204
     */
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   205
    private static boolean isLambdaMetafactoryCondyBSM(MethodType bsmType) {
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   206
        return bsmType == LMF_CONDY_MT;
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   207
    }
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   208
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   209
    /**
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   210
     * @return true iff the BSM method type exactly matches
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   211
     *         {@see java.lang.invoke.LambdaMetafactory#metafactory(
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   212
     *          MethodHandles.Lookup,String,MethodType,MethodType,MethodHandle,MethodType)}
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   213
     */
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   214
    private static boolean isLambdaMetafactoryIndyBSM(MethodType bsmType) {
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   215
        return bsmType == LMF_INDY_MT;
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   216
    }
576e024f10b6 8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
redestad
parents: 48895
diff changeset
   217
48826
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   218
    /** The JVM produces java.lang.Integer values to box
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   219
     *  CONSTANT_Integer boxes but does not intern them.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   220
     *  Let's intern them.  This is slightly wrong for
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   221
     *  a {@code CONSTANT_Dynamic} which produces an
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   222
     *  un-interned integer (e.g., {@code new Integer(0)}).
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   223
     */
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   224
    private static Object maybeReBox(Object x) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   225
        if (x instanceof Integer) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   226
            int xi = (int) x;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   227
            if (xi == (byte) xi)
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   228
                x = xi;  // must rebox; see JLS 5.1.7
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   229
        }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   230
        return x;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   231
    }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   232
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   233
    private static void maybeReBoxElements(Object[] xa) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   234
        for (int i = 0; i < xa.length; i++) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   235
            xa[i] = maybeReBox(xa[i]);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   236
        }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   237
    }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   238
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   239
    /** Canonical VM-aware implementation of BootstrapCallInfo.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   240
     * Knows how to dig into the JVM for lazily resolved (pull-mode) constants.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   241
     */
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   242
    private static final class VM_BSCI<T> extends BSCIWithCache<T> {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   243
        private final int[] indexInfo;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   244
        private final Class<?> caller;  // for index resolution only
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   245
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   246
        VM_BSCI(MethodHandle bsm, String name, T type,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   247
                Lookup lookup, int[] indexInfo) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   248
            super(bsm, name, type, indexInfo[0]);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   249
            if (!lookup.hasPrivateAccess())  //D.I.D.
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   250
                throw new AssertionError("bad Lookup object");
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   251
            this.caller = lookup.lookupClass();
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   252
            this.indexInfo = indexInfo;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   253
            // scoop up all the easy stuff right away:
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   254
            prefetchIntoCache(0, size());
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   255
        }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   256
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   257
        @Override Object fillCache(int i) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   258
            Object[] buf = { null };
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   259
            copyConstants(i, i+1, buf, 0);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   260
            Object res = wrapNull(buf[0]);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   261
            cache[i] = res;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   262
            int next = i + 1;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   263
            if (next < cache.length && cache[next] == null)
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   264
                maybePrefetchIntoCache(next, false);  // try to prefetch
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   265
            return res;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   266
        }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   267
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   268
        @Override public int copyConstants(int start, int end,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   269
                                           Object[] buf, int pos) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   270
            int i = start, bufi = pos;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   271
            while (i < end) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   272
                Object x = cache[i];
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   273
                if (x == null)  break;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   274
                buf[bufi++] = unwrapNull(x);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   275
                i++;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   276
            }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   277
            // give up at first null and grab the rest in one big block
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   278
            if (i >= end)  return i;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   279
            Object[] temp = new Object[end - i];
48895
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   280
            if (TRACE_METHOD_LINKAGE) {
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   281
                System.out.println("resolving more BSM arguments: " +
48826
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   282
                        Arrays.asList(caller.getSimpleName(), Arrays.toString(indexInfo), i, end));
48895
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   283
            }
48826
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   284
            copyOutBootstrapArguments(caller, indexInfo,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   285
                                      i, end, temp, 0,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   286
                                      true, null);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   287
            for (Object x : temp) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   288
                x = maybeReBox(x);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   289
                buf[bufi++] = x;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   290
                cache[i++] = wrapNull(x);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   291
            }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   292
            if (end < cache.length && cache[end] == null)
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   293
                maybePrefetchIntoCache(end, true);  // try to prefetch
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   294
            return i;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   295
        }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   296
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   297
        private static final int MIN_PF = 4;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   298
        private void maybePrefetchIntoCache(int i, boolean bulk) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   299
            int len = cache.length;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   300
            assert(0 <= i && i <= len);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   301
            int pfLimit = i;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   302
            if (bulk)  pfLimit += i;  // exponential prefetch expansion
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   303
            // try to prefetch at least MIN_PF elements
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   304
            if (pfLimit < i + MIN_PF)  pfLimit = i + MIN_PF;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   305
            if (pfLimit > len || pfLimit < 0)  pfLimit = len;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   306
            // stop prefetching where cache is more full than empty
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   307
            int empty = 0, nonEmpty = 0, lastEmpty = i;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   308
            for (int j = i; j < pfLimit; j++) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   309
                if (cache[j] == null) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   310
                    empty++;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   311
                    lastEmpty = j;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   312
                } else {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   313
                    nonEmpty++;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   314
                    if (nonEmpty > empty) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   315
                        pfLimit = lastEmpty + 1;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   316
                        break;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   317
                    }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   318
                    if (pfLimit < len)  pfLimit++;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   319
                }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   320
            }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   321
            if (bulk && empty < MIN_PF && pfLimit < len)
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   322
                return;  // not worth the effort
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   323
            prefetchIntoCache(i, pfLimit);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   324
        }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   325
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   326
        private void prefetchIntoCache(int i, int pfLimit) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   327
            if (pfLimit <= i)  return;  // corner case
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   328
            Object[] temp = new Object[pfLimit - i];
48895
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   329
            if (TRACE_METHOD_LINKAGE) {
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   330
                System.out.println("prefetching BSM arguments: " +
48826
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   331
                        Arrays.asList(caller.getSimpleName(), Arrays.toString(indexInfo), i, pfLimit));
48895
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   332
            }
48826
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   333
            copyOutBootstrapArguments(caller, indexInfo,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   334
                                      i, pfLimit, temp, 0,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   335
                                      false, NOT_PRESENT);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   336
            for (Object x : temp) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   337
                if (x != NOT_PRESENT && cache[i] == null) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   338
                    cache[i] = wrapNull(maybeReBox(x));
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   339
                }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   340
                i++;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   341
            }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   342
        }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   343
    }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   344
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   345
    /*non-public*/ static final
48895
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   346
    class PushAdapter {
48826
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   347
        // skeleton for push-mode BSM which wraps a pull-mode BSM:
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   348
        static Object pushToBootstrapMethod(MethodHandle pullModeBSM,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   349
                                            MethodHandles.Lookup lookup, String name, Object type,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   350
                                            Object... arguments) throws Throwable {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   351
            ConstantGroup cons = makeConstantGroup(Arrays.asList(arguments));
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   352
            BootstrapCallInfo<?> bsci = makeBootstrapCallInfo(pullModeBSM, name, type, cons);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   353
            if (TRACE_METHOD_LINKAGE)
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   354
                System.out.println("pull-mode BSM gets pushed arguments from fake BSCI");
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   355
            return pullModeBSM.invoke(lookup, bsci);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   356
        }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   357
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   358
        static final MethodHandle MH_pushToBootstrapMethod;
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   359
        static {
48895
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   360
            final Class<?> THIS_CLASS = PushAdapter.class;
48826
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   361
            try {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   362
                MH_pushToBootstrapMethod = IMPL_LOOKUP
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   363
                    .findStatic(THIS_CLASS, "pushToBootstrapMethod",
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   364
                                MethodType.methodType(Object.class, MethodHandle.class,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   365
                                        Lookup.class, String.class, Object.class, Object[].class));
48895
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   366
            } catch (Throwable ex) {
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   367
                throw new InternalError(ex);
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   368
            }
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   369
        }
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   370
    }
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   371
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   372
    /*non-public*/ static final
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   373
    class PullAdapter {
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   374
        // skeleton for pull-mode BSM which wraps a push-mode BSM:
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   375
        static Object pullFromBootstrapMethod(MethodHandle pushModeBSM,
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   376
                                              MethodHandles.Lookup lookup,
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   377
                                              BootstrapCallInfo<?> bsci)
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   378
                throws Throwable {
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   379
            int argc = bsci.size();
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   380
            switch (argc) {
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   381
                case 0:
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   382
                    return pushModeBSM.invoke(lookup, bsci.invocationName(), bsci.invocationType());
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   383
                case 1:
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   384
                    return pushModeBSM.invoke(lookup, bsci.invocationName(), bsci.invocationType(),
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   385
                            bsci.get(0));
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   386
                case 2:
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   387
                    return pushModeBSM.invoke(lookup, bsci.invocationName(), bsci.invocationType(),
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   388
                            bsci.get(0), bsci.get(1));
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   389
                case 3:
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   390
                    return pushModeBSM.invoke(lookup, bsci.invocationName(), bsci.invocationType(),
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   391
                            bsci.get(0), bsci.get(1), bsci.get(2));
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   392
                case 4:
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   393
                    return pushModeBSM.invoke(lookup, bsci.invocationName(), bsci.invocationType(),
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   394
                            bsci.get(0), bsci.get(1), bsci.get(2), bsci.get(3));
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   395
                case 5:
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   396
                    return pushModeBSM.invoke(lookup, bsci.invocationName(), bsci.invocationType(),
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   397
                            bsci.get(0), bsci.get(1), bsci.get(2), bsci.get(3), bsci.get(4));
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   398
                case 6:
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   399
                    return pushModeBSM.invoke(lookup, bsci.invocationName(), bsci.invocationType(),
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   400
                            bsci.get(0), bsci.get(1), bsci.get(2), bsci.get(3), bsci.get(4), bsci.get(5));
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   401
                default:
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   402
                    final int NON_SPREAD_ARG_COUNT = 3;  // (lookup, name, type)
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   403
                    final int MAX_SAFE_SIZE = MethodType.MAX_MH_ARITY / 2 - NON_SPREAD_ARG_COUNT;
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   404
                    if (argc >= MAX_SAFE_SIZE) {
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   405
                        // to be on the safe side, use invokeWithArguments which handles jumbo lists
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   406
                        Object[] newargv = new Object[NON_SPREAD_ARG_COUNT + argc];
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   407
                        newargv[0] = lookup;
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   408
                        newargv[1] = bsci.invocationName();
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   409
                        newargv[2] = bsci.invocationType();
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   410
                        bsci.copyConstants(0, argc, newargv, NON_SPREAD_ARG_COUNT);
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   411
                        return pushModeBSM.invokeWithArguments(newargv);
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   412
                    }
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   413
                    MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argc);
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   414
                    MethodHandle typedBSM = pushModeBSM.asType(invocationType);
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   415
                    MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT);
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   416
                    Object[] argv = new Object[argc];
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   417
                    bsci.copyConstants(0, argc, argv, 0);
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   418
                    return spreader.invokeExact(typedBSM, (Object) lookup, (Object) bsci.invocationName(), bsci.invocationType(), argv);
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   419
                }
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   420
        }
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   421
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   422
        static final MethodHandle MH_pullFromBootstrapMethod;
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   423
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   424
        static {
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   425
            final Class<?> THIS_CLASS = PullAdapter.class;
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   426
            try {
48826
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   427
                MH_pullFromBootstrapMethod = IMPL_LOOKUP
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   428
                    .findStatic(THIS_CLASS, "pullFromBootstrapMethod",
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   429
                                MethodType.methodType(Object.class, MethodHandle.class,
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   430
                                        Lookup.class, BootstrapCallInfo.class));
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   431
            } catch (Throwable ex) {
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   432
                throw new InternalError(ex);
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   433
            }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   434
        }
48895
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   435
    }
48826
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   436
48895
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   437
    /** Given a push-mode BSM (taking one argument) convert it to a
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   438
     *  pull-mode BSM (taking N pre-resolved arguments).
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   439
     *  This method is used when, in fact, the JVM is passing up
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   440
     *  pre-resolved arguments, but the BSM is expecting lazy stuff.
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   441
     *  Or, when goToPushMode is true, do the reverse transform.
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   442
     *  (The two transforms are exactly inverse.)
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   443
     */
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   444
    static MethodHandle pushMePullYou(MethodHandle bsm, boolean goToPushMode) {
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   445
        if (TRACE_METHOD_LINKAGE) {
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   446
            System.out.println("converting BSM of type " + bsm.type() + " to "
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   447
                    + (goToPushMode ? "push mode" : "pull mode"));
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   448
        }
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   449
        assert(isPullModeBSM(bsm) == goToPushMode); // there must be a change
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   450
        if (goToPushMode) {
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   451
            return PushAdapter.MH_pushToBootstrapMethod.bindTo(bsm).withVarargs(true);
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   452
        } else {
7a1916641c0c 8195850: Improve startup of code to pull arguments from BootstrapMethodInvoker
redestad
parents: 48826
diff changeset
   453
            return PullAdapter.MH_pullFromBootstrapMethod.bindTo(bsm).withVarargs(false);
48826
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   454
        }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   455
    }
c4d9d1b08e2e 8186209: Tool support for ConstantDynamic
psandoz
parents:
diff changeset
   456
}