< prev index next >

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

Print this page




 154 
 155     //// Implementation methods.
 156     @Override
 157     @ForceInline
 158     MemberName internalMemberName() {
 159         return member;
 160     }
 161 
 162     private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
 163 
 164     /**
 165      * Create a LF which can invoke the given method.
 166      * Cache and share this structure among all methods with
 167      * the same basicType and refKind.
 168      */
 169     private static LambdaForm preparedLambdaForm(MemberName m, Class<?> callerClass) {
 170         assert(m.isInvocable()) : m;  // call preparedFieldLambdaForm instead
 171         MethodType mtype = m.getInvocationType().basicType();
 172         assert(!m.isMethodHandleInvoke()) : m;
 173         int which;




 174         switch (m.getReferenceKind()) {
 175         case REF_invokeVirtual:    which = LF_INVVIRTUAL;    break;
 176         case REF_invokeStatic:     which = LF_INVSTATIC;     break;
 177         case REF_invokeSpecial:    which = LF_INVSPECIAL;    break;
 178         case REF_invokeInterface:  which = LF_INVINTERFACE;  break;
 179         case REF_newInvokeSpecial: which = LF_NEWINVSPECIAL; break;
 180         default:  throw new InternalError(m.toString());
 181         }
 182         if (which == LF_INVSTATIC && shouldBeInitialized(m)) {
 183             // precompute the barrier-free version:
 184             preparedLambdaForm(mtype, which);
 185             which = LF_INVSTATIC_INIT;
 186         }
 187         if (which == LF_INVSPECIAL && callerClass != null && callerClass.isInterface()) {






 188             which = LF_INVSPECIAL_IFC;
 189         }
 190         LambdaForm lform = preparedLambdaForm(mtype, which);
 191         maybeCompile(lform, m);
 192         assert(lform.methodType().dropParameterTypes(0, 1)
 193                 .equals(m.getInvocationType().basicType()))
 194                 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
 195         return lform;
 196     }
 197 
 198     private static LambdaForm preparedLambdaForm(MemberName m) {
 199         return preparedLambdaForm(m, null);
 200     }
 201 
 202     private static LambdaForm preparedLambdaForm(MethodType mtype, int which) {
 203         LambdaForm lform = mtype.form().cachedLambdaForm(which);
 204         if (lform != null)  return lform;
 205         lform = makePreparedLambdaForm(mtype, which);
 206         return mtype.form().setCachedLambdaForm(which, lform);
 207     }




 154 
 155     //// Implementation methods.
 156     @Override
 157     @ForceInline
 158     MemberName internalMemberName() {
 159         return member;
 160     }
 161 
 162     private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
 163 
 164     /**
 165      * Create a LF which can invoke the given method.
 166      * Cache and share this structure among all methods with
 167      * the same basicType and refKind.
 168      */
 169     private static LambdaForm preparedLambdaForm(MemberName m, Class<?> callerClass) {
 170         assert(m.isInvocable()) : m;  // call preparedFieldLambdaForm instead
 171         MethodType mtype = m.getInvocationType().basicType();
 172         assert(!m.isMethodHandleInvoke()) : m;
 173         int which;
 174         // MemberName.getReferenceKind may be different to the 'kind' passed to
 175         // DMH.make. Specifically private/final methods that use a direct call
 176         // have been adapted to REF_invokeSpecial, even though the actual
 177         // invocation mode may be invokevirtual or invokeinterface.
 178         switch (m.getReferenceKind()) {
 179         case REF_invokeVirtual:    which = LF_INVVIRTUAL;    break;
 180         case REF_invokeStatic:     which = LF_INVSTATIC;     break;
 181         case REF_invokeSpecial:    which = LF_INVSPECIAL;    break;
 182         case REF_invokeInterface:  which = LF_INVINTERFACE;  break;
 183         case REF_newInvokeSpecial: which = LF_NEWINVSPECIAL; break;
 184         default:  throw new InternalError(m.toString());
 185         }
 186         if (which == LF_INVSTATIC && shouldBeInitialized(m)) {
 187             // precompute the barrier-free version:
 188             preparedLambdaForm(mtype, which);
 189             which = LF_INVSTATIC_INIT;
 190         }
 191         // Direct calls involving interfaces require additional specialization to add
 192         // in a receiver typecheck. For true invokespecial we need to inspect the callerClass
 193         // for being an interface (which implies REFC is also an interface). For invokeinterface
 194         // we always need the check. If the declaring class is an interface, and the method is not
 195         // static, then this must be an invokeinterface.
 196         if (which == LF_INVSPECIAL && ((callerClass != null && callerClass.isInterface()) ||
 197                                        (!m.isStatic() && m.getDeclaringClass().isInterface()))) {
 198             which = LF_INVSPECIAL_IFC;
 199         }
 200         LambdaForm lform = preparedLambdaForm(mtype, which);
 201         maybeCompile(lform, m);
 202         assert(lform.methodType().dropParameterTypes(0, 1)
 203                 .equals(m.getInvocationType().basicType()))
 204                 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
 205         return lform;
 206     }
 207 
 208     private static LambdaForm preparedLambdaForm(MemberName m) {
 209         return preparedLambdaForm(m, null);
 210     }
 211 
 212     private static LambdaForm preparedLambdaForm(MethodType mtype, int which) {
 213         LambdaForm lform = mtype.form().cachedLambdaForm(which);
 214         if (lform != null)  return lform;
 215         lform = makePreparedLambdaForm(mtype, which);
 216         return mtype.form().setCachedLambdaForm(which, lform);
 217     }


< prev index next >