< prev index next >

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

Print this page




  67                 assert(member.getReferenceKind() == m.getReferenceKind());  // else this.form is wrong
  68                 member = m;
  69             }
  70         }
  71 
  72         this.member = member;
  73     }
  74 
  75     // Factory methods:
  76     static DirectMethodHandle make(byte refKind, Class<?> refc, MemberName member, Class<?> callerClass) {
  77         MethodType mtype = member.getMethodOrFieldType();
  78         if (!member.isStatic()) {
  79             if (!member.getDeclaringClass().isAssignableFrom(refc) || member.isConstructor())
  80                 throw new InternalError(member.toString());
  81             mtype = mtype.insertParameterTypes(0, refc);
  82         }
  83         if (!member.isField()) {
  84             switch (refKind) {
  85                 case REF_invokeSpecial: {
  86                     member = member.asSpecial();
  87                     LambdaForm lform = preparedLambdaForm(member, callerClass);
  88                     Class<?> checkClass = refc;  // Class to use for receiver type check
  89                     if (callerClass != null) {
  90                         checkClass = callerClass;  // potentially strengthen to caller class
  91                     }
  92                     return new Special(mtype, lform, member, checkClass);

  93                 }
  94                 case REF_invokeInterface: {
  95                     LambdaForm lform = preparedLambdaForm(member, callerClass);

  96                     return new Interface(mtype, lform, member, refc);
  97                 }
  98                 default: {
  99                     LambdaForm lform = preparedLambdaForm(member, callerClass);
 100                     return new DirectMethodHandle(mtype, lform, member);
 101                 }
 102             }
 103         } else {
 104             LambdaForm lform = preparedFieldLambdaForm(member);
 105             if (member.isStatic()) {
 106                 long offset = MethodHandleNatives.staticFieldOffset(member);
 107                 Object base = MethodHandleNatives.staticFieldBase(member);
 108                 return new StaticAccessor(mtype, lform, member, base, offset);
 109             } else {
 110                 long offset = MethodHandleNatives.objectFieldOffset(member);
 111                 assert(offset == (int)offset);
 112                 return new Accessor(mtype, lform, member, (int)offset);
 113             }
 114         }
 115     }
 116     static DirectMethodHandle make(Class<?> refc, MemberName member) {
 117         byte refKind = member.getReferenceKind();
 118         if (refKind == REF_invokeSpecial)
 119             refKind =  REF_invokeVirtual;


 149 
 150     @Override
 151     String internalProperties() {
 152         return "\n& DMH.MN="+internalMemberName();
 153     }
 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     }
 208 
 209     static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) {
 210         boolean needsInit = (which == LF_INVSTATIC_INIT);
 211         boolean doesAlloc = (which == LF_NEWINVSPECIAL);
 212         boolean needsReceiverCheck = (which == LF_INVINTERFACE ||
 213                                       which == LF_INVSPECIAL_IFC);
 214 
 215         String linkerName;
 216         LambdaForm.Kind kind;
 217         switch (which) {
 218         case LF_INVVIRTUAL:    linkerName = "linkToVirtual";   kind = DIRECT_INVOKE_VIRTUAL;     break;
 219         case LF_INVSTATIC:     linkerName = "linkToStatic";    kind = DIRECT_INVOKE_STATIC;      break;




  67                 assert(member.getReferenceKind() == m.getReferenceKind());  // else this.form is wrong
  68                 member = m;
  69             }
  70         }
  71 
  72         this.member = member;
  73     }
  74 
  75     // Factory methods:
  76     static DirectMethodHandle make(byte refKind, Class<?> refc, MemberName member, Class<?> callerClass) {
  77         MethodType mtype = member.getMethodOrFieldType();
  78         if (!member.isStatic()) {
  79             if (!member.getDeclaringClass().isAssignableFrom(refc) || member.isConstructor())
  80                 throw new InternalError(member.toString());
  81             mtype = mtype.insertParameterTypes(0, refc);
  82         }
  83         if (!member.isField()) {
  84             switch (refKind) {
  85                 case REF_invokeSpecial: {
  86                     member = member.asSpecial();
  87                     // if caller is an interface we need to adapt to get the
  88                     // receiver check inserted
  89                     if (callerClass == null) {
  90                         throw new InternalError("callerClass must not be null for REF_invokeSpecial");
  91                     }
  92                     LambdaForm lform = preparedLambdaForm(member, callerClass.isInterface());
  93                     return new Special(mtype, lform, member, callerClass);
  94                 }
  95                 case REF_invokeInterface: {
  96                     // we always adapt 'special' when dealing with interfaces
  97                     LambdaForm lform = preparedLambdaForm(member, true);
  98                     return new Interface(mtype, lform, member, refc);
  99                 }
 100                 default: {
 101                     LambdaForm lform = preparedLambdaForm(member);
 102                     return new DirectMethodHandle(mtype, lform, member);
 103                 }
 104             }
 105         } else {
 106             LambdaForm lform = preparedFieldLambdaForm(member);
 107             if (member.isStatic()) {
 108                 long offset = MethodHandleNatives.staticFieldOffset(member);
 109                 Object base = MethodHandleNatives.staticFieldBase(member);
 110                 return new StaticAccessor(mtype, lform, member, base, offset);
 111             } else {
 112                 long offset = MethodHandleNatives.objectFieldOffset(member);
 113                 assert(offset == (int)offset);
 114                 return new Accessor(mtype, lform, member, (int)offset);
 115             }
 116         }
 117     }
 118     static DirectMethodHandle make(Class<?> refc, MemberName member) {
 119         byte refKind = member.getReferenceKind();
 120         if (refKind == REF_invokeSpecial)
 121             refKind =  REF_invokeVirtual;


 151 
 152     @Override
 153     String internalProperties() {
 154         return "\n& DMH.MN="+internalMemberName();
 155     }
 156 
 157     //// Implementation methods.
 158     @Override
 159     @ForceInline
 160     MemberName internalMemberName() {
 161         return member;
 162     }
 163 
 164     private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
 165 
 166     /**
 167      * Create a LF which can invoke the given method.
 168      * Cache and share this structure among all methods with
 169      * the same basicType and refKind.
 170      */
 171     private static LambdaForm preparedLambdaForm(MemberName m, boolean adaptToSpecialIfc) {
 172         assert(m.isInvocable()) : m;  // call preparedFieldLambdaForm instead
 173         MethodType mtype = m.getInvocationType().basicType();
 174         assert(!m.isMethodHandleInvoke()) : m;
 175         int which;
 176         // MemberName.getReferenceKind may be different from the 'kind' passed to
 177         // DMH.make. Specifically private/final methods that use a direct call
 178         // have been adapted to REF_invokeSpecial, even though the actual
 179         // invocation mode may be invokevirtual or invokeinterface.
 180         switch (m.getReferenceKind()) {
 181         case REF_invokeVirtual:    which = LF_INVVIRTUAL;    break;
 182         case REF_invokeStatic:     which = LF_INVSTATIC;     break;
 183         case REF_invokeSpecial:    which = LF_INVSPECIAL;    break;
 184         case REF_invokeInterface:  which = LF_INVINTERFACE;  break;
 185         case REF_newInvokeSpecial: which = LF_NEWINVSPECIAL; break;
 186         default:  throw new InternalError(m.toString());
 187         }
 188         if (which == LF_INVSTATIC && shouldBeInitialized(m)) {
 189             // precompute the barrier-free version:
 190             preparedLambdaForm(mtype, which);
 191             which = LF_INVSTATIC_INIT;
 192         }
 193         if (which == LF_INVSPECIAL && adaptToSpecialIfc) {
 194             which = LF_INVSPECIAL_IFC;
 195         }
 196         LambdaForm lform = preparedLambdaForm(mtype, which);
 197         maybeCompile(lform, m);
 198         assert(lform.methodType().dropParameterTypes(0, 1)
 199                 .equals(m.getInvocationType().basicType()))
 200                 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
 201         return lform;
 202     }
 203 
 204     private static LambdaForm preparedLambdaForm(MemberName m) {
 205         return preparedLambdaForm(m, false);
 206     }
 207 
 208     private static LambdaForm preparedLambdaForm(MethodType mtype, int which) {
 209         LambdaForm lform = mtype.form().cachedLambdaForm(which);
 210         if (lform != null)  return lform;
 211         lform = makePreparedLambdaForm(mtype, which);
 212         return mtype.form().setCachedLambdaForm(which, lform);
 213     }
 214 
 215     static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) {
 216         boolean needsInit = (which == LF_INVSTATIC_INIT);
 217         boolean doesAlloc = (which == LF_NEWINVSPECIAL);
 218         boolean needsReceiverCheck = (which == LF_INVINTERFACE ||
 219                                       which == LF_INVSPECIAL_IFC);
 220 
 221         String linkerName;
 222         LambdaForm.Kind kind;
 223         switch (which) {
 224         case LF_INVVIRTUAL:    linkerName = "linkToVirtual";   kind = DIRECT_INVOKE_VIRTUAL;     break;
 225         case LF_INVSTATIC:     linkerName = "linkToStatic";    kind = DIRECT_INVOKE_STATIC;      break;


< prev index next >