< 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                     LambdaForm lform = preparedLambdaForm(member, callerClass.isInterface());
  90                     Class<?> checkClass = refc;  // Class to use for receiver type check
  91                     if (callerClass != null) {
  92                         checkClass = callerClass;  // potentially strengthen to caller class
  93                     }
  94                     return new Special(mtype, lform, member, checkClass);
  95                 }
  96                 case REF_invokeInterface: {
  97                     // we always adapt 'special' when dealing with interfaces
  98                     LambdaForm lform = preparedLambdaForm(member, true);
  99                     return new Interface(mtype, lform, member, refc);
 100                 }
 101                 default: {
 102                     LambdaForm lform = preparedLambdaForm(member);
 103                     return new DirectMethodHandle(mtype, lform, member);
 104                 }
 105             }
 106         } else {
 107             LambdaForm lform = preparedFieldLambdaForm(member);
 108             if (member.isStatic()) {
 109                 long offset = MethodHandleNatives.staticFieldOffset(member);
 110                 Object base = MethodHandleNatives.staticFieldBase(member);
 111                 return new StaticAccessor(mtype, lform, member, base, offset);
 112             } else {
 113                 long offset = MethodHandleNatives.objectFieldOffset(member);
 114                 assert(offset == (int)offset);
 115                 return new Accessor(mtype, lform, member, (int)offset);
 116             }
 117         }
 118     }
 119     static DirectMethodHandle make(Class<?> refc, MemberName member) {
 120         byte refKind = member.getReferenceKind();
 121         if (refKind == REF_invokeSpecial)
 122             refKind =  REF_invokeVirtual;


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


< prev index next >