< prev index next >

src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java

Print this page




  94         }
  95     }
  96 
  97     /** Invalidate all recorded nmethods. */
  98     private static native void clearCallSiteContext(CallSiteContext context);
  99 
 100     private static native void registerNatives();
 101     static {
 102         registerNatives();
 103     }
 104 
 105     /**
 106      * Compile-time constants go here. This collection exists not only for
 107      * reference from clients, but also for ensuring the VM and JDK agree on the
 108      * values of these constants (see {@link #verifyConstants()}).
 109      */
 110     static class Constants {
 111         Constants() { } // static only
 112 
 113         static final int
 114             MN_IS_METHOD           = 0x00010000, // method (not constructor)
 115             MN_IS_CONSTRUCTOR      = 0x00020000, // constructor
 116             MN_IS_FIELD            = 0x00040000, // field
 117             MN_IS_TYPE             = 0x00080000, // nested type
 118             MN_CALLER_SENSITIVE    = 0x00100000, // @CallerSensitive annotation detected
 119             MN_REFERENCE_KIND_SHIFT = 24, // refKind
 120             MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
 121             // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
 122             MN_SEARCH_SUPERCLASSES = 0x00100000,
 123             MN_SEARCH_INTERFACES   = 0x00200000;
 124 
 125         /**
 126          * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
 127          */
 128         static final byte
 129             REF_NONE                    = 0,  // null value
 130             REF_getField                = 1,
 131             REF_getStatic               = 2,
 132             REF_putField                = 3,
 133             REF_putStatic               = 4,
 134             REF_invokeVirtual           = 5,
 135             REF_invokeStatic            = 6,
 136             REF_invokeSpecial           = 7,
 137             REF_newInvokeSpecial        = 8,
 138             REF_invokeInterface         = 9,
 139             REF_LIMIT                  = 10;
 140     }
 141 
 142     static boolean refKindIsValid(int refKind) {
 143         return (refKind > REF_NONE && refKind < REF_LIMIT);
 144     }
 145     static boolean refKindIsField(byte refKind) {
 146         assert(refKindIsValid(refKind));
 147         return (refKind <= REF_putStatic);
 148     }
 149     static boolean refKindIsGetter(byte refKind) {
 150         assert(refKindIsValid(refKind));
 151         return (refKind <= REF_getStatic);
 152     }
 153     static boolean refKindIsSetter(byte refKind) {
 154         return refKindIsField(refKind) && !refKindIsGetter(refKind);
 155     }
 156     static boolean refKindIsMethod(byte refKind) {
 157         return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial);
 158     }
 159     static boolean refKindIsConstructor(byte refKind) {
 160         return (refKind == REF_newInvokeSpecial);
 161     }
 162     static boolean refKindHasReceiver(byte refKind) {
 163         assert(refKindIsValid(refKind));
 164         return (refKind & 1) != 0;
 165     }
 166     static boolean refKindIsStatic(byte refKind) {
 167         return !refKindHasReceiver(refKind) && (refKind != REF_newInvokeSpecial);
 168     }
 169     static boolean refKindDoesDispatch(byte refKind) {
 170         assert(refKindIsValid(refKind));
 171         return (refKind == REF_invokeVirtual ||
 172                 refKind == REF_invokeInterface);
 173     }
 174     static {
 175         final int HR_MASK = ((1 << REF_getField) |
 176                              (1 << REF_putField) |
 177                              (1 << REF_invokeVirtual) |
 178                              (1 << REF_invokeSpecial) |
 179                              (1 << REF_invokeInterface)


 548                     VarHandleGuards.class, getVarHandleGuardMethodName(guardType),
 549                     guardType, REF_invokeStatic);
 550 
 551             linker = MemberName.getFactory().resolveOrNull(REF_invokeStatic, linker,
 552                                                            VarHandleGuards.class);
 553             if (linker != null) {
 554                 return linker;
 555             }
 556             // Fall back to lambda form linkage if guard method is not available
 557             // TODO Optionally log fallback ?
 558         }
 559         return Invokers.varHandleInvokeLinkerMethod(ak, mtype);
 560     }
 561     static String getVarHandleGuardMethodName(MethodType guardType) {
 562         String prefix = "guard_";
 563         StringBuilder sb = new StringBuilder(prefix.length() + guardType.parameterCount());
 564 
 565         sb.append(prefix);
 566         for (int i = 1; i < guardType.parameterCount() - 1; i++) {
 567             Class<?> pt = guardType.parameterType(i);
 568             sb.append(getCharType(pt));
 569         }
 570         sb.append('_').append(getCharType(guardType.returnType()));
 571         return sb.toString();
 572     }
 573     static char getCharType(Class<?> pt) {
 574         return Wrapper.forBasicType(pt).basicTypeChar();
 575     }
 576     static NoSuchMethodError newNoSuchMethodErrorOnVarHandle(String name, MethodType mtype) {
 577         return new NoSuchMethodError("VarHandle." + name + mtype);
 578     }
 579 
 580     /**
 581      * The JVM is resolving a CONSTANT_MethodHandle CP entry.  And it wants our help.
 582      * It will make an up-call to this method.  (Do not change the name or signature.)
 583      * The type argument is a Class for field requests and a MethodType for non-fields.
 584      * <p>
 585      * Recent versions of the JVM may also pass a resolved MemberName for the type.
 586      * In that case, the name is ignored and may be null.
 587      */
 588     static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
 589                                                  Class<?> defc, String name, Object type) {
 590         try {
 591             Lookup lookup = IMPL_LOOKUP.in(callerClass);
 592             assert(refKindIsValid(refKind));
 593             return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type);




  94         }
  95     }
  96 
  97     /** Invalidate all recorded nmethods. */
  98     private static native void clearCallSiteContext(CallSiteContext context);
  99 
 100     private static native void registerNatives();
 101     static {
 102         registerNatives();
 103     }
 104 
 105     /**
 106      * Compile-time constants go here. This collection exists not only for
 107      * reference from clients, but also for ensuring the VM and JDK agree on the
 108      * values of these constants (see {@link #verifyConstants()}).
 109      */
 110     static class Constants {
 111         Constants() { } // static only
 112 
 113         static final int
 114             MN_IS_METHOD             = 0x00010000, // method (not object constructor)
 115             MN_IS_OBJECT_CONSTRUCTOR = 0x00020000, // object constructor
 116             MN_IS_FIELD              = 0x00040000, // field
 117             MN_IS_TYPE               = 0x00080000, // nested type
 118             MN_CALLER_SENSITIVE      = 0x00100000, // @CallerSensitive annotation detected
 119             MN_REFERENCE_KIND_SHIFT  = 24, // refKind
 120             MN_REFERENCE_KIND_MASK   = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
 121             // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
 122             MN_SEARCH_SUPERCLASSES   = 0x00100000,
 123             MN_SEARCH_INTERFACES     = 0x00200000;
 124 
 125         /**
 126          * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
 127          */
 128         static final byte
 129             REF_NONE                    = 0,  // null value
 130             REF_getField                = 1,
 131             REF_getStatic               = 2,
 132             REF_putField                = 3,
 133             REF_putStatic               = 4,
 134             REF_invokeVirtual           = 5,
 135             REF_invokeStatic            = 6,
 136             REF_invokeSpecial           = 7,
 137             REF_newInvokeSpecial        = 8,
 138             REF_invokeInterface         = 9,
 139             REF_LIMIT                  = 10;
 140     }
 141 
 142     static boolean refKindIsValid(int refKind) {
 143         return (refKind > REF_NONE && refKind < REF_LIMIT);
 144     }
 145     static boolean refKindIsField(byte refKind) {
 146         assert(refKindIsValid(refKind));
 147         return (refKind <= REF_putStatic);
 148     }
 149     static boolean refKindIsGetter(byte refKind) {
 150         assert(refKindIsValid(refKind));
 151         return (refKind <= REF_getStatic);
 152     }
 153     static boolean refKindIsSetter(byte refKind) {
 154         return refKindIsField(refKind) && !refKindIsGetter(refKind);
 155     }
 156     static boolean refKindIsMethod(byte refKind) {
 157         return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial);
 158     }
 159     static boolean refKindIsObjectConstructor(byte refKind) {
 160         return (refKind == REF_newInvokeSpecial);
 161     }
 162     static boolean refKindHasReceiver(byte refKind) {
 163         assert(refKindIsValid(refKind));
 164         return (refKind & 1) != 0;
 165     }
 166     static boolean refKindIsStatic(byte refKind) {
 167         return !refKindHasReceiver(refKind) && (refKind != REF_newInvokeSpecial);
 168     }
 169     static boolean refKindDoesDispatch(byte refKind) {
 170         assert(refKindIsValid(refKind));
 171         return (refKind == REF_invokeVirtual ||
 172                 refKind == REF_invokeInterface);
 173     }
 174     static {
 175         final int HR_MASK = ((1 << REF_getField) |
 176                              (1 << REF_putField) |
 177                              (1 << REF_invokeVirtual) |
 178                              (1 << REF_invokeSpecial) |
 179                              (1 << REF_invokeInterface)


 548                     VarHandleGuards.class, getVarHandleGuardMethodName(guardType),
 549                     guardType, REF_invokeStatic);
 550 
 551             linker = MemberName.getFactory().resolveOrNull(REF_invokeStatic, linker,
 552                                                            VarHandleGuards.class);
 553             if (linker != null) {
 554                 return linker;
 555             }
 556             // Fall back to lambda form linkage if guard method is not available
 557             // TODO Optionally log fallback ?
 558         }
 559         return Invokers.varHandleInvokeLinkerMethod(ak, mtype);
 560     }
 561     static String getVarHandleGuardMethodName(MethodType guardType) {
 562         String prefix = "guard_";
 563         StringBuilder sb = new StringBuilder(prefix.length() + guardType.parameterCount());
 564 
 565         sb.append(prefix);
 566         for (int i = 1; i < guardType.parameterCount() - 1; i++) {
 567             Class<?> pt = guardType.parameterType(i);
 568             sb.append(getCharErasedType(pt));
 569         }
 570         sb.append('_').append(getCharErasedType(guardType.returnType()));
 571         return sb.toString();
 572     }
 573     static char getCharErasedType(Class<?> pt) {
 574         return Wrapper.forBasicType(pt).basicTypeChar();
 575     }
 576     static NoSuchMethodError newNoSuchMethodErrorOnVarHandle(String name, MethodType mtype) {
 577         return new NoSuchMethodError("VarHandle." + name + mtype);
 578     }
 579 
 580     /**
 581      * The JVM is resolving a CONSTANT_MethodHandle CP entry.  And it wants our help.
 582      * It will make an up-call to this method.  (Do not change the name or signature.)
 583      * The type argument is a Class for field requests and a MethodType for non-fields.
 584      * <p>
 585      * Recent versions of the JVM may also pass a resolved MemberName for the type.
 586      * In that case, the name is ignored and may be null.
 587      */
 588     static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
 589                                                  Class<?> defc, String name, Object type) {
 590         try {
 591             Lookup lookup = IMPL_LOOKUP.in(callerClass);
 592             assert(refKindIsValid(refKind));
 593             return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type);


< prev index next >