1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/Invokers.java Sun Aug 17 20:09:05 2014 +0200
1.3 @@ -0,0 +1,462 @@
1.4 +/*
1.5 + * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.lang.invoke;
1.30 +
1.31 +import java.util.Arrays;
1.32 +import sun.invoke.empty.Empty;
1.33 +import static java.lang.invoke.MethodHandleStatics.*;
1.34 +import static java.lang.invoke.MethodHandleNatives.Constants.*;
1.35 +import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
1.36 +import static java.lang.invoke.LambdaForm.*;
1.37 +
1.38 +/**
1.39 + * Construction and caching of often-used invokers.
1.40 + * @author jrose
1.41 + */
1.42 +class Invokers {
1.43 + // exact type (sans leading taget MH) for the outgoing call
1.44 + private final MethodType targetType;
1.45 +
1.46 + // FIXME: Get rid of the invokers that are not useful.
1.47 +
1.48 + // exact invoker for the outgoing call
1.49 + private /*lazy*/ MethodHandle exactInvoker;
1.50 + private /*lazy*/ MethodHandle basicInvoker; // invokeBasic (unchecked exact)
1.51 +
1.52 + // erased (partially untyped but with primitives) invoker for the outgoing call
1.53 + // FIXME: get rid of
1.54 + private /*lazy*/ MethodHandle erasedInvoker;
1.55 + // FIXME: get rid of
1.56 + /*lazy*/ MethodHandle erasedInvokerWithDrops; // for InvokeGeneric
1.57 +
1.58 + // general invoker for the outgoing call
1.59 + private /*lazy*/ MethodHandle generalInvoker;
1.60 +
1.61 + // general invoker for the outgoing call, uses varargs
1.62 + private /*lazy*/ MethodHandle varargsInvoker;
1.63 +
1.64 + // general invoker for the outgoing call; accepts a trailing Object[]
1.65 + private final /*lazy*/ MethodHandle[] spreadInvokers;
1.66 +
1.67 + // invoker for an unbound callsite
1.68 + private /*lazy*/ MethodHandle uninitializedCallSite;
1.69 +
1.70 + /** Compute and cache information common to all collecting adapters
1.71 + * that implement members of the erasure-family of the given erased type.
1.72 + */
1.73 + /*non-public*/ Invokers(MethodType targetType) {
1.74 + this.targetType = targetType;
1.75 + this.spreadInvokers = new MethodHandle[targetType.parameterCount()+1];
1.76 + }
1.77 +
1.78 + /*non-public*/ MethodHandle exactInvoker() {
1.79 + MethodHandle invoker = exactInvoker;
1.80 + if (invoker != null) return invoker;
1.81 + invoker = makeExactOrGeneralInvoker(true);
1.82 + exactInvoker = invoker;
1.83 + return invoker;
1.84 + }
1.85 +
1.86 + /*non-public*/ MethodHandle generalInvoker() {
1.87 + MethodHandle invoker = generalInvoker;
1.88 + if (invoker != null) return invoker;
1.89 + invoker = makeExactOrGeneralInvoker(false);
1.90 + generalInvoker = invoker;
1.91 + return invoker;
1.92 + }
1.93 +
1.94 + private MethodHandle makeExactOrGeneralInvoker(boolean isExact) {
1.95 + MethodType mtype = targetType;
1.96 + MethodType invokerType = mtype.invokerType();
1.97 + int which = (isExact ? MethodTypeForm.LF_EX_INVOKER : MethodTypeForm.LF_GEN_INVOKER);
1.98 + LambdaForm lform = invokeHandleForm(mtype, false, which);
1.99 + MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype);
1.100 + String whichName = (isExact ? "invokeExact" : "invoke");
1.101 + invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke(whichName, mtype));
1.102 + assert(checkInvoker(invoker));
1.103 + maybeCompileToBytecode(invoker);
1.104 + return invoker;
1.105 + }
1.106 +
1.107 + /** If the target type seems to be common enough, eagerly compile the invoker to bytecodes. */
1.108 + private void maybeCompileToBytecode(MethodHandle invoker) {
1.109 + final int EAGER_COMPILE_ARITY_LIMIT = 10;
1.110 + if (targetType == targetType.erase() &&
1.111 + targetType.parameterCount() < EAGER_COMPILE_ARITY_LIMIT) {
1.112 + invoker.form.compileToBytecode();
1.113 + }
1.114 + }
1.115 +
1.116 + /*non-public*/ MethodHandle basicInvoker() {
1.117 + MethodHandle invoker = basicInvoker;
1.118 + if (invoker != null) return invoker;
1.119 + MethodType basicType = targetType.basicType();
1.120 + if (basicType != targetType) {
1.121 + // double cache; not used significantly
1.122 + return basicInvoker = basicType.invokers().basicInvoker();
1.123 + }
1.124 + MemberName method = invokeBasicMethod(basicType);
1.125 + invoker = DirectMethodHandle.make(method);
1.126 + assert(checkInvoker(invoker));
1.127 + basicInvoker = invoker;
1.128 + return invoker;
1.129 + }
1.130 +
1.131 + // This next one is called from LambdaForm.NamedFunction.<init>.
1.132 + /*non-public*/ static MemberName invokeBasicMethod(MethodType basicType) {
1.133 + assert(basicType == basicType.basicType());
1.134 + try {
1.135 + //Lookup.findVirtual(MethodHandle.class, name, type);
1.136 + return IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, MethodHandle.class, "invokeBasic", basicType);
1.137 + } catch (ReflectiveOperationException ex) {
1.138 + throw newInternalError("JVM cannot find invoker for "+basicType, ex);
1.139 + }
1.140 + }
1.141 +
1.142 + private boolean checkInvoker(MethodHandle invoker) {
1.143 + assert(targetType.invokerType().equals(invoker.type()))
1.144 + : java.util.Arrays.asList(targetType, targetType.invokerType(), invoker);
1.145 + assert(invoker.internalMemberName() == null ||
1.146 + invoker.internalMemberName().getMethodType().equals(targetType));
1.147 + assert(!invoker.isVarargsCollector());
1.148 + return true;
1.149 + }
1.150 +
1.151 + // FIXME: get rid of
1.152 + /*non-public*/ MethodHandle erasedInvoker() {
1.153 + MethodHandle xinvoker = exactInvoker();
1.154 + MethodHandle invoker = erasedInvoker;
1.155 + if (invoker != null) return invoker;
1.156 + MethodType erasedType = targetType.erase();
1.157 + invoker = xinvoker.asType(erasedType.invokerType());
1.158 + erasedInvoker = invoker;
1.159 + return invoker;
1.160 + }
1.161 +
1.162 + /*non-public*/ MethodHandle spreadInvoker(int leadingArgCount) {
1.163 + MethodHandle vaInvoker = spreadInvokers[leadingArgCount];
1.164 + if (vaInvoker != null) return vaInvoker;
1.165 + int spreadArgCount = targetType.parameterCount() - leadingArgCount;
1.166 + MethodType spreadInvokerType = targetType
1.167 + .replaceParameterTypes(leadingArgCount, targetType.parameterCount(), Object[].class);
1.168 + if (targetType.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY) {
1.169 + // Factor sinvoker.invoke(mh, a) into ginvoker.asSpreader().invoke(mh, a)
1.170 + // where ginvoker.invoke(mh, a*) => mh.invoke(a*).
1.171 + MethodHandle genInvoker = generalInvoker();
1.172 + vaInvoker = genInvoker.asSpreader(Object[].class, spreadArgCount);
1.173 + } else {
1.174 + // Cannot build a general invoker here of type ginvoker.invoke(mh, a*[254]).
1.175 + // Instead, factor sinvoker.invoke(mh, a) into ainvoker.invoke(filter(mh), a)
1.176 + // where filter(mh) == mh.asSpreader(Object[], spreadArgCount)
1.177 + MethodHandle arrayInvoker = MethodHandles.exactInvoker(spreadInvokerType);
1.178 + MethodHandle makeSpreader;
1.179 + try {
1.180 + makeSpreader = IMPL_LOOKUP
1.181 + .findVirtual(MethodHandle.class, "asSpreader",
1.182 + MethodType.methodType(MethodHandle.class, Class.class, int.class));
1.183 + } catch (ReflectiveOperationException ex) {
1.184 + throw newInternalError(ex);
1.185 + }
1.186 + makeSpreader = MethodHandles.insertArguments(makeSpreader, 1, Object[].class, spreadArgCount);
1.187 + vaInvoker = MethodHandles.filterArgument(arrayInvoker, 0, makeSpreader);
1.188 + }
1.189 + assert(vaInvoker.type().equals(spreadInvokerType.invokerType()));
1.190 + maybeCompileToBytecode(vaInvoker);
1.191 + spreadInvokers[leadingArgCount] = vaInvoker;
1.192 + return vaInvoker;
1.193 + }
1.194 +
1.195 + /*non-public*/ MethodHandle varargsInvoker() {
1.196 + MethodHandle vaInvoker = varargsInvoker;
1.197 + if (vaInvoker != null) return vaInvoker;
1.198 + vaInvoker = spreadInvoker(0).asType(MethodType.genericMethodType(0, true).invokerType());
1.199 + varargsInvoker = vaInvoker;
1.200 + return vaInvoker;
1.201 + }
1.202 +
1.203 + private static MethodHandle THROW_UCS = null;
1.204 +
1.205 + /*non-public*/ MethodHandle uninitializedCallSite() {
1.206 + MethodHandle invoker = uninitializedCallSite;
1.207 + if (invoker != null) return invoker;
1.208 + if (targetType.parameterCount() > 0) {
1.209 + MethodType type0 = targetType.dropParameterTypes(0, targetType.parameterCount());
1.210 + Invokers invokers0 = type0.invokers();
1.211 + invoker = MethodHandles.dropArguments(invokers0.uninitializedCallSite(),
1.212 + 0, targetType.parameterList());
1.213 + assert(invoker.type().equals(targetType));
1.214 + uninitializedCallSite = invoker;
1.215 + return invoker;
1.216 + }
1.217 + invoker = THROW_UCS;
1.218 + if (invoker == null) {
1.219 + try {
1.220 + THROW_UCS = invoker = IMPL_LOOKUP
1.221 + .findStatic(CallSite.class, "uninitializedCallSite",
1.222 + MethodType.methodType(Empty.class));
1.223 + } catch (ReflectiveOperationException ex) {
1.224 + throw newInternalError(ex);
1.225 + }
1.226 + }
1.227 + invoker = MethodHandles.explicitCastArguments(invoker, MethodType.methodType(targetType.returnType()));
1.228 + invoker = invoker.dropArguments(targetType, 0, targetType.parameterCount());
1.229 + assert(invoker.type().equals(targetType));
1.230 + uninitializedCallSite = invoker;
1.231 + return invoker;
1.232 + }
1.233 +
1.234 + public String toString() {
1.235 + return "Invokers"+targetType;
1.236 + }
1.237 +
1.238 + static MemberName methodHandleInvokeLinkerMethod(String name,
1.239 + MethodType mtype,
1.240 + Object[] appendixResult) {
1.241 + int which;
1.242 + switch (name) {
1.243 + case "invokeExact": which = MethodTypeForm.LF_EX_LINKER; break;
1.244 + case "invoke": which = MethodTypeForm.LF_GEN_LINKER; break;
1.245 + default: throw new InternalError("not invoker: "+name);
1.246 + }
1.247 + LambdaForm lform;
1.248 + if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) {
1.249 + lform = invokeHandleForm(mtype, false, which);
1.250 + appendixResult[0] = mtype;
1.251 + } else {
1.252 + lform = invokeHandleForm(mtype, true, which);
1.253 + }
1.254 + return lform.vmentry;
1.255 + }
1.256 +
1.257 + // argument count to account for trailing "appendix value" (typically the mtype)
1.258 + private static final int MH_LINKER_ARG_APPENDED = 1;
1.259 +
1.260 + /** Returns an adapter for invokeExact or generic invoke, as a MH or constant pool linker.
1.261 + * If !customized, caller is responsible for supplying, during adapter execution,
1.262 + * a copy of the exact mtype. This is because the adapter might be generalized to
1.263 + * a basic type.
1.264 + * @param mtype the caller's method type (either basic or full-custom)
1.265 + * @param customized whether to use a trailing appendix argument (to carry the mtype)
1.266 + * @param which bit-encoded 0x01 whether it is a CP adapter ("linker") or MHs.invoker value ("invoker");
1.267 + * 0x02 whether it is for invokeExact or generic invoke
1.268 + */
1.269 + private static LambdaForm invokeHandleForm(MethodType mtype, boolean customized, int which) {
1.270 + boolean isCached;
1.271 + if (!customized) {
1.272 + mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.
1.273 + isCached = true;
1.274 + } else {
1.275 + isCached = false; // maybe cache if mtype == mtype.basicType()
1.276 + }
1.277 + boolean isLinker, isGeneric;
1.278 + String debugName;
1.279 + switch (which) {
1.280 + case MethodTypeForm.LF_EX_LINKER: isLinker = true; isGeneric = false; debugName = "invokeExact_MT"; break;
1.281 + case MethodTypeForm.LF_EX_INVOKER: isLinker = false; isGeneric = false; debugName = "exactInvoker"; break;
1.282 + case MethodTypeForm.LF_GEN_LINKER: isLinker = true; isGeneric = true; debugName = "invoke_MT"; break;
1.283 + case MethodTypeForm.LF_GEN_INVOKER: isLinker = false; isGeneric = true; debugName = "invoker"; break;
1.284 + default: throw new InternalError();
1.285 + }
1.286 + LambdaForm lform;
1.287 + if (isCached) {
1.288 + lform = mtype.form().cachedLambdaForm(which);
1.289 + if (lform != null) return lform;
1.290 + }
1.291 + // exactInvokerForm (Object,Object)Object
1.292 + // link with java.lang.invoke.MethodHandle.invokeBasic(MethodHandle,Object,Object)Object/invokeSpecial
1.293 + final int THIS_MH = 0;
1.294 + final int CALL_MH = THIS_MH + (isLinker ? 0 : 1);
1.295 + final int ARG_BASE = CALL_MH + 1;
1.296 + final int OUTARG_LIMIT = ARG_BASE + mtype.parameterCount();
1.297 + final int INARG_LIMIT = OUTARG_LIMIT + (isLinker && !customized ? 1 : 0);
1.298 + int nameCursor = OUTARG_LIMIT;
1.299 + final int MTYPE_ARG = customized ? -1 : nameCursor++; // might be last in-argument
1.300 + final int CHECK_TYPE = nameCursor++;
1.301 + final int LINKER_CALL = nameCursor++;
1.302 + MethodType invokerFormType = mtype.invokerType();
1.303 + if (isLinker) {
1.304 + if (!customized)
1.305 + invokerFormType = invokerFormType.appendParameterTypes(MemberName.class);
1.306 + } else {
1.307 + invokerFormType = invokerFormType.invokerType();
1.308 + }
1.309 + Name[] names = arguments(nameCursor - INARG_LIMIT, invokerFormType);
1.310 + assert(names.length == nameCursor)
1.311 + : Arrays.asList(mtype, customized, which, nameCursor, names.length);
1.312 + if (MTYPE_ARG >= INARG_LIMIT) {
1.313 + assert(names[MTYPE_ARG] == null);
1.314 + NamedFunction getter = BoundMethodHandle.getSpeciesData("L").getterFunction(0);
1.315 + names[MTYPE_ARG] = new Name(getter, names[THIS_MH]);
1.316 + // else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM)
1.317 + }
1.318 +
1.319 + // Make the final call. If isGeneric, then prepend the result of type checking.
1.320 + MethodType outCallType = mtype.basicType();
1.321 + Object[] outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
1.322 + Object mtypeArg = (customized ? mtype : names[MTYPE_ARG]);
1.323 + if (!isGeneric) {
1.324 + names[CHECK_TYPE] = new Name(NF_checkExactType, names[CALL_MH], mtypeArg);
1.325 + // mh.invokeExact(a*):R => checkExactType(mh, TYPEOF(a*:R)); mh.invokeBasic(a*)
1.326 + } else {
1.327 + names[CHECK_TYPE] = new Name(NF_checkGenericType, names[CALL_MH], mtypeArg);
1.328 + // mh.invokeGeneric(a*):R => checkGenericType(mh, TYPEOF(a*:R)).invokeBasic(a*)
1.329 + outArgs[0] = names[CHECK_TYPE];
1.330 + }
1.331 + names[LINKER_CALL] = new Name(outCallType, outArgs);
1.332 + lform = new LambdaForm(debugName, INARG_LIMIT, names);
1.333 + if (isLinker)
1.334 + lform.compileToBytecode(); // JVM needs a real methodOop
1.335 + if (isCached)
1.336 + lform = mtype.form().setCachedLambdaForm(which, lform);
1.337 + return lform;
1.338 + }
1.339 +
1.340 + /*non-public*/ static
1.341 + WrongMethodTypeException newWrongMethodTypeException(MethodType actual, MethodType expected) {
1.342 + // FIXME: merge with JVM logic for throwing WMTE
1.343 + return new WrongMethodTypeException("expected "+expected+" but found "+actual);
1.344 + }
1.345 +
1.346 + /** Static definition of MethodHandle.invokeExact checking code. */
1.347 + /*non-public*/ static
1.348 + @ForceInline
1.349 + void checkExactType(Object mhObj, Object expectedObj) {
1.350 + MethodHandle mh = (MethodHandle) mhObj;
1.351 + MethodType expected = (MethodType) expectedObj;
1.352 + MethodType actual = mh.type();
1.353 + if (actual != expected)
1.354 + throw newWrongMethodTypeException(expected, actual);
1.355 + }
1.356 +
1.357 + /** Static definition of MethodHandle.invokeGeneric checking code.
1.358 + * Directly returns the type-adjusted MH to invoke, as follows:
1.359 + * {@code (R)MH.invoke(a*) => MH.asType(TYPEOF(a*:R)).invokeBasic(a*)}
1.360 + */
1.361 + /*non-public*/ static
1.362 + @ForceInline
1.363 + Object checkGenericType(Object mhObj, Object expectedObj) {
1.364 + MethodHandle mh = (MethodHandle) mhObj;
1.365 + MethodType expected = (MethodType) expectedObj;
1.366 + if (mh.type() == expected) return mh;
1.367 + MethodHandle atc = mh.asTypeCache;
1.368 + if (atc != null && atc.type() == expected) return atc;
1.369 + return mh.asType(expected);
1.370 + /* Maybe add more paths here. Possible optimizations:
1.371 + * for (R)MH.invoke(a*),
1.372 + * let MT0 = TYPEOF(a*:R), MT1 = MH.type
1.373 + *
1.374 + * if MT0==MT1 or MT1 can be safely called by MT0
1.375 + * => MH.invokeBasic(a*)
1.376 + * if MT1 can be safely called by MT0[R := Object]
1.377 + * => MH.invokeBasic(a*) & checkcast(R)
1.378 + * if MT1 can be safely called by MT0[* := Object]
1.379 + * => checkcast(A)* & MH.invokeBasic(a*) & checkcast(R)
1.380 + * if a big adapter BA can be pulled out of (MT0,MT1)
1.381 + * => BA.invokeBasic(MT0,MH,a*)
1.382 + * if a local adapter LA can cached on static CS0 = new GICS(MT0)
1.383 + * => CS0.LA.invokeBasic(MH,a*)
1.384 + * else
1.385 + * => MH.asType(MT0).invokeBasic(A*)
1.386 + */
1.387 + }
1.388 +
1.389 + static MemberName linkToCallSiteMethod(MethodType mtype) {
1.390 + LambdaForm lform = callSiteForm(mtype, false);
1.391 + return lform.vmentry;
1.392 + }
1.393 +
1.394 + static MemberName linkToTargetMethod(MethodType mtype) {
1.395 + LambdaForm lform = callSiteForm(mtype, true);
1.396 + return lform.vmentry;
1.397 + }
1.398 +
1.399 + // skipCallSite is true if we are optimizing a ConstantCallSite
1.400 + private static LambdaForm callSiteForm(MethodType mtype, boolean skipCallSite) {
1.401 + mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.
1.402 + final int which = (skipCallSite ? MethodTypeForm.LF_MH_LINKER : MethodTypeForm.LF_CS_LINKER);
1.403 + LambdaForm lform = mtype.form().cachedLambdaForm(which);
1.404 + if (lform != null) return lform;
1.405 + // exactInvokerForm (Object,Object)Object
1.406 + // link with java.lang.invoke.MethodHandle.invokeBasic(MethodHandle,Object,Object)Object/invokeSpecial
1.407 + final int ARG_BASE = 0;
1.408 + final int OUTARG_LIMIT = ARG_BASE + mtype.parameterCount();
1.409 + final int INARG_LIMIT = OUTARG_LIMIT + 1;
1.410 + int nameCursor = OUTARG_LIMIT;
1.411 + final int APPENDIX_ARG = nameCursor++; // the last in-argument
1.412 + final int CSITE_ARG = skipCallSite ? -1 : APPENDIX_ARG;
1.413 + final int CALL_MH = skipCallSite ? APPENDIX_ARG : nameCursor++; // result of getTarget
1.414 + final int LINKER_CALL = nameCursor++;
1.415 + MethodType invokerFormType = mtype.appendParameterTypes(skipCallSite ? MethodHandle.class : CallSite.class);
1.416 + Name[] names = arguments(nameCursor - INARG_LIMIT, invokerFormType);
1.417 + assert(names.length == nameCursor);
1.418 + assert(names[APPENDIX_ARG] != null);
1.419 + if (!skipCallSite)
1.420 + names[CALL_MH] = new Name(NF_getCallSiteTarget, names[CSITE_ARG]);
1.421 + // (site.)invokedynamic(a*):R => mh = site.getTarget(); mh.invokeBasic(a*)
1.422 + final int PREPEND_MH = 0, PREPEND_COUNT = 1;
1.423 + Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, OUTARG_LIMIT + PREPEND_COUNT, Object[].class);
1.424 + // prepend MH argument:
1.425 + System.arraycopy(outArgs, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT);
1.426 + outArgs[PREPEND_MH] = names[CALL_MH];
1.427 + names[LINKER_CALL] = new Name(mtype, outArgs);
1.428 + lform = new LambdaForm((skipCallSite ? "linkToTargetMethod" : "linkToCallSite"), INARG_LIMIT, names);
1.429 + lform.compileToBytecode(); // JVM needs a real methodOop
1.430 + lform = mtype.form().setCachedLambdaForm(which, lform);
1.431 + return lform;
1.432 + }
1.433 +
1.434 + /** Static definition of MethodHandle.invokeGeneric checking code. */
1.435 + /*non-public*/ static
1.436 + @ForceInline
1.437 + Object getCallSiteTarget(Object site) {
1.438 + return ((CallSite)site).getTarget();
1.439 + }
1.440 +
1.441 + // Local constant functions:
1.442 + private static final NamedFunction NF_checkExactType;
1.443 + private static final NamedFunction NF_checkGenericType;
1.444 + private static final NamedFunction NF_asType;
1.445 + private static final NamedFunction NF_getCallSiteTarget;
1.446 + static {
1.447 + try {
1.448 + NF_checkExactType = new NamedFunction(Invokers.class
1.449 + .getDeclaredMethod("checkExactType", Object.class, Object.class));
1.450 + NF_checkGenericType = new NamedFunction(Invokers.class
1.451 + .getDeclaredMethod("checkGenericType", Object.class, Object.class));
1.452 + NF_asType = new NamedFunction(MethodHandle.class
1.453 + .getDeclaredMethod("asType", MethodType.class));
1.454 + NF_getCallSiteTarget = new NamedFunction(Invokers.class
1.455 + .getDeclaredMethod("getCallSiteTarget", Object.class));
1.456 + NF_checkExactType.resolve();
1.457 + NF_checkGenericType.resolve();
1.458 + NF_getCallSiteTarget.resolve();
1.459 + // bound
1.460 + } catch (ReflectiveOperationException ex) {
1.461 + throw newInternalError(ex);
1.462 + }
1.463 + }
1.464 +
1.465 +}