< prev index next >

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

Print this page

 97         }
 98     }
 99 
100     /** Invalidate all recorded nmethods. */
101     private static native void clearCallSiteContext(CallSiteContext context);
102 
103     private static native void registerNatives();
104     static {
105         registerNatives();
106     }
107 
108     /**
109      * Compile-time constants go here. This collection exists not only for
110      * reference from clients, but also for ensuring the VM and JDK agree on the
111      * values of these constants (see {@link #verifyConstants()}).
112      */
113     static class Constants {
114         Constants() { } // static only
115 
116         static final int
117             MN_IS_METHOD           = 0x00010000, // method (not constructor)
118             MN_IS_CONSTRUCTOR      = 0x00020000, // constructor
119             MN_IS_FIELD            = 0x00040000, // field
120             MN_IS_TYPE             = 0x00080000, // nested type
121             MN_CALLER_SENSITIVE    = 0x00100000, // @CallerSensitive annotation detected
122             MN_TRUSTED_FINAL       = 0x00200000, // trusted final field
123             MN_REFERENCE_KIND_SHIFT = 24, // refKind
124             MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
125             // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
126             MN_SEARCH_SUPERCLASSES = 0x00100000,
127             MN_SEARCH_INTERFACES   = 0x00200000;
128 
129         /**
130          * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
131          */
132         static final byte
133             REF_NONE                    = 0,  // null value
134             REF_getField                = 1,
135             REF_getStatic               = 2,
136             REF_putField                = 3,
137             REF_putStatic               = 4,
138             REF_invokeVirtual           = 5,
139             REF_invokeStatic            = 6,
140             REF_invokeSpecial           = 7,
141             REF_newInvokeSpecial        = 8,
142             REF_invokeInterface         = 9,
143             REF_LIMIT                  = 10;
144 
145         /**
146          * Flags for Lookup.ClassOptions
147          */

161 
162     }
163 
164     static boolean refKindIsValid(int refKind) {
165         return (refKind > REF_NONE && refKind < REF_LIMIT);
166     }
167     static boolean refKindIsField(byte refKind) {
168         assert(refKindIsValid(refKind));
169         return (refKind <= REF_putStatic);
170     }
171     static boolean refKindIsGetter(byte refKind) {
172         assert(refKindIsValid(refKind));
173         return (refKind <= REF_getStatic);
174     }
175     static boolean refKindIsSetter(byte refKind) {
176         return refKindIsField(refKind) && !refKindIsGetter(refKind);
177     }
178     static boolean refKindIsMethod(byte refKind) {
179         return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial);
180     }
181     static boolean refKindIsConstructor(byte refKind) {
182         return (refKind == REF_newInvokeSpecial);
183     }
184     static boolean refKindHasReceiver(byte refKind) {
185         assert(refKindIsValid(refKind));
186         return (refKind & 1) != 0;
187     }
188     static boolean refKindIsStatic(byte refKind) {
189         return !refKindHasReceiver(refKind) && (refKind != REF_newInvokeSpecial);
190     }
191     static boolean refKindDoesDispatch(byte refKind) {
192         assert(refKindIsValid(refKind));
193         return (refKind == REF_invokeVirtual ||
194                 refKind == REF_invokeInterface);
195     }
196     static {
197         final int HR_MASK = ((1 << REF_getField) |
198                              (1 << REF_putField) |
199                              (1 << REF_invokeVirtual) |
200                              (1 << REF_invokeSpecial) |
201                              (1 << REF_invokeInterface)

570                     VarHandleGuards.class, getVarHandleGuardMethodName(guardType),
571                     guardType, REF_invokeStatic);
572 
573             linker = MemberName.getFactory().resolveOrNull(REF_invokeStatic, linker,
574                                                            VarHandleGuards.class, LM_TRUSTED);
575             if (linker != null) {
576                 return linker;
577             }
578             // Fall back to lambda form linkage if guard method is not available
579             // TODO Optionally log fallback ?
580         }
581         return Invokers.varHandleInvokeLinkerMethod(mtype);
582     }
583     static String getVarHandleGuardMethodName(MethodType guardType) {
584         String prefix = "guard_";
585         StringBuilder sb = new StringBuilder(prefix.length() + guardType.parameterCount());
586 
587         sb.append(prefix);
588         for (int i = 1; i < guardType.parameterCount() - 1; i++) {
589             Class<?> pt = guardType.parameterType(i);
590             sb.append(getCharType(pt));
591         }
592         sb.append('_').append(getCharType(guardType.returnType()));
593         return sb.toString();
594     }
595     static char getCharType(Class<?> pt) {
596         return Wrapper.forBasicType(pt).basicTypeChar();
597     }
598     static NoSuchMethodError newNoSuchMethodErrorOnVarHandle(String name, MethodType mtype) {
599         return new NoSuchMethodError("VarHandle." + name + mtype);
600     }
601 
602     /**
603      * The JVM is resolving a CONSTANT_MethodHandle CP entry.  And it wants our help.
604      * It will make an up-call to this method.  (Do not change the name or signature.)
605      * The type argument is a Class for field requests and a MethodType for non-fields.
606      * <p>
607      * Recent versions of the JVM may also pass a resolved MemberName for the type.
608      * In that case, the name is ignored and may be null.
609      */
610     static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
611                                                  Class<?> defc, String name, Object type) {
612         try {
613             Lookup lookup = IMPL_LOOKUP.in(callerClass);
614             assert(refKindIsValid(refKind));
615             return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type);

 97         }
 98     }
 99 
