< prev index next >

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

Print this page

 61         if (member.getDeclaringClass().isInterface() &&
 62             member.getReferenceKind() == REF_invokeInterface &&
 63             member.isMethod() && !member.isAbstract()) {
 64             // Check for corner case: invokeinterface of Object method
 65             MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind());
 66             m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null, LM_TRUSTED);
 67             if (m != null && m.isPublic()) {
 68                 assert(member.getReferenceKind() == m.getReferenceKind());  // else this.form is wrong
 69                 member = m;
 70             }
 71         }
 72 
 73         this.member = member;
 74         this.crackable = crackable;
 75     }
 76 
 77     // Factory methods:
 78     static DirectMethodHandle make(byte refKind, Class<?> refc, MemberName member, Class<?> callerClass) {
 79         MethodType mtype = member.getMethodOrFieldType();
 80         if (!member.isStatic()) {
 81             if (!member.getDeclaringClass().isAssignableFrom(refc) || member.isConstructor())
 82                 throw new InternalError(member.toString());
 83             mtype = mtype.insertParameterTypes(0, refc);

 84         }
 85         if (!member.isField()) {
 86             // refKind reflects the original type of lookup via findSpecial or
 87             // findVirtual etc.
 88             return switch (refKind) {
 89                 case REF_invokeSpecial -> {
 90                     member = member.asSpecial();
 91                     // if caller is an interface we need to adapt to get the
 92                     // receiver check inserted
 93                     if (callerClass == null) {
 94                         throw new InternalError("callerClass must not be null for REF_invokeSpecial");
 95                     }
 96                     LambdaForm lform = preparedLambdaForm(member, callerClass.isInterface());
 97                     yield new Special(mtype, lform, member, true, callerClass);
 98                 }
 99                 case REF_invokeInterface -> {
100                     // for interfaces we always need the receiver typecheck,
101                     // so we always pass 'true' to ensure we adapt if needed
102                     // to include the REF_invokeSpecial case
103                     LambdaForm lform = preparedLambdaForm(member, true);

111         } else {
112             LambdaForm lform = preparedFieldLambdaForm(member);
113             if (member.isStatic()) {
114                 long offset = MethodHandleNatives.staticFieldOffset(member);
115                 Object base = MethodHandleNatives.staticFieldBase(member);
116                 return new StaticAccessor(mtype, lform, member, true, base, offset);
117             } else {
118                 long offset = MethodHandleNatives.objectFieldOffset(member);
119                 assert(offset == (int)offset);
120                 return new Accessor(mtype, lform, member, true, (int)offset);
121             }
122         }
123     }
124     static DirectMethodHandle make(Class<?> refc, MemberName member) {
125         byte refKind = member.getReferenceKind();
126         if (refKind == REF_invokeSpecial)
127             refKind =  REF_invokeVirtual;
128         return make(refKind, refc, member, null /* no callerClass context */);
129     }
130     static DirectMethodHandle make(MemberName member) {
131         if (member.isConstructor())
132             return makeAllocator(member);
133         return make(member.getDeclaringClass(), member);
134     }
135     private static DirectMethodHandle makeAllocator(MemberName ctor) {
136         assert(ctor.isConstructor() && ctor.getName().equals("<init>"));

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

521     /*non-public*/
522     static long fieldOffset(Object accessorObj) {
523         // Note: We return a long because that is what Unsafe.getObject likes.
524         // We store a plain int because it is more compact.
525         return ((Accessor)accessorObj).fieldOffset;
526     }
527 
528     @ForceInline
529     /*non-public*/
530     static Object checkBase(Object obj) {
531         // Note that the object's class has already been verified,
532         // since the parameter type of the Accessor method handle
533         // is either member.getDeclaringClass or a subclass.
534         // This was verified in DirectMethodHandle.make.
535         // Therefore, the only remaining check is for null.
536         // Since this check is *not* guaranteed by Unsafe.getInt
537         // and its siblings, we need to make an explicit one here.
538         return Objects.requireNonNull(obj);
539     }
540 
541     /** This subclass handles static field references. */
542     static class StaticAccessor extends DirectMethodHandle {
543         private final Class<?> fieldType;
544         private final Object   staticBase;
545         private final long     staticOffset;
546 
547         private StaticAccessor(MethodType mtype, LambdaForm form, MemberName member,
548                                boolean crackable, Object staticBase, long staticOffset) {
549             super(mtype, form, member, crackable);
550             this.fieldType    = member.getFieldType();
551             this.staticBase   = staticBase;
552             this.staticOffset = staticOffset;
553         }
554 
555         @Override Object checkCast(Object obj) {
556             return fieldType.cast(obj);
557         }
558         @Override
559         MethodHandle copyWith(MethodType mt, LambdaForm lf) {
560             return new StaticAccessor(mt, lf, member, crackable, staticBase, staticOffset);
561         }
562         @Override
563         MethodHandle viewAsType(MethodType newType, boolean strict) {
564             assert(viewAsTypeChecks(newType, strict));
565             return new StaticAccessor(newType, form, member, false, staticBase, staticOffset);

573     }
574 
575     @ForceInline
576     /*non-public*/
577     static Object staticBase(Object accessorObj) {
578         return ((StaticAccessor)accessorObj).staticBase;
579     }
580 
581     @ForceInline
582     /*non-public*/
583     static long staticOffset(Object accessorObj) {
584         return ((StaticAccessor)accessorObj).staticOffset;
585     }
586 
587     @ForceInline
588     /*non-public*/
589     static Object checkCast(Object mh, Object obj) {
590         return ((DirectMethodHandle) mh).checkCast(obj);
591     }
592 










593     Object checkCast(Object obj) {
594         return member.getReturnType().cast(obj);
595     }
596 
597     // Caching machinery for field accessors:
598     static final byte
599             AF_GETFIELD        = 0,
600             AF_PUTFIELD        = 1,
601             AF_GETSTATIC       = 2,
602             AF_PUTSTATIC       = 3,
603             AF_GETSTATIC_INIT  = 4,
604             AF_PUTSTATIC_INIT  = 5,
605             AF_LIMIT           = 6;
606     // Enumerate the different field kinds using Wrapper,
607     // with an extra case added for checked references.
608     static final int
609             FT_LAST_WRAPPER    = Wrapper.COUNT-1,
610             FT_UNCHECKED_REF   = Wrapper.OBJECT.ordinal(),
611             FT_CHECKED_REF     = FT_LAST_WRAPPER+1,
612             FT_LIMIT           = FT_LAST_WRAPPER+2;
613     private static int afIndex(byte formOp, boolean isVolatile, int ftypeKind) {

614         return ((formOp * FT_LIMIT * 2)
615                 + (isVolatile ? FT_LIMIT : 0)

616                 + ftypeKind);
617     }
618     @Stable
619     private static final LambdaForm[] ACCESSOR_FORMS
620             = new LambdaForm[afIndex(AF_LIMIT, false, 0)];
621     static int ftypeKind(Class<?> ftype) {
622         if (ftype.isPrimitive())
623             return Wrapper.forPrimitiveType(ftype).ordinal();
624         else if (VerifyType.isNullReferenceConversion(Object.class, ftype))
625             return FT_UNCHECKED_REF;
626         else
627             return FT_CHECKED_REF;

628     }
629 
630     /**
631      * Create a LF which can access the given field.
632      * Cache and share this structure among all fields with
633      * the same basicType and refKind.
634      */
635     private static LambdaForm preparedFieldLambdaForm(MemberName m) {
636         Class<?> ftype = m.getFieldType();
637         boolean isVolatile = m.isVolatile();
638         byte formOp = switch (m.getReferenceKind()) {
639             case REF_getField  -> AF_GETFIELD;
640             case REF_putField  -> AF_PUTFIELD;
641             case REF_getStatic -> AF_GETSTATIC;
642             case REF_putStatic -> AF_PUTSTATIC;
643             default -> throw new InternalError(m.toString());
644         };
645         if (shouldBeInitialized(m)) {
646             // precompute the barrier-free version:
647             preparedFieldLambdaForm(formOp, isVolatile, ftype);
648             assert((AF_GETSTATIC_INIT - AF_GETSTATIC) ==
649                    (AF_PUTSTATIC_INIT - AF_PUTSTATIC));
650             formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
651         }
652         LambdaForm lform = preparedFieldLambdaForm(formOp, isVolatile, ftype);
653         maybeCompile(lform, m);
654         assert(lform.methodType().dropParameterTypes(0, 1)
655                 .equals(m.getInvocationType().basicType()))
656                 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
657         return lform;
658     }
659     private static LambdaForm preparedFieldLambdaForm(byte formOp, boolean isVolatile, Class<?> ftype) {
660         int ftypeKind = ftypeKind(ftype);
661         int afIndex = afIndex(formOp, isVolatile, ftypeKind);

662         LambdaForm lform = ACCESSOR_FORMS[afIndex];
663         if (lform != null)  return lform;
664         lform = makePreparedFieldLambdaForm(formOp, isVolatile, ftypeKind);
665         ACCESSOR_FORMS[afIndex] = lform;  // don't bother with a CAS
666         return lform;
667     }
668 
669     private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
670 
671     private static Kind getFieldKind(boolean isGetter, boolean isVolatile, Wrapper wrapper) {
672         if (isGetter) {
673             if (isVolatile) {
674                 switch (wrapper) {
675                     case BOOLEAN: return GET_BOOLEAN_VOLATILE;
676                     case BYTE:    return GET_BYTE_VOLATILE;
677                     case SHORT:   return GET_SHORT_VOLATILE;
678                     case CHAR:    return GET_CHAR_VOLATILE;
679                     case INT:     return GET_INT_VOLATILE;
680                     case LONG:    return GET_LONG_VOLATILE;
681                     case FLOAT:   return GET_FLOAT_VOLATILE;
682                     case DOUBLE:  return GET_DOUBLE_VOLATILE;
683                     case OBJECT:  return GET_REFERENCE_VOLATILE;
684                 }
685             } else {
686                 switch (wrapper) {
687                     case BOOLEAN: return GET_BOOLEAN;
688                     case BYTE:    return GET_BYTE;
689                     case SHORT:   return GET_SHORT;
690                     case CHAR:    return GET_CHAR;
691                     case INT:     return GET_INT;
692                     case LONG:    return GET_LONG;
693                     case FLOAT:   return GET_FLOAT;
694                     case DOUBLE:  return GET_DOUBLE;
695                     case OBJECT:  return GET_REFERENCE;
696                 }
697             }
698         } else {
699             if (isVolatile) {
700                 switch (wrapper) {
701                     case BOOLEAN: return PUT_BOOLEAN_VOLATILE;
702                     case BYTE:    return PUT_BYTE_VOLATILE;
703                     case SHORT:   return PUT_SHORT_VOLATILE;
704                     case CHAR:    return PUT_CHAR_VOLATILE;
705                     case INT:     return PUT_INT_VOLATILE;
706                     case LONG:    return PUT_LONG_VOLATILE;
707                     case FLOAT:   return PUT_FLOAT_VOLATILE;
708                     case DOUBLE:  return PUT_DOUBLE_VOLATILE;
709                     case OBJECT:  return PUT_REFERENCE_VOLATILE;
710                 }
711             } else {
712                 switch (wrapper) {
713                     case BOOLEAN: return PUT_BOOLEAN;
714                     case BYTE:    return PUT_BYTE;
715                     case SHORT:   return PUT_SHORT;
716                     case CHAR:    return PUT_CHAR;
717                     case INT:     return PUT_INT;
718                     case LONG:    return PUT_LONG;
719                     case FLOAT:   return PUT_FLOAT;
720                     case DOUBLE:  return PUT_DOUBLE;
721                     case OBJECT:  return PUT_REFERENCE;
722                 }
723             }
724         }
725         throw new AssertionError("Invalid arguments");
726     }
727 
728     static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {





729         boolean isGetter  = (formOp & 1) == (AF_GETFIELD & 1);
730         boolean isStatic  = (formOp >= AF_GETSTATIC);
731         boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
732         boolean needsCast = (ftypeKind == FT_CHECKED_REF);
733         Wrapper fw = (needsCast ? Wrapper.OBJECT : ALL_WRAPPERS[ftypeKind]);
734         Class<?> ft = fw.primitiveType();
735         assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
736 
737         // getObject, putIntVolatile, etc.
738         Kind kind = getFieldKind(isGetter, isVolatile, fw);
739 
740         MethodType linkerType;
741         if (isGetter)
742             linkerType = MethodType.methodType(ft, Object.class, long.class);
743         else
744             linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);




745         MemberName linker = new MemberName(Unsafe.class, kind.methodName, linkerType, REF_invokeVirtual);
746         try {
747             linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, LM_TRUSTED,
748                                               NoSuchMethodException.class);
749         } catch (ReflectiveOperationException ex) {
750             throw newInternalError(ex);
751         }
752 
753         // What is the external type of the lambda form?
754         MethodType mtype;
755         if (isGetter)
756             mtype = MethodType.methodType(ft);
757         else
758             mtype = MethodType.methodType(void.class, ft);
759         mtype = mtype.basicType();  // erase short to int, etc.
760         if (!isStatic)
761             mtype = mtype.insertParameterTypes(0, Object.class);
762         final int DMH_THIS  = 0;
763         final int ARG_BASE  = 1;
764         final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
765         // if this is for non-static access, the base pointer is stored at this index:
766         final int OBJ_BASE  = isStatic ? -1 : ARG_BASE;
767         // if this is for write access, the value to be written is stored at this index:
768         final int SET_VALUE  = isGetter ? -1 : ARG_LIMIT - 1;
769         int nameCursor = ARG_LIMIT;
770         final int F_HOLDER  = (isStatic ? nameCursor++ : -1);  // static base if any
771         final int F_OFFSET  = nameCursor++;  // Either static offset or field offset.
772         final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
773         final int U_HOLDER  = nameCursor++;  // UNSAFE holder
774         final int INIT_BAR  = (needsInit ? nameCursor++ : -1);

775         final int PRE_CAST  = (needsCast && !isGetter ? nameCursor++ : -1);
776         final int LINKER_CALL = nameCursor++;
777         final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
778         final int RESULT    = nameCursor-1;  // either the call or the cast
779         Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
780         if (needsInit)
781             names[INIT_BAR] = new Name(getFunction(NF_ensureInitialized), names[DMH_THIS]);
782         if (needsCast && !isGetter)
783             names[PRE_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[SET_VALUE]);
784         Object[] outArgs = new Object[1 + linkerType.parameterCount()];
785         assert(outArgs.length == (isGetter ? 3 : 4));
786         outArgs[0] = names[U_HOLDER] = new Name(getFunction(NF_UNSAFE));
787         if (isStatic) {
788             outArgs[1] = names[F_HOLDER]  = new Name(getFunction(NF_staticBase), names[DMH_THIS]);
789             outArgs[2] = names[F_OFFSET]  = new Name(getFunction(NF_staticOffset), names[DMH_THIS]);
790         } else {
791             outArgs[1] = names[OBJ_CHECK] = new Name(getFunction(NF_checkBase), names[OBJ_BASE]);
792             outArgs[2] = names[F_OFFSET]  = new Name(getFunction(NF_fieldOffset), names[DMH_THIS]);
793         }





794         if (!isGetter) {
795             outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
796         }
797         for (Object a : outArgs)  assert(a != null);
798         names[LINKER_CALL] = new Name(linker, outArgs);
799         if (needsCast && isGetter)
800             names[POST_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[LINKER_CALL]);
801         for (Name n : names)  assert(n != null);
802 
803         LambdaForm form;
804         if (needsCast || needsInit) {
805             // can't use the pre-generated form when casting and/or initializing
806             form = new LambdaForm(ARG_LIMIT, names, RESULT);
807         } else {
808             form = new LambdaForm(ARG_LIMIT, names, RESULT, kind);
809         }
810 
811         if (LambdaForm.debugNames()) {
812             // add some detail to the lambdaForm debugname,
813             // significant only for debugging
814             StringBuilder nameBuilder = new StringBuilder(kind.methodName);
815             if (isStatic) {

826             LambdaForm.associateWithDebugName(form, nameBuilder.toString());
827         }
828         return form;
829     }
830 
831     /**
832      * Pre-initialized NamedFunctions for bootstrapping purposes.
833      */
834     static final byte NF_internalMemberName = 0,
835             NF_internalMemberNameEnsureInit = 1,
836             NF_ensureInitialized = 2,
837             NF_fieldOffset = 3,
838             NF_checkBase = 4,
839             NF_staticBase = 5,
840             NF_staticOffset = 6,
841             NF_checkCast = 7,
842             NF_allocateInstance = 8,
843             NF_constructorMethod = 9,
844             NF_UNSAFE = 10,
845             NF_checkReceiver = 11,
846             NF_LIMIT = 12;


847 
848     private static final @Stable NamedFunction[] NFS = new NamedFunction[NF_LIMIT];
849 
850     private static NamedFunction getFunction(byte func) {
851         NamedFunction nf = NFS[func];
852         if (nf != null) {
853             return nf;
854         }
855         // Each nf must be statically invocable or we get tied up in our bootstraps.
856         nf = NFS[func] = createFunction(func);
857         assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf));
858         return nf;
859     }
860 


861     private static final MethodType OBJ_OBJ_TYPE = MethodType.methodType(Object.class, Object.class);
862 
863     private static final MethodType LONG_OBJ_TYPE = MethodType.methodType(long.class, Object.class);
864 
865     private static NamedFunction createFunction(byte func) {
866         try {
867             switch (func) {
868                 case NF_internalMemberName:
869                     return getNamedFunction("internalMemberName", OBJ_OBJ_TYPE);
870                 case NF_internalMemberNameEnsureInit:
871                     return getNamedFunction("internalMemberNameEnsureInit", OBJ_OBJ_TYPE);
872                 case NF_ensureInitialized:
873                     return getNamedFunction("ensureInitialized", MethodType.methodType(void.class, Object.class));
874                 case NF_fieldOffset:
875                     return getNamedFunction("fieldOffset", LONG_OBJ_TYPE);
876                 case NF_checkBase:
877                     return getNamedFunction("checkBase", OBJ_OBJ_TYPE);
878                 case NF_staticBase:
879                     return getNamedFunction("staticBase", OBJ_OBJ_TYPE);
880                 case NF_staticOffset:
881                     return getNamedFunction("staticOffset", LONG_OBJ_TYPE);
882                 case NF_checkCast:
883                     return getNamedFunction("checkCast", MethodType.methodType(Object.class, Object.class, Object.class));
884                 case NF_allocateInstance:
885                     return getNamedFunction("allocateInstance", OBJ_OBJ_TYPE);
886                 case NF_constructorMethod:
887                     return getNamedFunction("constructorMethod", OBJ_OBJ_TYPE);
888                 case NF_UNSAFE:
889                     MemberName member = new MemberName(MethodHandleStatics.class, "UNSAFE", Unsafe.class, REF_getField);
890                     return new NamedFunction(
891                             MemberName.getFactory().resolveOrFail(REF_getField, member,
892                                                                   DirectMethodHandle.class, LM_TRUSTED,
893                                                                   NoSuchMethodException.class));
894                 case NF_checkReceiver:
895                     member = new MemberName(DirectMethodHandle.class, "checkReceiver", OBJ_OBJ_TYPE, REF_invokeVirtual);
896                     return new NamedFunction(
897                             MemberName.getFactory().resolveOrFail(REF_invokeVirtual, member,
898                                                                   DirectMethodHandle.class, LM_TRUSTED,
899                                                                   NoSuchMethodException.class));




900                 default:
901                     throw newInternalError("Unknown function: " + func);
902             }
903         } catch (ReflectiveOperationException ex) {
904             throw newInternalError(ex);
905         }
906     }
907 
908     private static NamedFunction getNamedFunction(String name, MethodType type)
909         throws ReflectiveOperationException
910     {
911         MemberName member = new MemberName(DirectMethodHandle.class, name, type, REF_invokeStatic);
912         return new NamedFunction(
913                 MemberName.getFactory().resolveOrFail(REF_invokeStatic, member,
914                                                       DirectMethodHandle.class, LM_TRUSTED,
915                                                       NoSuchMethodException.class));
916     }
917 
918     static {
919         // The Holder class will contain pre-generated DirectMethodHandles resolved

 61         if (member.getDeclaringClass().isInterface() &&
 62             member.getReferenceKind() == REF_invokeInterface &&
 63             member.isMethod() && !member.isAbstract()) {
 64             // Check for corner case: invokeinterface of Object method
 65             MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind());
 66             m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null, LM_TRUSTED);
 67             if (m != null && m.isPublic()) {
 68                 assert(member.getReferenceKind() == m.getReferenceKind());  // else this.form is wrong
 69                 member = m;
 70             }
 71         }
 72 
 73         this.member = member;
 74         this.crackable = crackable;
 75     }
 76 
 77     // Factory methods:
 78     static DirectMethodHandle make(byte refKind, Class<?> refc, MemberName member, Class<?> callerClass) {
 79         MethodType mtype = member.getMethodOrFieldType();
 80         if (!member.isStatic()) {
 81             if (!member.getDeclaringClass().isAssignableFrom(refc) || member.isObjectConstructor())
 82                 throw new InternalError(member.toString());
 83             Class<?> receiverType = refc.isPrimitiveClass() ? refc.asValueType() : refc;
 84             mtype = mtype.insertParameterTypes(0, receiverType);
 85         }
 86         if (!member.isField()) {
 87             // refKind reflects the original type of lookup via findSpecial or
 88             // findVirtual etc.
 89             return switch (refKind) {
 90                 case REF_invokeSpecial -> {
 91                     member = member.asSpecial();
 92                     // if caller is an interface we need to adapt to get the
 93                     // receiver check inserted
 94                     if (callerClass == null) {
 95                         throw new InternalError("callerClass must not be null for REF_invokeSpecial");
 96                     }
 97                     LambdaForm lform = preparedLambdaForm(member, callerClass.isInterface());
 98                     yield new Special(mtype, lform, member, true, callerClass);
 99                 }
100                 case REF_invokeInterface -> {
101                     // for interfaces we always need the receiver typecheck,
102                     // so we always pass 'true' to ensure we adapt if needed
103                     // to include the REF_invokeSpecial case
104                     LambdaForm lform = preparedLambdaForm(member, true);

112         } else {
113             LambdaForm lform = preparedFieldLambdaForm(member);
114             if (member.isStatic()) {
115                 long offset = MethodHandleNatives.staticFieldOffset(member);
116                 Object base = MethodHandleNatives.staticFieldBase(member);
117                 return new StaticAccessor(mtype, lform, member, true, base, offset);
118             } else {
119                 long offset = MethodHandleNatives.objectFieldOffset(member);
120                 assert(offset == (int)offset);
121                 return new Accessor(mtype, lform, member, true, (int)offset);
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.isObjectConstructor() && 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.isObjectConstructor() && !ctor.getDeclaringClass().isPrimitiveClass()) : ctor;
138 
139         Class<?> instanceClass = ctor.getDeclaringClass();
140         ctor = ctor.asObjectConstructor();
141         assert(ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
142         MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
143         LambdaForm lform = preparedLambdaForm(ctor);
144         MemberName init = ctor.asSpecial();
145         assert(init.getMethodType().returnType() == void.class);
146         return new Constructor(mtype, lform, ctor, true, init, instanceClass);
147     }
148 
149     @Override
150     BoundMethodHandle rebind() {
151         return BoundMethodHandle.makeReinvoker(this);
152     }
153 
154     @Override
155     MethodHandle copyWith(MethodType mt, LambdaForm lf) {
156         assert(this.getClass() == DirectMethodHandle.class);  // must override in subclasses
157         return new DirectMethodHandle(mt, lf, member, crackable);
158     }
159 
160     @Override
161     MethodHandle viewAsType(MethodType newType, boolean strict) {

523     /*non-public*/
524     static long fieldOffset(Object accessorObj) {
525         // Note: We return a long because that is what Unsafe.getObject likes.
526         // We store a plain int because it is more compact.
527         return ((Accessor)accessorObj).fieldOffset;
528     }
529 
530     @ForceInline
531     /*non-public*/
532     static Object checkBase(Object obj) {
533         // Note that the object's class has already been verified,
534         // since the parameter type of the Accessor method handle
535         // is either member.getDeclaringClass or a subclass.
536         // This was verified in DirectMethodHandle.make.
537         // Therefore, the only remaining check is for null.
538         // Since this check is *not* guaranteed by Unsafe.getInt
539         // and its siblings, we need to make an explicit one here.
540         return Objects.requireNonNull(obj);
541     }
542 

543     static class StaticAccessor extends DirectMethodHandle {
544         final Class<?> fieldType;
545         final Object staticBase;
546         final long staticOffset;
547 
548         private StaticAccessor(MethodType mtype, LambdaForm form, MemberName member,
549                                boolean crackable, Object staticBase, long staticOffset) {
550             super(mtype, form, member, crackable);
551             this.fieldType    = member.getFieldType();
552             this.staticBase   = staticBase;
553             this.staticOffset = staticOffset;
554         }
555 
556         @Override Object checkCast(Object obj) {
557             return fieldType.cast(obj);
558         }
559         @Override
560         MethodHandle copyWith(MethodType mt, LambdaForm lf) {
561             return new StaticAccessor(mt, lf, member, crackable, staticBase, staticOffset);
562         }
563         @Override
564         MethodHandle viewAsType(MethodType newType, boolean strict) {
565             assert(viewAsTypeChecks(newType, strict));
566             return new StaticAccessor(newType, form, member, false, staticBase, staticOffset);

574     }
575 
576     @ForceInline
577     /*non-public*/
578     static Object staticBase(Object accessorObj) {
579         return ((StaticAccessor)accessorObj).staticBase;
580     }
581 
582     @ForceInline
583     /*non-public*/
584     static long staticOffset(Object accessorObj) {
585         return ((StaticAccessor)accessorObj).staticOffset;
586     }
587 
588     @ForceInline
589     /*non-public*/
590     static Object checkCast(Object mh, Object obj) {
591         return ((DirectMethodHandle) mh).checkCast(obj);
592     }
593 
594     @ForceInline
595     /*non-public*/ static Class<?> fieldType(Object accessorObj) {
596         return ((Accessor) accessorObj).fieldType;
597     }
598 
599     @ForceInline
600     /*non-public*/ static Class<?> staticFieldType(Object accessorObj) {
601         return ((StaticAccessor) accessorObj).fieldType;
602     }
603 
604     Object checkCast(Object obj) {
605         return member.getReturnType().cast(obj);
606     }
607 
608     // Caching machinery for field accessors:
609     static final byte
610             AF_GETFIELD        = 0,
611             AF_PUTFIELD        = 1,
612             AF_GETSTATIC       = 2,
613             AF_PUTSTATIC       = 3,
614             AF_GETSTATIC_INIT  = 4,
615             AF_PUTSTATIC_INIT  = 5,
616             AF_LIMIT           = 6;
617     // Enumerate the different field kinds using Wrapper,
618     // with an extra case added for checked references and value field access
619     static final int
620             FT_LAST_WRAPPER     = Wrapper.COUNT-1,
621             FT_UNCHECKED_REF    = Wrapper.OBJECT.ordinal(),
622             FT_CHECKED_REF      = FT_LAST_WRAPPER+1,
623             FT_CHECKED_VALUE    = FT_LAST_WRAPPER+2,  // flattened and non-flattened
624             FT_LIMIT            = FT_LAST_WRAPPER+4;
625     private static int afIndex(byte formOp, boolean isVolatile, boolean isFlatValue, int ftypeKind) {
626         return ((formOp * FT_LIMIT * 2)
627                 + (isVolatile ? FT_LIMIT : 0)
628                 + (isFlatValue ? 1 : 0)
629                 + ftypeKind);
630     }
631     @Stable
632     private static final LambdaForm[] ACCESSOR_FORMS
633             = new LambdaForm[afIndex(AF_LIMIT, false, false, 0)];
634     static int ftypeKind(Class<?> ftype, boolean isValue) {
635         if (ftype.isPrimitive())
636             return Wrapper.forPrimitiveType(ftype).ordinal();
637         else if (VerifyType.isNullReferenceConversion(Object.class, ftype)) {
638             return FT_UNCHECKED_REF;
639         } else
640             // null check for value type in addition to check cast
641             return isValue ? FT_CHECKED_VALUE : FT_CHECKED_REF;
642     }
643 
644     /**
645      * Create a LF which can access the given field.
646      * Cache and share this structure among all fields with
647      * the same basicType and refKind.
648      */
649     private static LambdaForm preparedFieldLambdaForm(MemberName m) {
650         Class<?> ftype = m.getFieldType();
651         boolean isVolatile = m.isVolatile();
652         byte formOp = switch (m.getReferenceKind()) {
653             case REF_getField  -> AF_GETFIELD;
654             case REF_putField  -> AF_PUTFIELD;
655             case REF_getStatic -> AF_GETSTATIC;
656             case REF_putStatic -> AF_PUTSTATIC;
657             default -> throw new InternalError(m.toString());
658         };
659         if (shouldBeInitialized(m)) {
660             // precompute the barrier-free version:
661             preparedFieldLambdaForm(formOp, m.isVolatile(), m.isInlineableField(), m.isFlattened(), ftype);
662             assert((AF_GETSTATIC_INIT - AF_GETSTATIC) ==
663                    (AF_PUTSTATIC_INIT - AF_PUTSTATIC));
664             formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
665         }
666         LambdaForm lform = preparedFieldLambdaForm(formOp, m.isVolatile(), m.isInlineableField(), m.isFlattened(), ftype);
667         maybeCompile(lform, m);
668         assert(lform.methodType().dropParameterTypes(0, 1)
669                 .equals(m.getInvocationType().basicType()))
670                 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
671         return lform;
672     }
673 
674     private static LambdaForm preparedFieldLambdaForm(byte formOp, boolean isVolatile, boolean isValue, boolean isFlatValue, Class<?> ftype) {
675         int ftypeKind = ftypeKind(ftype, isValue);
676         int afIndex = afIndex(formOp, isVolatile, isFlatValue, ftypeKind);
677         LambdaForm lform = ACCESSOR_FORMS[afIndex];
678         if (lform != null)  return lform;
679         lform = makePreparedFieldLambdaForm(formOp, isVolatile, isValue, isFlatValue, ftypeKind);
680         ACCESSOR_FORMS[afIndex] = lform;  // don't bother with a CAS
681         return lform;
682     }
683 
684     private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
685 
686     private static Kind getFieldKind(boolean isGetter, boolean isVolatile, boolean isFlatValue, Wrapper wrapper) {
687         if (isGetter) {
688             if (isVolatile) {
689                 switch (wrapper) {
690                     case BOOLEAN: return GET_BOOLEAN_VOLATILE;
691                     case BYTE:    return GET_BYTE_VOLATILE;
692                     case SHORT:   return GET_SHORT_VOLATILE;
693                     case CHAR:    return GET_CHAR_VOLATILE;
694                     case INT:     return GET_INT_VOLATILE;
695                     case LONG:    return GET_LONG_VOLATILE;
696                     case FLOAT:   return GET_FLOAT_VOLATILE;
697                     case DOUBLE:  return GET_DOUBLE_VOLATILE;
698                     case OBJECT:  return isFlatValue ? GET_VALUE_VOLATILE : GET_REFERENCE_VOLATILE;
699                 }
700             } else {
701                 switch (wrapper) {
702                     case BOOLEAN: return GET_BOOLEAN;
703                     case BYTE:    return GET_BYTE;
704                     case SHORT:   return GET_SHORT;
705                     case CHAR:    return GET_CHAR;
706                     case INT:     return GET_INT;
707                     case LONG:    return GET_LONG;
708                     case FLOAT:   return GET_FLOAT;
709                     case DOUBLE:  return GET_DOUBLE;
710                     case OBJECT:  return isFlatValue ? GET_VALUE : GET_REFERENCE;
711                 }
712             }
713         } else {
714             if (isVolatile) {
715                 switch (wrapper) {
716                     case BOOLEAN: return PUT_BOOLEAN_VOLATILE;
717                     case BYTE:    return PUT_BYTE_VOLATILE;
718                     case SHORT:   return PUT_SHORT_VOLATILE;
719                     case CHAR:    return PUT_CHAR_VOLATILE;
720                     case INT:     return PUT_INT_VOLATILE;
721                     case LONG:    return PUT_LONG_VOLATILE;
722                     case FLOAT:   return PUT_FLOAT_VOLATILE;
723                     case DOUBLE:  return PUT_DOUBLE_VOLATILE;
724                     case OBJECT:  return isFlatValue ? PUT_VALUE_VOLATILE : PUT_REFERENCE_VOLATILE;
725                 }
726             } else {
727                 switch (wrapper) {
728                     case BOOLEAN: return PUT_BOOLEAN;
729                     case BYTE:    return PUT_BYTE;
730                     case SHORT:   return PUT_SHORT;
731                     case CHAR:    return PUT_CHAR;
732                     case INT:     return PUT_INT;
733                     case LONG:    return PUT_LONG;
734                     case FLOAT:   return PUT_FLOAT;
735                     case DOUBLE:  return PUT_DOUBLE;
736                     case OBJECT:  return isFlatValue ? PUT_VALUE : PUT_REFERENCE;
737                 }
738             }
739         }
740         throw new AssertionError("Invalid arguments");
741     }
742 
743     /** invoked by GenerateJLIClassesHelper */
744     static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftype) {
745         return makePreparedFieldLambdaForm(formOp, isVolatile, false, false, ftype);
746     }
747 
748     private static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, boolean isValue, boolean isFlatValue, int ftypeKind) {
749         boolean isGetter  = (formOp & 1) == (AF_GETFIELD & 1);
750         boolean isStatic  = (formOp >= AF_GETSTATIC);
751         boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
752         boolean needsCast = (ftypeKind == FT_CHECKED_REF || ftypeKind == FT_CHECKED_VALUE);
753         Wrapper fw = (needsCast ? Wrapper.OBJECT : ALL_WRAPPERS[ftypeKind]);
754         Class<?> ft = fw.primitiveType();
755         assert(needsCast ? true : ftypeKind(ft, isValue) == ftypeKind);
756 
757         // getObject, putIntVolatile, etc.
758         Kind kind = getFieldKind(isGetter, isVolatile, isFlatValue, fw);
759 
760         MethodType linkerType;
761         boolean hasValueTypeArg = isGetter ? isValue : isFlatValue;
762         if (isGetter) {
763             linkerType = isValue ? MethodType.methodType(ft, Object.class, long.class, Class.class)
764                                  : MethodType.methodType(ft, Object.class, long.class);
765         } else {
766             linkerType = isFlatValue ? MethodType.methodType(void.class, Object.class, long.class, Class.class, ft)
767                                      : MethodType.methodType(void.class, Object.class, long.class, ft);
768         }
769         MemberName linker = new MemberName(Unsafe.class, kind.methodName, linkerType, REF_invokeVirtual);
770         try {
771             linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, LM_TRUSTED,
772                                               NoSuchMethodException.class);
773         } catch (ReflectiveOperationException ex) {
774             throw newInternalError(ex);
775         }
776 
777         // What is the external type of the lambda form?
778         MethodType mtype;
779         if (isGetter)
780             mtype = MethodType.methodType(ft);
781         else
782             mtype = MethodType.methodType(void.class, ft);
783         mtype = mtype.basicType();  // erase short to int, etc.
784         if (!isStatic)
785             mtype = mtype.insertParameterTypes(0, Object.class);
786         final int DMH_THIS  = 0;
787         final int ARG_BASE  = 1;
788         final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
789         // if this is for non-static access, the base pointer is stored at this index:
790         final int OBJ_BASE  = isStatic ? -1 : ARG_BASE;
791         // if this is for write access, the value to be written is stored at this index:
792         final int SET_VALUE  = isGetter ? -1 : ARG_LIMIT - 1;
793         int nameCursor = ARG_LIMIT;
794         final int F_HOLDER  = (isStatic ? nameCursor++ : -1);  // static base if any
795         final int F_OFFSET  = nameCursor++;  // Either static offset or field offset.
796         final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
797         final int U_HOLDER  = nameCursor++;  // UNSAFE holder
798         final int INIT_BAR  = (needsInit ? nameCursor++ : -1);
799         final int VALUE_TYPE = (hasValueTypeArg ? nameCursor++ : -1);
800         final int PRE_CAST  = (needsCast && !isGetter ? nameCursor++ : -1);
801         final int LINKER_CALL = nameCursor++;
802         final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
803         final int RESULT    = nameCursor-1;  // either the call or the cast
804         Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
805         if (needsInit)
806             names[INIT_BAR] = new Name(getFunction(NF_ensureInitialized), names[DMH_THIS]);
807         if (needsCast && !isGetter)
808             names[PRE_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[SET_VALUE]);
809         Object[] outArgs = new Object[1 + linkerType.parameterCount()];
810         assert (outArgs.length == (isGetter ? 3 : 4) + (hasValueTypeArg ? 1 : 0));
811         outArgs[0] = names[U_HOLDER] = new Name(getFunction(NF_UNSAFE));
812         if (isStatic) {
813             outArgs[1] = names[F_HOLDER]  = new Name(getFunction(NF_staticBase), names[DMH_THIS]);
814             outArgs[2] = names[F_OFFSET]  = new Name(getFunction(NF_staticOffset), names[DMH_THIS]);
815         } else {
816             outArgs[1] = names[OBJ_CHECK] = new Name(getFunction(NF_checkBase), names[OBJ_BASE]);
817             outArgs[2] = names[F_OFFSET]  = new Name(getFunction(NF_fieldOffset), names[DMH_THIS]);
818         }
819         int x = 3;
820         if (hasValueTypeArg) {
821             outArgs[x++] = names[VALUE_TYPE] = isStatic ? new Name(getFunction(NF_staticFieldType), names[DMH_THIS])
822                                                         : new Name(getFunction(NF_fieldType), names[DMH_THIS]);
823         }
824         if (!isGetter) {
825             outArgs[x] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
826         }
827         for (Object a : outArgs)  assert(a != null);
828         names[LINKER_CALL] = new Name(linker, outArgs);
829         if (needsCast && isGetter)
830             names[POST_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[LINKER_CALL]);
831         for (Name n : names)  assert(n != null);
832 
833         LambdaForm form;
834         if (needsCast || needsInit) {
835             // can't use the pre-generated form when casting and/or initializing
836             form = new LambdaForm(ARG_LIMIT, names, RESULT);
837         } else {
838             form = new LambdaForm(ARG_LIMIT, names, RESULT, kind);
839         }
840 
841         if (LambdaForm.debugNames()) {
842             // add some detail to the lambdaForm debugname,
843             // significant only for debugging
844             StringBuilder nameBuilder = new StringBuilder(kind.methodName);
845             if (isStatic) {

856             LambdaForm.associateWithDebugName(form, nameBuilder.toString());
857         }
858         return form;
859     }
860 
861     /**
862      * Pre-initialized NamedFunctions for bootstrapping purposes.
863      */
864     static final byte NF_internalMemberName = 0,
865             NF_internalMemberNameEnsureInit = 1,
866             NF_ensureInitialized = 2,
867             NF_fieldOffset = 3,
868             NF_checkBase = 4,
869             NF_staticBase = 5,
870             NF_staticOffset = 6,
871             NF_checkCast = 7,
872             NF_allocateInstance = 8,
873             NF_constructorMethod = 9,
874             NF_UNSAFE = 10,
875             NF_checkReceiver = 11,
876             NF_fieldType = 12,
877             NF_staticFieldType = 13,
878             NF_LIMIT = 14;
879 
880     private static final @Stable NamedFunction[] NFS = new NamedFunction[NF_LIMIT];
881 
882     private static NamedFunction getFunction(byte func) {
883         NamedFunction nf = NFS[func];
884         if (nf != null) {
885             return nf;
886         }
887         // Each nf must be statically invocable or we get tied up in our bootstraps.
888         nf = NFS[func] = createFunction(func);
889         assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf));
890         return nf;
891     }
892 
893     private static final MethodType CLS_OBJ_TYPE = MethodType.methodType(Class.class, Object.class);
894 
895     private static final MethodType OBJ_OBJ_TYPE = MethodType.methodType(Object.class, Object.class);
896 
897     private static final MethodType LONG_OBJ_TYPE = MethodType.methodType(long.class, Object.class);
898 
899     private static NamedFunction createFunction(byte func) {
900         try {
901             switch (func) {
902                 case NF_internalMemberName:
903                     return getNamedFunction("internalMemberName", OBJ_OBJ_TYPE);
904                 case NF_internalMemberNameEnsureInit:
905                     return getNamedFunction("internalMemberNameEnsureInit", OBJ_OBJ_TYPE);
906                 case NF_ensureInitialized:
907                     return getNamedFunction("ensureInitialized", MethodType.methodType(void.class, Object.class));
908                 case NF_fieldOffset:
909                     return getNamedFunction("fieldOffset", LONG_OBJ_TYPE);
910                 case NF_checkBase:
911                     return getNamedFunction("checkBase", OBJ_OBJ_TYPE);
912                 case NF_staticBase:
913                     return getNamedFunction("staticBase", OBJ_OBJ_TYPE);
914                 case NF_staticOffset:
915                     return getNamedFunction("staticOffset", LONG_OBJ_TYPE);
916                 case NF_checkCast:
917                     return getNamedFunction("checkCast", MethodType.methodType(Object.class, Object.class, Object.class));
918                 case NF_allocateInstance:
919                     return getNamedFunction("allocateInstance", OBJ_OBJ_TYPE);
920                 case NF_constructorMethod:
921                     return getNamedFunction("constructorMethod", OBJ_OBJ_TYPE);
922                 case NF_UNSAFE:
923                     MemberName member = new MemberName(MethodHandleStatics.class, "UNSAFE", Unsafe.class, REF_getField);
924                     return new NamedFunction(
925                             MemberName.getFactory().resolveOrFail(REF_getField, member,
926                                                                   DirectMethodHandle.class, LM_TRUSTED,
927                                                                   NoSuchMethodException.class));
928                 case NF_checkReceiver:
929                     member = new MemberName(DirectMethodHandle.class, "checkReceiver", OBJ_OBJ_TYPE, REF_invokeVirtual);
930                     return new NamedFunction(
931                         MemberName.getFactory().resolveOrFail(REF_invokeVirtual, member,
932                                                               DirectMethodHandle.class, LM_TRUSTED,
933                                                               NoSuchMethodException.class));
934                 case NF_fieldType:
935                     return getNamedFunction("fieldType", CLS_OBJ_TYPE);
936                 case NF_staticFieldType:
937                     return getNamedFunction("staticFieldType", CLS_OBJ_TYPE);
938                 default:
939                     throw newInternalError("Unknown function: " + func);
940             }
941         } catch (ReflectiveOperationException ex) {
942             throw newInternalError(ex);
943         }
944     }
945 
946     private static NamedFunction getNamedFunction(String name, MethodType type)
947         throws ReflectiveOperationException
948     {
949         MemberName member = new MemberName(DirectMethodHandle.class, name, type, REF_invokeStatic);
950         return new NamedFunction(
951                 MemberName.getFactory().resolveOrFail(REF_invokeStatic, member,
952                                                       DirectMethodHandle.class, LM_TRUSTED,
953                                                       NoSuchMethodException.class));
954     }
955 
956     static {
957         // The Holder class will contain pre-generated DirectMethodHandles resolved
< prev index next >