< prev index next >

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

Print this page
rev 55127 : 8223351: [lworld] Primary mirror and nullable mirror for inline type
Reviewed-by: tbd


  61             member.getReferenceKind() == REF_invokeInterface &&
  62             member.isMethod() && !member.isAbstract()) {
  63             // Check for corner case: invokeinterface of Object method
  64             MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind());
  65             m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null);
  66             if (m != null && m.isPublic()) {
  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.isValue() ? refc.asValueType() : refc);
  82         }
  83         if (!member.isField()) {
  84             // refKind reflects the original type of lookup via findSpecial or
  85             // findVirtual etc.
  86             switch (refKind) {
  87                 case REF_invokeSpecial: {
  88                     member = member.asSpecial();
  89                     // if caller is an interface we need to adapt to get the
  90                     // receiver check inserted
  91                     if (callerClass == null) {
  92                         throw new InternalError("callerClass must not be null for REF_invokeSpecial");
  93                     }
  94                     LambdaForm lform = preparedLambdaForm(member, callerClass.isInterface());
  95                     return new Special(mtype, lform, member, callerClass);
  96                 }
  97                 case REF_invokeInterface: {
  98                     // for interfaces we always need the receiver typecheck,
  99                     // so we always pass 'true' to ensure we adapt if needed
 100                     // to include the REF_invokeSpecial case
 101                     LambdaForm lform = preparedLambdaForm(member, true);
 102                     return new Interface(mtype, lform, member, refc);
 103                 }
 104                 default: {
 105                     LambdaForm lform = preparedLambdaForm(member);
 106                     return new DirectMethodHandle(mtype, lform, member);
 107                 }
 108             }
 109         } else {
 110             LambdaForm lform = preparedFieldLambdaForm(member);
 111             if (member.isStatic()) {
 112                 long offset = MethodHandleNatives.staticFieldOffset(member);
 113                 Object base = MethodHandleNatives.staticFieldBase(member);
 114                 return member.isValue() ? new StaticValueAccessor(mtype, lform, member, base, offset)
 115                                         : new StaticAccessor(mtype, lform, member, base, offset);
 116             } else {
 117                 long offset = MethodHandleNatives.objectFieldOffset(member);
 118                 assert(offset == (int)offset);
 119                 return  member.isValue() ? new ValueAccessor(mtype, lform, member, (int)offset)
 120                                          : new Accessor(mtype, lform, member, (int)offset);
 121 
 122             }
 123         }
 124     }
 125     static DirectMethodHandle make(Class<?> refc, MemberName member) {
 126         byte refKind = member.getReferenceKind();
 127         if (refKind == REF_invokeSpecial)
 128             refKind =  REF_invokeVirtual;
 129         return make(refKind, refc, member, null /* no callerClass context */);
 130     }
 131     static DirectMethodHandle make(MemberName member) {
 132         if (member.isConstructor() && member.getReturnType() == void.class)
 133             return makeAllocator(member);
 134         return make(member.getDeclaringClass(), member);
 135     }
 136     private static DirectMethodHandle makeAllocator(MemberName ctor) {
 137         assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
 138         Class<?> instanceClass = ctor.getDeclaringClass();
 139         if (instanceClass.isValue())
 140             instanceClass = instanceClass.asValueType();  // convert to Q-Type
 141         ctor = ctor.asConstructor();
 142         assert(ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
 143         MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
 144         LambdaForm lform = preparedLambdaForm(ctor);
 145         MemberName init = ctor.asSpecial();
 146         assert(init.getMethodType().returnType() == void.class);
 147         return new Constructor(mtype, lform, ctor, init, instanceClass);
 148     }
 149 
 150     @Override
 151     BoundMethodHandle rebind() {
 152         return BoundMethodHandle.makeReinvoker(this);
 153     }
 154 
 155     @Override
 156     MethodHandle copyWith(MethodType mt, LambdaForm lf) {
 157         assert(this.getClass() == DirectMethodHandle.class);  // must override in subclasses
 158         return new DirectMethodHandle(mt, lf, member);
 159     }
 160 


 650             return isValue ? FT_CHECKED_VALUE : FT_CHECKED_REF;
 651     }
 652 
 653     /**
 654      * Create a LF which can access the given field.
 655      * Cache and share this structure among all fields with
 656      * the same basicType and refKind.
 657      */
 658     private static LambdaForm preparedFieldLambdaForm(MemberName m) {
 659         Class<?> ftype = m.getFieldType();
 660         byte formOp;
 661         switch (m.getReferenceKind()) {
 662         case REF_getField:      formOp = AF_GETFIELD;    break;
 663         case REF_putField:      formOp = AF_PUTFIELD;    break;
 664         case REF_getStatic:     formOp = AF_GETSTATIC;   break;
 665         case REF_putStatic:     formOp = AF_PUTSTATIC;   break;
 666         default:  throw new InternalError(m.toString());
 667         }
 668         if (shouldBeInitialized(m)) {
 669             // precompute the barrier-free version:
 670             preparedFieldLambdaForm(formOp, m.isVolatile(), m.isValue(), m.isFlattened(), ftype);
 671             assert((AF_GETSTATIC_INIT - AF_GETSTATIC) ==
 672                    (AF_PUTSTATIC_INIT - AF_PUTSTATIC));
 673             formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
 674         }
 675         LambdaForm lform = preparedFieldLambdaForm(formOp, m.isVolatile(), m.isValue(), m.isFlattened(), ftype);
 676         maybeCompile(lform, m);
 677         assert(lform.methodType().dropParameterTypes(0, 1)
 678                 .equals(m.getInvocationType().basicType()))
 679                 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
 680         return lform;
 681     }
 682 
 683     private static LambdaForm preparedFieldLambdaForm(byte formOp, boolean isVolatile, boolean isValue, boolean isFlatValue, Class<?> ftype) {
 684         int ftypeKind = ftypeKind(ftype, isValue);
 685         int afIndex = afIndex(formOp, isVolatile, isFlatValue, ftypeKind);
 686         LambdaForm lform = ACCESSOR_FORMS[afIndex];
 687         if (lform != null)  return lform;
 688         lform = makePreparedFieldLambdaForm(formOp, isVolatile, isValue, isFlatValue, ftypeKind);
 689         ACCESSOR_FORMS[afIndex] = lform;  // don't bother with a CAS
 690         return lform;
 691     }
 692 
 693     private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
 694 
 695     private static Kind getFieldKind(boolean isGetter, boolean isVolatile, boolean isFlatValue, Wrapper wrapper) {




  61             member.getReferenceKind() == REF_invokeInterface &&
  62             member.isMethod() && !member.isAbstract()) {
  63             // Check for corner case: invokeinterface of Object method
  64             MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind());
  65             m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null);
  66             if (m != null && m.isPublic()) {
  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.asPrimaryType());
  82         }
  83         if (!member.isField()) {
  84             // refKind reflects the original type of lookup via findSpecial or
  85             // findVirtual etc.
  86             switch (refKind) {
  87                 case REF_invokeSpecial: {
  88                     member = member.asSpecial();
  89                     // if caller is an interface we need to adapt to get the
  90                     // receiver check inserted
  91                     if (callerClass == null) {
  92                         throw new InternalError("callerClass must not be null for REF_invokeSpecial");
  93                     }
  94                     LambdaForm lform = preparedLambdaForm(member, callerClass.isInterface());
  95                     return new Special(mtype, lform, member, callerClass);
  96                 }
  97                 case REF_invokeInterface: {
  98                     // for interfaces we always need the receiver typecheck,
  99                     // so we always pass 'true' to ensure we adapt if needed
 100                     // to include the REF_invokeSpecial case
 101                     LambdaForm lform = preparedLambdaForm(member, true);
 102                     return new Interface(mtype, lform, member, refc);
 103                 }
 104                 default: {
 105                     LambdaForm lform = preparedLambdaForm(member);
 106                     return new DirectMethodHandle(mtype, lform, member);
 107                 }
 108             }
 109         } else {
 110             LambdaForm lform = preparedFieldLambdaForm(member);
 111             if (member.isStatic()) {
 112                 long offset = MethodHandleNatives.staticFieldOffset(member);
 113                 Object base = MethodHandleNatives.staticFieldBase(member);
 114                 return member.isInlineableField() ? new StaticValueAccessor(mtype, lform, member, base, offset)
 115                                                   : new StaticAccessor(mtype, lform, member, base, offset);
 116             } else {
 117                 long offset = MethodHandleNatives.objectFieldOffset(member);
 118                 assert(offset == (int)offset);
 119                 return  member.isInlineableField() ? new ValueAccessor(mtype, lform, member, (int)offset)
 120                                                    : new Accessor(mtype, lform, member, (int)offset);
 121 
 122             }
 123         }
 124     }
 125     static DirectMethodHandle make(Class<?> refc, MemberName member) {
 126         byte refKind = member.getReferenceKind();
 127         if (refKind == REF_invokeSpecial)
 128             refKind =  REF_invokeVirtual;
 129         return make(refKind, refc, member, null /* no callerClass context */);
 130     }
 131     static DirectMethodHandle make(MemberName member) {
 132         if (member.isConstructor() && member.getReturnType() == void.class)
 133             return makeAllocator(member);
 134         return make(member.getDeclaringClass(), member);
 135     }
 136     private static DirectMethodHandle makeAllocator(MemberName ctor) {
 137         assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
 138         Class<?> instanceClass = ctor.getDeclaringClass().asPrimaryType();  // convert to Q-Type


 139         ctor = ctor.asConstructor();
 140         assert(ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
 141         MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
 142         LambdaForm lform = preparedLambdaForm(ctor);
 143         MemberName init = ctor.asSpecial();
 144         assert(init.getMethodType().returnType() == void.class);
 145         return new Constructor(mtype, lform, ctor, init, instanceClass);
 146     }
 147 
 148     @Override
 149     BoundMethodHandle rebind() {
 150         return BoundMethodHandle.makeReinvoker(this);
 151     }
 152 
 153     @Override
 154     MethodHandle copyWith(MethodType mt, LambdaForm lf) {
 155         assert(this.getClass() == DirectMethodHandle.class);  // must override in subclasses
 156         return new DirectMethodHandle(mt, lf, member);
 157     }
 158 


 648             return isValue ? FT_CHECKED_VALUE : FT_CHECKED_REF;
 649     }
 650 
 651     /**
 652      * Create a LF which can access the given field.
 653      * Cache and share this structure among all fields with
 654      * the same basicType and refKind.
 655      */
 656     private static LambdaForm preparedFieldLambdaForm(MemberName m) {
 657         Class<?> ftype = m.getFieldType();
 658         byte formOp;
 659         switch (m.getReferenceKind()) {
 660         case REF_getField:      formOp = AF_GETFIELD;    break;
 661         case REF_putField:      formOp = AF_PUTFIELD;    break;
 662         case REF_getStatic:     formOp = AF_GETSTATIC;   break;
 663         case REF_putStatic:     formOp = AF_PUTSTATIC;   break;
 664         default:  throw new InternalError(m.toString());
 665         }
 666         if (shouldBeInitialized(m)) {
 667             // precompute the barrier-free version:
 668             preparedFieldLambdaForm(formOp, m.isVolatile(), m.isInlineableField(), m.isFlattened(), ftype);
 669             assert((AF_GETSTATIC_INIT - AF_GETSTATIC) ==
 670                    (AF_PUTSTATIC_INIT - AF_PUTSTATIC));
 671             formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
 672         }
 673         LambdaForm lform = preparedFieldLambdaForm(formOp, m.isVolatile(), m.isInlineableField(), m.isFlattened(), ftype);
 674         maybeCompile(lform, m);
 675         assert(lform.methodType().dropParameterTypes(0, 1)
 676                 .equals(m.getInvocationType().basicType()))
 677                 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
 678         return lform;
 679     }
 680 
 681     private static LambdaForm preparedFieldLambdaForm(byte formOp, boolean isVolatile, boolean isValue, boolean isFlatValue, Class<?> ftype) {
 682         int ftypeKind = ftypeKind(ftype, isValue);
 683         int afIndex = afIndex(formOp, isVolatile, isFlatValue, ftypeKind);
 684         LambdaForm lform = ACCESSOR_FORMS[afIndex];
 685         if (lform != null)  return lform;
 686         lform = makePreparedFieldLambdaForm(formOp, isVolatile, isValue, isFlatValue, ftypeKind);
 687         ACCESSOR_FORMS[afIndex] = lform;  // don't bother with a CAS
 688         return lform;
 689     }
 690 
 691     private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
 692 
 693     private static Kind getFieldKind(boolean isGetter, boolean isVolatile, boolean isFlatValue, Wrapper wrapper) {


< prev index next >