100     /** Invalidate all recorded nmethods. */
101     private static native void clearCallSiteContext(CallSiteContext context);
102 
103     private static native void registerNatives();
104     static {
105         registerNatives();
106     }
107 
108     /**
109      * Compile-time constants go here. This collection exists not only for
110      * reference from clients, but also for ensuring the VM and JDK agree on the
111      * values of these constants (see {@link #verifyConstants()}).
112      */
113     static class Constants {
114         Constants() { } // static only
115 
116         static final int
117             MN_IS_METHOD             = 0x00010000, // method (not object constructor)
118             MN_IS_OBJECT_CONSTRUCTOR = 0x00020000, // object constructor
119             MN_IS_FIELD              = 0x00040000, // field
120             MN_IS_TYPE               = 0x00080000, // nested type
121             MN_CALLER_SENSITIVE      = 0x00100000, // @CallerSensitive annotation detected
122             MN_TRUSTED_FINAL         = 0x00200000, // trusted final field
123             MN_REFERENCE_KIND_SHIFT  = 24, // refKind
124             MN_REFERENCE_KIND_MASK   = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
125             // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
126             MN_SEARCH_SUPERCLASSES   = 0x00100000,
127             MN_SEARCH_INTERFACES     = 0x00200000;
128 
129         /**
130          * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
131          */
132         static final byte
133             REF_NONE                    = 0,  // null value
134             REF_getField                = 1,
135             REF_getStatic               = 2,
136             REF_putField                = 3,
137             REF_putStatic               = 4,
138             REF_invokeVirtual           = 5,
139             REF_invokeStatic            = 6,
140             REF_invokeSpecial           = 7,
141             REF_newInvokeSpecial        = 8,
142             REF_invokeInterface         = 9,
143             REF_LIMIT                  = 10;
144 
145         /**
146          * Flags for Lookup.ClassOptions
147          */

161 
162     }
163 
164     static boolean refKindIsValid(int refKind) {
165         return (refKind > REF_NONE && refKind < REF_LIMIT);
166     }
167     static boolean refKindIsField(byte refKind) {
168         assert(refKindIsValid(refKind));
169         return (refKind <= REF_putStatic);
170     }
171     static boolean refKindIsGetter(byte refKind) {
172         assert(refKindIsValid(refKind));
173         return (refKind <= REF_getStatic);
174     }
175     static boolean refKindIsSetter(byte refKind) {
176         return refKindIsField(refKind) && !refKindIsGetter(refKind);
177     }
178     static boolean refKindIsMethod(byte refKind) {
179         return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial);
180     }
181     static boolean refKindIsObjectConstructor(byte refKind) {
182         return (refKind == REF_newInvokeSpecial);
183     }
184     static boolean refKindHasReceiver(byte refKind) {
185         assert(refKindIsValid(refKind));
186         return (refKind & 1) != 0;
187     }
188     static boolean refKindIsStatic(byte refKind) {
189         return !refKindHasReceiver(refKind) && (refKind != REF_newInvokeSpecial);
190     }
191     static boolean refKindDoesDispatch(byte refKind) {
192         assert(refKindIsValid(refKind));
193         return (refKind == REF_invokeVirtual ||
194                 refKind == REF_invokeInterface);
195     }
196     static {
197         final int HR_MASK = ((1 << REF_getField) |
198                              (1 << REF_putField) |
199                              (1 << REF_invokeVirtual) |
200                              (1 << REF_invokeSpecial) |
201                              (1 << REF_invokeInterface)

570                     VarHandleGuards.class, getVarHandleGuardMethodName(guardType),
571                     guardType, REF_invokeStatic);
572 
573             linker = MemberName.getFactory().resolveOrNull(REF_invokeStatic, linker,
574                                                            VarHandleGuards.class, LM_TRUSTED);
575             if (linker != null) {
576                 return linker;
577             }
578             // Fall back to lambda form linkage if guard method is not available
579             // TODO Optionally log fallback ?
580         }
581         return Invokers.varHandleInvokeLinkerMethod(mtype);
582     }
583     static String getVarHandleGuardMethodName(MethodType guardType) {
584         String prefix = "guard_";
585         StringBuilder sb = new StringBuilder(prefix.length() + guardType.parameterCount());
586 
587         sb.append(prefix);
588         for (int i = 1; i < guardType.parameterCount() - 1; i++) {
589             Class<?> pt = guardType.parameterType(i);
590             sb.append(getCharErasedType(pt));
591         }
592         sb.append('_').append(getCharErasedType(guardType.returnType()));
593         return sb.toString();
594     }
595     static char getCharErasedType(Class<?> pt) {
596         return Wrapper.forBasicType(pt).basicTypeChar();
597     }
598     static NoSuchMethodError newNoSuchMethodErrorOnVarHandle(String name, MethodType mtype) {
599         return new NoSuchMethodError("VarHandle." + name + mtype);
600     }
601 
602     /**
603      * The JVM is resolving a CONSTANT_MethodHandle CP entry.  And it wants our help.
604      * It will make an up-call to this method.  (Do not change the name or signature.)
605      * The type argument is a Class for field requests and a MethodType for non-fields.
606      * <p>
607      * Recent versions of the JVM may also pass a resolved MemberName for the type.
608      * In that case, the name is ignored and may be null.
609      */
610     static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
611                                                  Class<?> defc, String name, Object type) {
612         try {
613             Lookup lookup = IMPL_LOOKUP.in(callerClass);
614             assert(refKindIsValid(refKind));
615             return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type);
< prev index next >