rt/emul/compact/src/main/java/java/lang/invoke/MethodHandleNatives.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 12 Aug 2014 20:51:09 +0200
branchjdk8
changeset 1669 139267156f32
parent 1661 6d5075e5ceac
child 1670 b913b6b415a0
permissions -rw-r--r--
The bootstrap method gets called with three arguments
     1 /*
     2  * Copyright (c) 2008, 2013, 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 static java.lang.invoke.MethodHandleNatives.Constants.*;
    29 import static java.lang.invoke.MethodHandleStatics.*;
    30 import java.lang.invoke.MethodHandles.Lookup;
    31 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
    32 import java.lang.reflect.Constructor;
    33 import java.lang.reflect.Field;
    34 import java.lang.reflect.Method;
    35 
    36 /**
    37  * The JVM interface for the method handles package is all here.
    38  * This is an interface internal and private to an implementation of JSR 292.
    39  * <em>This class is not part of the JSR 292 standard.</em>
    40  * @author jrose
    41  */
    42 class MethodHandleNatives {
    43 
    44     private MethodHandleNatives() { } // static only
    45 
    46     /// MemberName support
    47 
    48     static void init(MemberName self, Object ref) {
    49     }
    50     
    51     static void expand(MemberName self) {
    52     }
    53     
    54     static MemberName resolve(MemberName self, Class<?> caller) throws LinkageError {
    55         return self;
    56     }
    57     static int getMembers(Class<?> defc, String matchName, String matchSig,
    58             int matchFlags, Class<?> caller, int skip, MemberName[] results) {
    59         int orig = skip;
    60         for (Method m : defc.getMethods()) {
    61             if (skip == results.length) {
    62                 break;
    63             }
    64             MemberName mn = new MemberName(m);
    65             results[skip++] = mn;
    66         }
    67         for (Constructor m : defc.getConstructors()) {
    68             if (skip == results.length) {
    69                 break;
    70             }
    71             MemberName mn = new MemberName(m);
    72             results[skip++] = mn;
    73         }
    74         for (Field m : defc.getFields()) {
    75             if (skip == results.length) {
    76                 break;
    77             }
    78             MemberName mn = new MemberName(m);
    79             results[skip++] = mn;
    80         }
    81         return skip - orig;
    82     }
    83 
    84     /// Field layout queries parallel to sun.misc.Unsafe:
    85     static native long objectFieldOffset(MemberName self);  // e.g., returns vmindex
    86     static native long staticFieldOffset(MemberName self);  // e.g., returns vmindex
    87     static native Object staticFieldBase(MemberName self);  // e.g., returns clazz
    88     static native Object getMemberVMInfo(MemberName self);  // returns {vmindex,vmtarget}
    89 
    90     /// MethodHandle support
    91 
    92     /// CallSite support
    93 
    94     /** Tell the JVM that we need to change the target of a CallSite. */
    95     static native void setCallSiteTargetNormal(CallSite site, MethodHandle target);
    96     static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target);
    97 
    98     static {
    99         // The JVM calls MethodHandleNatives.<clinit>.  Cascade the <clinit> calls as needed:
   100         MethodHandleImpl.initStatics();
   101 }
   102 
   103     // All compile-time constants go here.
   104     // There is an opportunity to check them against the JVM's idea of them.
   105     static class Constants {
   106         Constants() { } // static only
   107         // MethodHandleImpl
   108         static final int // for getConstant
   109                 GC_COUNT_GWT = 4,
   110                 GC_LAMBDA_SUPPORT = 5;
   111 
   112         // MemberName
   113         // The JVM uses values of -2 and above for vtable indexes.
   114         // Field values are simple positive offsets.
   115         // Ref: src/share/vm/oops/methodOop.hpp
   116         // This value is negative enough to avoid such numbers,
   117         // but not too negative.
   118         static final int
   119                 MN_IS_METHOD           = 0x00010000, // method (not constructor)
   120                 MN_IS_CONSTRUCTOR      = 0x00020000, // constructor
   121                 MN_IS_FIELD            = 0x00040000, // field
   122                 MN_IS_TYPE             = 0x00080000, // nested type
   123                 MN_CALLER_SENSITIVE    = 0x00100000, // @CallerSensitive annotation detected
   124                 MN_REFERENCE_KIND_SHIFT = 24, // refKind
   125                 MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
   126                 // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
   127                 MN_SEARCH_SUPERCLASSES = 0x00100000,
   128                 MN_SEARCH_INTERFACES   = 0x00200000;
   129 
   130         /**
   131          * Basic types as encoded in the JVM.  These code values are not
   132          * intended for use outside this class.  They are used as part of
   133          * a private interface between the JVM and this class.
   134          */
   135         static final int
   136             T_BOOLEAN  =  4,
   137             T_CHAR     =  5,
   138             T_FLOAT    =  6,
   139             T_DOUBLE   =  7,
   140             T_BYTE     =  8,
   141             T_SHORT    =  9,
   142             T_INT      = 10,
   143             T_LONG     = 11,
   144             T_OBJECT   = 12,
   145             //T_ARRAY    = 13
   146             T_VOID     = 14,
   147             //T_ADDRESS  = 15
   148             T_ILLEGAL  = 99;
   149 
   150         /**
   151          * Constant pool entry types.
   152          */
   153         static final byte
   154             CONSTANT_Utf8                = 1,
   155             CONSTANT_Integer             = 3,
   156             CONSTANT_Float               = 4,
   157             CONSTANT_Long                = 5,
   158             CONSTANT_Double              = 6,
   159             CONSTANT_Class               = 7,
   160             CONSTANT_String              = 8,
   161             CONSTANT_Fieldref            = 9,
   162             CONSTANT_Methodref           = 10,
   163             CONSTANT_InterfaceMethodref  = 11,
   164             CONSTANT_NameAndType         = 12,
   165             CONSTANT_MethodHandle        = 15,  // JSR 292
   166             CONSTANT_MethodType          = 16,  // JSR 292
   167             CONSTANT_InvokeDynamic       = 18,
   168             CONSTANT_LIMIT               = 19;   // Limit to tags found in classfiles
   169 
   170         /**
   171          * Access modifier flags.
   172          */
   173         static final char
   174             ACC_PUBLIC                 = 0x0001,
   175             ACC_PRIVATE                = 0x0002,
   176             ACC_PROTECTED              = 0x0004,
   177             ACC_STATIC                 = 0x0008,
   178             ACC_FINAL                  = 0x0010,
   179             ACC_SYNCHRONIZED           = 0x0020,
   180             ACC_VOLATILE               = 0x0040,
   181             ACC_TRANSIENT              = 0x0080,
   182             ACC_NATIVE                 = 0x0100,
   183             ACC_INTERFACE              = 0x0200,
   184             ACC_ABSTRACT               = 0x0400,
   185             ACC_STRICT                 = 0x0800,
   186             ACC_SYNTHETIC              = 0x1000,
   187             ACC_ANNOTATION             = 0x2000,
   188             ACC_ENUM                   = 0x4000,
   189             // aliases:
   190             ACC_SUPER                  = ACC_SYNCHRONIZED,
   191             ACC_BRIDGE                 = ACC_VOLATILE,
   192             ACC_VARARGS                = ACC_TRANSIENT;
   193 
   194         /**
   195          * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
   196          */
   197         static final byte
   198             REF_NONE                    = 0,  // null value
   199             REF_getField                = 1,
   200             REF_getStatic               = 2,
   201             REF_putField                = 3,
   202             REF_putStatic               = 4,
   203             REF_invokeVirtual           = 5,
   204             REF_invokeStatic            = 6,
   205             REF_invokeSpecial           = 7,
   206             REF_newInvokeSpecial        = 8,
   207             REF_invokeInterface         = 9,
   208             REF_LIMIT                  = 10;
   209     }
   210 
   211     static boolean refKindIsValid(int refKind) {
   212         return (refKind > REF_NONE && refKind < REF_LIMIT);
   213     }
   214     static boolean refKindIsField(byte refKind) {
   215         assert(refKindIsValid(refKind));
   216         return (refKind <= REF_putStatic);
   217     }
   218     static boolean refKindIsGetter(byte refKind) {
   219         assert(refKindIsValid(refKind));
   220         return (refKind <= REF_getStatic);
   221     }
   222     static boolean refKindIsSetter(byte refKind) {
   223         return refKindIsField(refKind) && !refKindIsGetter(refKind);
   224     }
   225     static boolean refKindIsMethod(byte refKind) {
   226         return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial);
   227     }
   228     static boolean refKindIsConstructor(byte refKind) {
   229         return (refKind == REF_newInvokeSpecial);
   230     }
   231     static boolean refKindHasReceiver(byte refKind) {
   232         assert(refKindIsValid(refKind));
   233         return (refKind & 1) != 0;
   234     }
   235     static boolean refKindIsStatic(byte refKind) {
   236         return !refKindHasReceiver(refKind) && (refKind != REF_newInvokeSpecial);
   237     }
   238     static boolean refKindDoesDispatch(byte refKind) {
   239         assert(refKindIsValid(refKind));
   240         return (refKind == REF_invokeVirtual ||
   241                 refKind == REF_invokeInterface);
   242     }
   243     static {
   244         final int HR_MASK = ((1 << REF_getField) |
   245                              (1 << REF_putField) |
   246                              (1 << REF_invokeVirtual) |
   247                              (1 << REF_invokeSpecial) |
   248                              (1 << REF_invokeInterface)
   249                             );
   250         for (byte refKind = REF_NONE+1; refKind < REF_LIMIT; refKind++) {
   251             assert(refKindHasReceiver(refKind) == (((1<<refKind) & HR_MASK) != 0)) : refKind;
   252         }
   253     }
   254     static String refKindName(byte refKind) {
   255         assert(refKindIsValid(refKind));
   256         switch (refKind) {
   257         case REF_getField:          return "getField";
   258         case REF_getStatic:         return "getStatic";
   259         case REF_putField:          return "putField";
   260         case REF_putStatic:         return "putStatic";
   261         case REF_invokeVirtual:     return "invokeVirtual";
   262         case REF_invokeStatic:      return "invokeStatic";
   263         case REF_invokeSpecial:     return "invokeSpecial";
   264         case REF_newInvokeSpecial:  return "newInvokeSpecial";
   265         case REF_invokeInterface:   return "invokeInterface";
   266         default:                    return "REF_???";
   267         }
   268     }
   269 
   270     private static native int getNamedCon(int which, Object[] name);
   271     static boolean verifyConstants() {
   272         Object[] box = { null };
   273         for (int i = 0; ; i++) {
   274             box[0] = null;
   275             int vmval = getNamedCon(i, box);
   276             if (box[0] == null)  break;
   277             String name = (String) box[0];
   278             try {
   279                 Field con = Constants.class.getDeclaredField(name);
   280                 int jval = con.getInt(null);
   281                 if (jval == vmval)  continue;
   282                 String err = (name+": JVM has "+vmval+" while Java has "+jval);
   283                 if (name.equals("CONV_OP_LIMIT")) {
   284                     System.err.println("warning: "+err);
   285                     continue;
   286                 }
   287                 throw new InternalError(err);
   288             } catch (IllegalAccessException ex) {
   289                 String err = (name+": JVM has "+vmval+" which Java does not define");
   290                 // ignore exotic ops the JVM cares about; we just wont issue them
   291                 //System.err.println("warning: "+err);
   292                 continue;
   293             }
   294         }
   295         return true;
   296     }
   297     static {
   298         assert(verifyConstants());
   299     }
   300 
   301     // Up-calls from the JVM.
   302     // These must NOT be public.
   303 
   304     /**
   305      * The JVM is linking an invokedynamic instruction.  Create a reified call site for it.
   306      */
   307     static MemberName linkCallSite(Object callerObj,
   308                                    Object bootstrapMethodObj,
   309                                    Object nameObj, Object typeObj,
   310                                    Object staticArguments,
   311                                    Object[] appendixResult) {
   312         MethodHandle bootstrapMethod = (MethodHandle)bootstrapMethodObj;
   313         Class<?> caller = (Class<?>)callerObj;
   314         String name = nameObj.toString().intern();
   315         MethodType type = (MethodType)typeObj;
   316         CallSite callSite = CallSite.makeSite(bootstrapMethod,
   317                                               name,
   318                                               type,
   319                                               staticArguments,
   320                                               caller);
   321         if (callSite instanceof ConstantCallSite) {
   322             appendixResult[0] = callSite.dynamicInvoker();
   323             return Invokers.linkToTargetMethod(type);
   324         } else {
   325             appendixResult[0] = callSite;
   326             return Invokers.linkToCallSiteMethod(type);
   327         }
   328     }
   329 
   330     /**
   331      * The JVM wants a pointer to a MethodType.  Oblige it by finding or creating one.
   332      */
   333     static MethodType findMethodHandleType(Class<?> rtype, Class<?>[] ptypes) {
   334         return MethodType.makeImpl(rtype, ptypes, true);
   335     }
   336 
   337     /**
   338      * The JVM wants to link a call site that requires a dynamic type check.
   339      * Name is a type-checking invoker, invokeExact or invoke.
   340      * Return a JVM method (MemberName) to handle the invoking.
   341      * The method assumes the following arguments on the stack:
   342      * 0: the method handle being invoked
   343      * 1-N: the arguments to the method handle invocation
   344      * N+1: an optional, implicitly added argument (typically the given MethodType)
   345      * <p>
   346      * The nominal method at such a call site is an instance of
   347      * a signature-polymorphic method (see @PolymorphicSignature).
   348      * Such method instances are user-visible entities which are
   349      * "split" from the generic placeholder method in {@code MethodHandle}.
   350      * (Note that the placeholder method is not identical with any of
   351      * its instances.  If invoked reflectively, is guaranteed to throw an
   352      * {@code UnsupportedOperationException}.)
   353      * If the signature-polymorphic method instance is ever reified,
   354      * it appears as a "copy" of the original placeholder
   355      * (a native final member of {@code MethodHandle}) except
   356      * that its type descriptor has shape required by the instance,
   357      * and the method instance is <em>not</em> varargs.
   358      * The method instance is also marked synthetic, since the
   359      * method (by definition) does not appear in Java source code.
   360      * <p>
   361      * The JVM is allowed to reify this method as instance metadata.
   362      * For example, {@code invokeBasic} is always reified.
   363      * But the JVM may instead call {@code linkMethod}.
   364      * If the result is an * ordered pair of a {@code (method, appendix)},
   365      * the method gets all the arguments (0..N inclusive)
   366      * plus the appendix (N+1), and uses the appendix to complete the call.
   367      * In this way, one reusable method (called a "linker method")
   368      * can perform the function of any number of polymorphic instance
   369      * methods.
   370      * <p>
   371      * Linker methods are allowed to be weakly typed, with any or
   372      * all references rewritten to {@code Object} and any primitives
   373      * (except {@code long}/{@code float}/{@code double})
   374      * rewritten to {@code int}.
   375      * A linker method is trusted to return a strongly typed result,
   376      * according to the specific method type descriptor of the
   377      * signature-polymorphic instance it is emulating.
   378      * This can involve (as necessary) a dynamic check using
   379      * data extracted from the appendix argument.
   380      * <p>
   381      * The JVM does not inspect the appendix, other than to pass
   382      * it verbatim to the linker method at every call.
   383      * This means that the JDK runtime has wide latitude
   384      * for choosing the shape of each linker method and its
   385      * corresponding appendix.
   386      * Linker methods should be generated from {@code LambdaForm}s
   387      * so that they do not become visible on stack traces.
   388      * <p>
   389      * The {@code linkMethod} call is free to omit the appendix
   390      * (returning null) and instead emulate the required function
   391      * completely in the linker method.
   392      * As a corner case, if N==255, no appendix is possible.
   393      * In this case, the method returned must be custom-generated to
   394      * to perform any needed type checking.
   395      * <p>
   396      * If the JVM does not reify a method at a call site, but instead
   397      * calls {@code linkMethod}, the corresponding call represented
   398      * in the bytecodes may mention a valid method which is not
   399      * representable with a {@code MemberName}.
   400      * Therefore, use cases for {@code linkMethod} tend to correspond to
   401      * special cases in reflective code such as {@code findVirtual}
   402      * or {@code revealDirect}.
   403      */
   404     static MemberName linkMethod(Class<?> callerClass, int refKind,
   405                                  Class<?> defc, String name, Object type,
   406                                  Object[] appendixResult) {
   407         if (!TRACE_METHOD_LINKAGE)
   408             return linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
   409         return linkMethodTracing(callerClass, refKind, defc, name, type, appendixResult);
   410     }
   411     static MemberName linkMethodImpl(Class<?> callerClass, int refKind,
   412                                      Class<?> defc, String name, Object type,
   413                                      Object[] appendixResult) {
   414         try {
   415             if (defc == MethodHandle.class && refKind == REF_invokeVirtual) {
   416                 return Invokers.methodHandleInvokeLinkerMethod(name, fixMethodType(callerClass, type), appendixResult);
   417             }
   418         } catch (Throwable ex) {
   419             if (ex instanceof LinkageError)
   420                 throw (LinkageError) ex;
   421             else
   422                 throw new LinkageError(ex.getMessage(), ex);
   423         }
   424         throw new LinkageError("no such method "+defc.getName()+"."+name+type);
   425     }
   426     private static MethodType fixMethodType(Class<?> callerClass, Object type) {
   427         if (type instanceof MethodType)
   428             return (MethodType) type;
   429         else
   430             return MethodType.fromMethodDescriptorString((String)type, callerClass.getClassLoader());
   431     }
   432     // Tracing logic:
   433     static MemberName linkMethodTracing(Class<?> callerClass, int refKind,
   434                                         Class<?> defc, String name, Object type,
   435                                         Object[] appendixResult) {
   436         System.out.println("linkMethod "+defc.getName()+"."+
   437                            name+type+"/"+Integer.toHexString(refKind));
   438         try {
   439             MemberName res = linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
   440             System.out.println("linkMethod => "+res+" + "+appendixResult[0]);
   441             return res;
   442         } catch (Throwable ex) {
   443             System.out.println("linkMethod => throw "+ex);
   444             throw ex;
   445         }
   446     }
   447 
   448 
   449     /**
   450      * The JVM is resolving a CONSTANT_MethodHandle CP entry.  And it wants our help.
   451      * It will make an up-call to this method.  (Do not change the name or signature.)
   452      * The type argument is a Class for field requests and a MethodType for non-fields.
   453      * <p>
   454      * Recent versions of the JVM may also pass a resolved MemberName for the type.
   455      * In that case, the name is ignored and may be null.
   456      */
   457     static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
   458                                                  Class<?> defc, String name, Object type) {
   459         try {
   460             Lookup lookup = IMPL_LOOKUP.in(callerClass);
   461             assert(refKindIsValid(refKind));
   462             return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type);
   463         } catch (IllegalAccessException ex) {
   464             Throwable cause = ex.getCause();
   465             if (cause instanceof AbstractMethodError) {
   466                 throw (AbstractMethodError) cause;
   467             } else {
   468                 Error err = new IllegalAccessError(ex.getMessage());
   469                 throw initCauseFrom(err, ex);
   470             }
   471         } catch (NoSuchMethodException ex) {
   472             Error err = new NoSuchMethodError(ex.getMessage());
   473             throw initCauseFrom(err, ex);
   474         } catch (NoSuchFieldException ex) {
   475             Error err = new NoSuchFieldError(ex.getMessage());
   476             throw initCauseFrom(err, ex);
   477         } catch (ReflectiveOperationException ex) {
   478             Error err = new IncompatibleClassChangeError();
   479             throw initCauseFrom(err, ex);
   480         }
   481     }
   482 
   483     /**
   484      * Use best possible cause for err.initCause(), substituting the
   485      * cause for err itself if the cause has the same (or better) type.
   486      */
   487     static private Error initCauseFrom(Error err, Exception ex) {
   488         Throwable th = ex.getCause();
   489         if (err.getClass().isInstance(th))
   490            return (Error) th;
   491         err.initCause(th == null ? ex : th);
   492         return err;
   493     }
   494 
   495     /**
   496      * Is this method a caller-sensitive method?
   497      * I.e., does it call Reflection.getCallerClass or a similer method
   498      * to ask about the identity of its caller?
   499      */
   500     static boolean isCallerSensitive(MemberName mem) {
   501         if (!mem.isInvocable())  return false;  // fields are not caller sensitive
   502 
   503         return mem.isCallerSensitive() || canBeCalledVirtual(mem);
   504     }
   505 
   506     static boolean canBeCalledVirtual(MemberName mem) {
   507         assert(mem.isInvocable());
   508         Class<?> defc = mem.getDeclaringClass();
   509         switch (mem.getName()) {
   510         case "checkMemberAccess":
   511             return true; //canBeCalledVirtual(mem, java.lang.SecurityManager.class);
   512         case "getContextClassLoader":
   513             return canBeCalledVirtual(mem, java.lang.Thread.class);
   514         }
   515         return false;
   516     }
   517 
   518     static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) {
   519         Class<?> symbolicRefClass = symbolicRef.getDeclaringClass();
   520         if (symbolicRefClass == definingClass)  return true;
   521         if (symbolicRef.isStatic() || symbolicRef.isPrivate())  return false;
   522         return (definingClass.isAssignableFrom(symbolicRefClass) ||  // Msym overrides Mdef
   523                 symbolicRefClass.isInterface());                     // Mdef implements Msym
   524     }
   525 }