< prev index next >

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

Print this page

 95         }
 96     }
 97 
 98     /** Invalidate all recorded nmethods. */
 99     private static native void clearCallSiteContext(CallSiteContext context);
100 
101     private static native void registerNatives();
102     static {
103         registerNatives();
104     }
105 
106     /**
107      * Compile-time constants go here. This collection exists not only for
108      * reference from clients, but also for ensuring the VM and JDK agree on the
109      * values of these constants (see {@link #verifyConstants()}).
110      */
111     static class Constants {
112         Constants() { } // static only
113 
114         static final int
115             MN_IS_METHOD           = 0x00010000, // method (not constructor)
116             MN_IS_CONSTRUCTOR      = 0x00020000, // constructor
117             MN_IS_FIELD            = 0x00040000, // field
118             MN_IS_TYPE             = 0x00080000, // nested type
119             MN_CALLER_SENSITIVE    = 0x00100000, // @CallerSensitive annotation detected
120             MN_TRUSTED_FINAL       = 0x00200000, // trusted final field
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          */

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

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

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

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

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