1 /*
   2  * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 import jdk.internal.access.JavaLangAccess;
  29 import jdk.internal.access.SharedSecrets;
  30 import jdk.internal.ref.CleanerFactory;
  31 import sun.invoke.util.Wrapper;
  32 
  33 import java.lang.invoke.MethodHandles.Lookup;
  34 import java.lang.reflect.Field;
  35 
  36 import static java.lang.invoke.MethodHandleNatives.Constants.*;
  37 import static java.lang.invoke.MethodHandleStatics.TRACE_METHOD_LINKAGE;
  38 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
  39 
  40 /**
  41  * The JVM interface for the method handles package is all here.
  42  * This is an interface internal and private to an implementation of JSR 292.
  43  * <em>This class is not part of the JSR 292 standard.</em>
  44  * @author jrose
  45  */
  46 class MethodHandleNatives {
  47 
  48     private MethodHandleNatives() { } // static only
  49 
  50     /// MemberName support
  51 
  52     static native void init(MemberName self, Object ref);
  53     static native void expand(MemberName self);
  54     static native MemberName resolve(MemberName self, Class<?> caller,
  55             boolean speculativeResolve) throws LinkageError, ClassNotFoundException;
  56     static native int getMembers(Class<?> defc, String matchName, String matchSig,
  57             int matchFlags, Class<?> caller, int skip, MemberName[] results);
  58 
  59     /// Field layout queries parallel to jdk.internal.misc.Unsafe:
  60     static native long objectFieldOffset(MemberName self);  // e.g., returns vmindex
  61     static native long staticFieldOffset(MemberName self);  // e.g., returns vmindex
  62     static native Object staticFieldBase(MemberName self);  // e.g., returns clazz
  63     static native Object getMemberVMInfo(MemberName self);  // returns {vmindex,vmtarget}
  64 
  65     /// CallSite support
  66 
  67     /** Tell the JVM that we need to change the target of a CallSite. */
  68     static native void setCallSiteTargetNormal(CallSite site, MethodHandle target);
  69     static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target);
  70 
  71     static native void copyOutBootstrapArguments(Class<?> caller, int[] indexInfo,
  72                                                  int start, int end,
  73                                                  Object[] buf, int pos,
  74                                                  boolean resolve,
  75                                                  Object ifNotAvailable);
  76 
  77     /** Represents a context to track nmethod dependencies on CallSite instance target. */
  78     static class CallSiteContext implements Runnable {
  79         //@Injected JVM_nmethodBucket* vmdependencies;
  80         //@Injected jlong last_cleanup;
  81 
  82         static CallSiteContext make(CallSite cs) {
  83             final CallSiteContext newContext = new CallSiteContext();
  84             // CallSite instance is tracked by a Cleanable which clears native
  85             // structures allocated for CallSite context. Though the CallSite can
  86             // become unreachable, its Context is retained by the Cleanable instance
  87             // (which is referenced from Cleaner instance which is referenced from
  88             // CleanerFactory class) until cleanup is performed.
  89             CleanerFactory.cleaner().register(cs, newContext);
  90             return newContext;
  91         }
  92 
  93         @Override
  94         public void run() {
  95             MethodHandleNatives.clearCallSiteContext(this);
  96         }
  97     }
  98 
  99     /** Invalidate all recorded nmethods. */
 100     private static native void clearCallSiteContext(CallSiteContext context);
 101 
 102     private static native void registerNatives();
 103     static {
 104         registerNatives();
 105     }
 106 
 107     /**
 108      * Compile-time constants go here. This collection exists not only for
 109      * reference from clients, but also for ensuring the VM and JDK agree on the
 110      * values of these constants (see {@link #verifyConstants()}).
 111      */
 112     static class Constants {
 113         Constants() { } // static only
 114 
 115         static final int
 116             MN_IS_METHOD           = 0x00010000, // method (not constructor)
 117             MN_IS_CONSTRUCTOR      = 0x00020000, // constructor
 118             MN_IS_FIELD            = 0x00040000, // field
 119             MN_IS_TYPE             = 0x00080000, // nested type
 120             MN_CALLER_SENSITIVE    = 0x00100000, // @CallerSensitive annotation detected
 121             MN_REFERENCE_KIND_SHIFT = 24, // refKind
 122             MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
 123             // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
 124             MN_SEARCH_SUPERCLASSES = 0x00100000,
 125             MN_SEARCH_INTERFACES   = 0x00200000;
 126 
 127         /**
 128          * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
 129          */
 130         static final byte
 131             REF_NONE                    = 0,  // null value
 132             REF_getField                = 1,
 133             REF_getStatic               = 2,
 134             REF_putField                = 3,
 135             REF_putStatic               = 4,
 136             REF_invokeVirtual           = 5,
 137             REF_invokeStatic            = 6,
 138             REF_invokeSpecial           = 7,
 139             REF_newInvokeSpecial        = 8,
 140             REF_invokeInterface         = 9,
 141             REF_LIMIT                  = 10;
 142 
 143         /**
 144          * Flags for Lookup.ClassOptions
 145          */
 146         static final int
 147             NESTMATE_CLASS            = 0x00000001,
 148             HIDDEN_CLASS              = 0x00000002,
 149             STRONG_LOADER_LINK        = 0x00000004,
 150             ACCESS_VM_ANNOTATIONS     = 0x00000008;
 151     }
 152 
 153     static boolean refKindIsValid(int refKind) {
 154         return (refKind > REF_NONE && refKind < REF_LIMIT);
 155     }
 156     static boolean refKindIsField(byte refKind) {
 157         assert(refKindIsValid(refKind));
 158         return (refKind <= REF_putStatic);
 159     }
 160     static boolean refKindIsGetter(byte refKind) {
 161         assert(refKindIsValid(refKind));
 162         return (refKind <= REF_getStatic);
 163     }
 164     static boolean refKindIsSetter(byte refKind) {
 165         return refKindIsField(refKind) && !refKindIsGetter(refKind);
 166     }
 167     static boolean refKindIsMethod(byte refKind) {
 168         return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial);
 169     }
 170     static boolean refKindIsConstructor(byte refKind) {
 171         return (refKind == REF_newInvokeSpecial);
 172     }
 173     static boolean refKindHasReceiver(byte refKind) {
 174         assert(refKindIsValid(refKind));
 175         return (refKind & 1) != 0;
 176     }
 177     static boolean refKindIsStatic(byte refKind) {
 178         return !refKindHasReceiver(refKind) && (refKind != REF_newInvokeSpecial);
 179     }
 180     static boolean refKindDoesDispatch(byte refKind) {
 181         assert(refKindIsValid(refKind));
 182         return (refKind == REF_invokeVirtual ||
 183                 refKind == REF_invokeInterface);
 184     }
 185     static {
 186         final int HR_MASK = ((1 << REF_getField) |
 187                              (1 << REF_putField) |
 188                              (1 << REF_invokeVirtual) |
 189                              (1 << REF_invokeSpecial) |
 190                              (1 << REF_invokeInterface)
 191                             );
 192         for (byte refKind = REF_NONE+1; refKind < REF_LIMIT; refKind++) {
 193             assert(refKindHasReceiver(refKind) == (((1<<refKind) & HR_MASK) != 0)) : refKind;
 194         }
 195     }
 196     static String refKindName(byte refKind) {
 197         assert(refKindIsValid(refKind));
 198         switch (refKind) {
 199         case REF_getField:          return "getField";
 200         case REF_getStatic:         return "getStatic";
 201         case REF_putField:          return "putField";
 202         case REF_putStatic:         return "putStatic";
 203         case REF_invokeVirtual:     return "invokeVirtual";
 204         case REF_invokeStatic:      return "invokeStatic";
 205         case REF_invokeSpecial:     return "invokeSpecial";
 206         case REF_newInvokeSpecial:  return "newInvokeSpecial";
 207         case REF_invokeInterface:   return "invokeInterface";
 208         default:                    return "REF_???";
 209         }
 210     }
 211 
 212     private static native int getNamedCon(int which, Object[] name);
 213     static boolean verifyConstants() {
 214         Object[] box = { null };
 215         for (int i = 0; ; i++) {
 216             box[0] = null;
 217             int vmval = getNamedCon(i, box);
 218             if (box[0] == null)  break;
 219             String name = (String) box[0];
 220             try {
 221                 Field con = Constants.class.getDeclaredField(name);
 222                 int jval = con.getInt(null);
 223                 if (jval == vmval)  continue;
 224                 String err = (name+": JVM has "+vmval+" while Java has "+jval);
 225                 if (name.equals("CONV_OP_LIMIT")) {
 226                     System.err.println("warning: "+err);
 227                     continue;
 228                 }
 229                 throw new InternalError(err);
 230             } catch (NoSuchFieldException | IllegalAccessException ex) {
 231                 String err = (name+": JVM has "+vmval+" which Java does not define");
 232                 // ignore exotic ops the JVM cares about; we just wont issue them
 233                 //System.err.println("warning: "+err);
 234                 continue;
 235             }
 236         }
 237         return true;
 238     }
 239     static {
 240         assert(verifyConstants());
 241     }
 242 
 243     // Up-calls from the JVM.
 244     // These must NOT be public.
 245 
 246     /**
 247      * The JVM is linking an invokedynamic instruction.  Create a reified call site for it.
 248      */
 249     static MemberName linkCallSite(Object callerObj,
 250                                    int indexInCP,
 251                                    Object bootstrapMethodObj,
 252                                    Object nameObj, Object typeObj,
 253                                    Object staticArguments,
 254                                    Object[] appendixResult) {
 255         MethodHandle bootstrapMethod = (MethodHandle)bootstrapMethodObj;
 256         Class<?> caller = (Class<?>)callerObj;
 257         String name = nameObj.toString().intern();
 258         MethodType type = (MethodType)typeObj;
 259         if (!TRACE_METHOD_LINKAGE)
 260             return linkCallSiteImpl(caller, bootstrapMethod, name, type,
 261                                     staticArguments, appendixResult);
 262         return linkCallSiteTracing(caller, bootstrapMethod, name, type,
 263                                    staticArguments, appendixResult);
 264     }
 265     static MemberName linkCallSiteImpl(Class<?> caller,
 266                                        MethodHandle bootstrapMethod,
 267                                        String name, MethodType type,
 268                                        Object staticArguments,
 269                                        Object[] appendixResult) {
 270         CallSite callSite = CallSite.makeSite(bootstrapMethod,
 271                                               name,
 272                                               type,
 273                                               staticArguments,
 274                                               caller);
 275         if (callSite instanceof ConstantCallSite) {
 276             appendixResult[0] = callSite.dynamicInvoker();
 277             return Invokers.linkToTargetMethod(type);
 278         } else {
 279             appendixResult[0] = callSite;
 280             return Invokers.linkToCallSiteMethod(type);
 281         }
 282     }
 283     // Tracing logic:
 284     static MemberName linkCallSiteTracing(Class<?> caller,
 285                                           MethodHandle bootstrapMethod,
 286                                           String name, MethodType type,
 287                                           Object staticArguments,
 288                                           Object[] appendixResult) {
 289         Object bsmReference = bootstrapMethod.internalMemberName();
 290         if (bsmReference == null)  bsmReference = bootstrapMethod;
 291         String staticArglist = staticArglistForTrace(staticArguments);
 292         System.out.println("linkCallSite "+caller.getName()+" "+
 293                            bsmReference+" "+
 294                            name+type+"/"+staticArglist);
 295         try {
 296             MemberName res = linkCallSiteImpl(caller, bootstrapMethod, name, type,
 297                                               staticArguments, appendixResult);
 298             System.out.println("linkCallSite => "+res+" + "+appendixResult[0]);
 299             return res;
 300         } catch (Throwable ex) {
 301             ex.printStackTrace(); // print now in case exception is swallowed
 302             System.out.println("linkCallSite => throw "+ex);
 303             throw ex;
 304         }
 305     }
 306 
 307     // this implements the upcall from the JVM, MethodHandleNatives.linkDynamicConstant:
 308     static Object linkDynamicConstant(Object callerObj,
 309                                       int indexInCP,
 310                                       Object bootstrapMethodObj,
 311                                       Object nameObj, Object typeObj,
 312                                       Object staticArguments) {
 313         MethodHandle bootstrapMethod = (MethodHandle)bootstrapMethodObj;
 314         Class<?> caller = (Class<?>)callerObj;
 315         String name = nameObj.toString().intern();
 316         Class<?> type = (Class<?>)typeObj;
 317         if (!TRACE_METHOD_LINKAGE)
 318             return linkDynamicConstantImpl(caller, bootstrapMethod, name, type, staticArguments);
 319         return linkDynamicConstantTracing(caller, bootstrapMethod, name, type, staticArguments);
 320     }
 321 
 322     static Object linkDynamicConstantImpl(Class<?> caller,
 323                                           MethodHandle bootstrapMethod,
 324                                           String name, Class<?> type,
 325                                           Object staticArguments) {
 326         return ConstantBootstraps.makeConstant(bootstrapMethod, name, type, staticArguments, caller);
 327     }
 328 
 329     private static String staticArglistForTrace(Object staticArguments) {
 330         if (staticArguments instanceof Object[])
 331             return "BSA="+java.util.Arrays.asList((Object[]) staticArguments);
 332         if (staticArguments instanceof int[])
 333             return "BSA@"+java.util.Arrays.toString((int[]) staticArguments);
 334         if (staticArguments == null)
 335             return "BSA0=null";
 336         return "BSA1="+staticArguments;
 337     }
 338 
 339     // Tracing logic:
 340     static Object linkDynamicConstantTracing(Class<?> caller,
 341                                              MethodHandle bootstrapMethod,
 342                                              String name, Class<?> type,
 343                                              Object staticArguments) {
 344         Object bsmReference = bootstrapMethod.internalMemberName();
 345         if (bsmReference == null)  bsmReference = bootstrapMethod;
 346         String staticArglist = staticArglistForTrace(staticArguments);
 347         System.out.println("linkDynamicConstant "+caller.getName()+" "+
 348                            bsmReference+" "+
 349                            name+type+"/"+staticArglist);
 350         try {
 351             Object res = linkDynamicConstantImpl(caller, bootstrapMethod, name, type, staticArguments);
 352             System.out.println("linkDynamicConstantImpl => "+res);
 353             return res;
 354         } catch (Throwable ex) {
 355             ex.printStackTrace(); // print now in case exception is swallowed
 356             System.out.println("linkDynamicConstant => throw "+ex);
 357             throw ex;
 358         }
 359     }
 360 
 361     /** The JVM is requesting pull-mode bootstrap when it provides
 362      *  a tuple of the form int[]{ argc, vmindex }.
 363      *  The BSM is expected to call back to the JVM using the caller
 364      *  class and vmindex to resolve the static arguments.
 365      */
 366     static boolean staticArgumentsPulled(Object staticArguments) {
 367         return staticArguments instanceof int[];
 368     }
 369 
 370     /** A BSM runs in pull-mode if and only if its sole arguments
 371      * are (Lookup, BootstrapCallInfo), or can be converted pairwise
 372      * to those types, and it is not of variable arity.
 373      * Excluding error cases, we can just test that the arity is a constant 2.
 374      *
 375      * NOTE: This method currently returns false, since pulling is not currently
 376      * exposed to a BSM. When pull mode is supported the method block will be
 377      * replaced with currently commented out code.
 378      */
 379     static boolean isPullModeBSM(MethodHandle bsm) {
 380         return false;
 381 //        return bsm.type().parameterCount() == 2 && !bsm.isVarargsCollector();
 382     }
 383 
 384     /**
 385      * The JVM wants a pointer to a MethodType.  Oblige it by finding or creating one.
 386      */
 387     static MethodType findMethodHandleType(Class<?> rtype, Class<?>[] ptypes) {
 388         return MethodType.makeImpl(rtype, ptypes, true);
 389     }
 390 
 391     /**
 392      * The JVM wants to link a call site that requires a dynamic type check.
 393      * Name is a type-checking invoker, invokeExact or invoke.
 394      * Return a JVM method (MemberName) to handle the invoking.
 395      * The method assumes the following arguments on the stack:
 396      * 0: the method handle being invoked
 397      * 1-N: the arguments to the method handle invocation
 398      * N+1: an optional, implicitly added argument (typically the given MethodType)
 399      * <p>
 400      * The nominal method at such a call site is an instance of
 401      * a signature-polymorphic method (see @PolymorphicSignature).
 402      * Such method instances are user-visible entities which are
 403      * "split" from the generic placeholder method in {@code MethodHandle}.
 404      * (Note that the placeholder method is not identical with any of
 405      * its instances.  If invoked reflectively, is guaranteed to throw an
 406      * {@code UnsupportedOperationException}.)
 407      * If the signature-polymorphic method instance is ever reified,
 408      * it appears as a "copy" of the original placeholder
 409      * (a native final member of {@code MethodHandle}) except
 410      * that its type descriptor has shape required by the instance,
 411      * and the method instance is <em>not</em> varargs.
 412      * The method instance is also marked synthetic, since the
 413      * method (by definition) does not appear in Java source code.
 414      * <p>
 415      * The JVM is allowed to reify this method as instance metadata.
 416      * For example, {@code invokeBasic} is always reified.
 417      * But the JVM may instead call {@code linkMethod}.
 418      * If the result is an * ordered pair of a {@code (method, appendix)},
 419      * the method gets all the arguments (0..N inclusive)
 420      * plus the appendix (N+1), and uses the appendix to complete the call.
 421      * In this way, one reusable method (called a "linker method")
 422      * can perform the function of any number of polymorphic instance
 423      * methods.
 424      * <p>
 425      * Linker methods are allowed to be weakly typed, with any or
 426      * all references rewritten to {@code Object} and any primitives
 427      * (except {@code long}/{@code float}/{@code double})
 428      * rewritten to {@code int}.
 429      * A linker method is trusted to return a strongly typed result,
 430      * according to the specific method type descriptor of the
 431      * signature-polymorphic instance it is emulating.
 432      * This can involve (as necessary) a dynamic check using
 433      * data extracted from the appendix argument.
 434      * <p>
 435      * The JVM does not inspect the appendix, other than to pass
 436      * it verbatim to the linker method at every call.
 437      * This means that the JDK runtime has wide latitude
 438      * for choosing the shape of each linker method and its
 439      * corresponding appendix.
 440      * Linker methods should be generated from {@code LambdaForm}s
 441      * so that they do not become visible on stack traces.
 442      * <p>
 443      * The {@code linkMethod} call is free to omit the appendix
 444      * (returning null) and instead emulate the required function
 445      * completely in the linker method.
 446      * As a corner case, if N==255, no appendix is possible.
 447      * In this case, the method returned must be custom-generated to
 448      * perform any needed type checking.
 449      * <p>
 450      * If the JVM does not reify a method at a call site, but instead
 451      * calls {@code linkMethod}, the corresponding call represented
 452      * in the bytecodes may mention a valid method which is not
 453      * representable with a {@code MemberName}.
 454      * Therefore, use cases for {@code linkMethod} tend to correspond to
 455      * special cases in reflective code such as {@code findVirtual}
 456      * or {@code revealDirect}.
 457      */
 458     static MemberName linkMethod(Class<?> callerClass, int refKind,
 459                                  Class<?> defc, String name, Object type,
 460                                  Object[] appendixResult) {
 461         if (!TRACE_METHOD_LINKAGE)
 462             return linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
 463         return linkMethodTracing(callerClass, refKind, defc, name, type, appendixResult);
 464     }
 465     static MemberName linkMethodImpl(Class<?> callerClass, int refKind,
 466                                      Class<?> defc, String name, Object type,
 467                                      Object[] appendixResult) {
 468         try {
 469             if (refKind == REF_invokeVirtual) {
 470                 if (defc == MethodHandle.class) {
 471                     return Invokers.methodHandleInvokeLinkerMethod(
 472                             name, fixMethodType(callerClass, type), appendixResult);
 473                 } else if (defc == VarHandle.class) {
 474                     return varHandleOperationLinkerMethod(
 475                             name, fixMethodType(callerClass, type), appendixResult);
 476                 }
 477             }
 478         } catch (Error e) {
 479             // Pass through an Error, including say StackOverflowError or
 480             // OutOfMemoryError
 481             throw e;
 482         } catch (Throwable ex) {
 483             // Wrap anything else in LinkageError
 484             throw new LinkageError(ex.getMessage(), ex);
 485         }
 486         throw new LinkageError("no such method "+defc.getName()+"."+name+type);
 487     }
 488     private static MethodType fixMethodType(Class<?> callerClass, Object type) {
 489         if (type instanceof MethodType)
 490             return (MethodType) type;
 491         else
 492             return MethodType.fromDescriptor((String)type, callerClass.getClassLoader());
 493     }
 494     // Tracing logic:
 495     static MemberName linkMethodTracing(Class<?> callerClass, int refKind,
 496                                         Class<?> defc, String name, Object type,
 497                                         Object[] appendixResult) {
 498         System.out.println("linkMethod "+defc.getName()+"."+
 499                            name+type+"/"+Integer.toHexString(refKind));
 500         try {
 501             MemberName res = linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
 502             System.out.println("linkMethod => "+res+" + "+appendixResult[0]);
 503             return res;
 504         } catch (Throwable ex) {
 505             System.out.println("linkMethod => throw "+ex);
 506             throw ex;
 507         }
 508     }
 509 
 510     /**
 511      * Obtain the method to link to the VarHandle operation.
 512      * This method is located here and not in Invokers to avoid
 513      * intializing that and other classes early on in VM bootup.
 514      */
 515     private static MemberName varHandleOperationLinkerMethod(String name,
 516                                                              MethodType mtype,
 517                                                              Object[] appendixResult) {
 518         // Get the signature method type
 519         final MethodType sigType = mtype.basicType();
 520 
 521         // Get the access kind from the method name
 522         VarHandle.AccessMode ak;
 523         try {
 524             ak = VarHandle.AccessMode.valueFromMethodName(name);
 525         } catch (IllegalArgumentException e) {
 526             throw MethodHandleStatics.newInternalError(e);
 527         }
 528 
 529         // Create the appendix descriptor constant
 530         VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal());
 531         appendixResult[0] = ad;
 532 
 533         if (MethodHandleStatics.VAR_HANDLE_GUARDS) {
 534             // If not polymorphic in the return type, such as the compareAndSet
 535             // methods that return boolean
 536             Class<?> guardReturnType = sigType.returnType();
 537             if (ak.at.isMonomorphicInReturnType) {
 538                 if (ak.at.returnType != mtype.returnType()) {
 539                     // The caller contains a different return type than that
 540                     // defined by the method
 541                     throw newNoSuchMethodErrorOnVarHandle(name, mtype);
 542                 }
 543                 // Adjust the return type of the signature method type
 544                 guardReturnType = ak.at.returnType;
 545             }
 546 
 547             // Get the guard method type for linking
 548             final Class<?>[] guardParams = new Class<?>[sigType.parameterCount() + 2];
 549             // VarHandle at start
 550             guardParams[0] = VarHandle.class;
 551             for (int i = 0; i < sigType.parameterCount(); i++) {
 552                 guardParams[i + 1] = sigType.parameterType(i);
 553             }
 554             // Access descriptor at end
 555             guardParams[guardParams.length - 1] = VarHandle.AccessDescriptor.class;
 556             MethodType guardType = MethodType.makeImpl(guardReturnType, guardParams, true);
 557 
 558             MemberName linker = new MemberName(
 559                     VarHandleGuards.class, getVarHandleGuardMethodName(guardType),
 560                     guardType, REF_invokeStatic);
 561 
 562             linker = MemberName.getFactory().resolveOrNull(REF_invokeStatic, linker,
 563                                                            VarHandleGuards.class);
 564             if (linker != null) {
 565                 return linker;
 566             }
 567             // Fall back to lambda form linkage if guard method is not available
 568             // TODO Optionally log fallback ?
 569         }
 570         return Invokers.varHandleInvokeLinkerMethod(ak, mtype);
 571     }
 572     static String getVarHandleGuardMethodName(MethodType guardType) {
 573         String prefix = "guard_";
 574         StringBuilder sb = new StringBuilder(prefix.length() + guardType.parameterCount());
 575 
 576         sb.append(prefix);
 577         for (int i = 1; i < guardType.parameterCount() - 1; i++) {
 578             Class<?> pt = guardType.parameterType(i);
 579             sb.append(getCharType(pt));
 580         }
 581         sb.append('_').append(getCharType(guardType.returnType()));
 582         return sb.toString();
 583     }
 584     static char getCharType(Class<?> pt) {
 585         return Wrapper.forBasicType(pt).basicTypeChar();
 586     }
 587     static NoSuchMethodError newNoSuchMethodErrorOnVarHandle(String name, MethodType mtype) {
 588         return new NoSuchMethodError("VarHandle." + name + mtype);
 589     }
 590 
 591     /**
 592      * The JVM is resolving a CONSTANT_MethodHandle CP entry.  And it wants our help.
 593      * It will make an up-call to this method.  (Do not change the name or signature.)
 594      * The type argument is a Class for field requests and a MethodType for non-fields.
 595      * <p>
 596      * Recent versions of the JVM may also pass a resolved MemberName for the type.
 597      * In that case, the name is ignored and may be null.
 598      */
 599     static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
 600                                                  Class<?> defc, String name, Object type) {
 601         try {
 602             Lookup lookup = IMPL_LOOKUP.in(callerClass);
 603             assert(refKindIsValid(refKind));
 604             return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type);
 605         } catch (ReflectiveOperationException ex) {
 606             throw mapLookupExceptionToError(ex);
 607         }
 608     }
 609 
 610     /**
 611      * Map a reflective exception to a linkage error.
 612      */
 613     static LinkageError mapLookupExceptionToError(ReflectiveOperationException ex) {
 614         LinkageError err;
 615         if (ex instanceof IllegalAccessException) {
 616             Throwable cause = ex.getCause();
 617             if (cause instanceof AbstractMethodError) {
 618                 return (AbstractMethodError) cause;
 619             } else {
 620                 err = new IllegalAccessError(ex.getMessage());
 621             }
 622         } else if (ex instanceof NoSuchMethodException) {
 623             err = new NoSuchMethodError(ex.getMessage());
 624         } else if (ex instanceof NoSuchFieldException) {
 625             err = new NoSuchFieldError(ex.getMessage());
 626         } else {
 627             err = new IncompatibleClassChangeError();
 628         }
 629         return initCauseFrom(err, ex);
 630     }
 631 
 632     /**
 633      * Use best possible cause for err.initCause(), substituting the
 634      * cause for err itself if the cause has the same (or better) type.
 635      */
 636     static <E extends Error> E initCauseFrom(E err, Exception ex) {
 637         Throwable th = ex.getCause();
 638         @SuppressWarnings("unchecked")
 639         final Class<E> Eclass = (Class<E>) err.getClass();
 640         if (Eclass.isInstance(th))
 641            return Eclass.cast(th);
 642         err.initCause(th == null ? ex : th);
 643         return err;
 644     }
 645 
 646     /**
 647      * Is this method a caller-sensitive method?
 648      * I.e., does it call Reflection.getCallerClass or a similar method
 649      * to ask about the identity of its caller?
 650      */
 651     static boolean isCallerSensitive(MemberName mem) {
 652         if (!mem.isInvocable())  return false;  // fields are not caller sensitive
 653 
 654         return mem.isCallerSensitive() || canBeCalledVirtual(mem);
 655     }
 656 
 657     static boolean canBeCalledVirtual(MemberName mem) {
 658         assert(mem.isInvocable());
 659         switch (mem.getName()) {
 660         case "getContextClassLoader":
 661             return canBeCalledVirtual(mem, java.lang.Thread.class);
 662         }
 663         return false;
 664     }
 665 
 666     static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) {
 667         Class<?> symbolicRefClass = symbolicRef.getDeclaringClass();
 668         if (symbolicRefClass == definingClass)  return true;
 669         if (symbolicRef.isStatic() || symbolicRef.isPrivate())  return false;
 670         return (definingClass.isAssignableFrom(symbolicRefClass) ||  // Msym overrides Mdef
 671                 symbolicRefClass.isInterface());                     // Mdef implements Msym
 672     }
 673 
 674     private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
 675     /*
 676      * A convenient method for LambdaForms to get the class data of a given class.
 677      * LambdaForms cannot use condy via MethodHandles.classData
 678      */
 679     static Object classData(Class<?> c) {
 680         return JLA.classData(c);
 681     }
 682 }