115 return new StaticAccessor(mtype, lform, member, true, base, offset);
116 } else {
117 long offset = MethodHandleNatives.objectFieldOffset(member);
118 assert(offset == (int)offset);
119 return new Accessor(mtype, lform, member, true, (int)offset);
120 }
121 }
122 }
123 static DirectMethodHandle make(Class<?> refc, MemberName member) {
124 byte refKind = member.getReferenceKind();
125 if (refKind == REF_invokeSpecial)
126 refKind = REF_invokeVirtual;
127 return make(refKind, refc, member, null /* no callerClass context */);
128 }
129 static DirectMethodHandle make(MemberName member) {
130 if (member.isConstructor())
131 return makeAllocator(member.getDeclaringClass(), member);
132 return make(member.getDeclaringClass(), member);
133 }
134 static DirectMethodHandle makeAllocator(Class<?> instanceClass, MemberName ctor) {
135 assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
136 ctor = ctor.asConstructor();
137 assert(ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
138 MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
139 LambdaForm lform = preparedLambdaForm(ctor);
140 MemberName init = ctor.asSpecial();
141 assert(init.getMethodType().returnType() == void.class);
142 return new Constructor(mtype, lform, ctor, true, init, instanceClass);
143 }
144
145 @Override
146 BoundMethodHandle rebind() {
147 return BoundMethodHandle.makeReinvoker(this);
148 }
149
150 @Override
151 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
152 assert(this.getClass() == DirectMethodHandle.class); // must override in subclasses
153 return new DirectMethodHandle(mt, lf, member, crackable);
154 }
155
156 @Override
157 MethodHandle viewAsType(MethodType newType, boolean strict) {
587 }
588
589 @ForceInline
590 /*non-public*/
591 static Object staticBase(Object accessorObj) {
592 return ((StaticAccessor)accessorObj).staticBase;
593 }
594
595 @ForceInline
596 /*non-public*/
597 static long staticOffset(Object accessorObj) {
598 return ((StaticAccessor)accessorObj).staticOffset;
599 }
600
601 @ForceInline
602 /*non-public*/
603 static Object checkCast(Object mh, Object obj) {
604 return ((DirectMethodHandle) mh).checkCast(obj);
605 }
606
607 Object checkCast(Object obj) {
608 return member.getMethodType().returnType().cast(obj);
609 }
610
611 // Caching machinery for field accessors:
612 static final byte
613 AF_GETFIELD = 0,
614 AF_PUTFIELD = 1,
615 AF_GETSTATIC = 2,
616 AF_PUTSTATIC = 3,
617 AF_GETSTATIC_INIT = 4,
618 AF_PUTSTATIC_INIT = 5,
619 AF_LIMIT = 6;
620 // Enumerate the different field kinds using Wrapper,
621 // with an extra case added for checked references.
622 static final int
623 FT_LAST_WRAPPER = Wrapper.COUNT-1,
624 FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(),
625 FT_CHECKED_REF = FT_LAST_WRAPPER+1,
626 FT_LIMIT = FT_LAST_WRAPPER+2;
627 private static int afIndex(byte formOp, boolean isVolatile, int ftypeKind) {
628 return ((formOp * FT_LIMIT * 2)
629 + (isVolatile ? FT_LIMIT : 0)
630 + ftypeKind);
631 }
632 @Stable
633 private static final LambdaForm[] ACCESSOR_FORMS
634 = new LambdaForm[afIndex(AF_LIMIT, false, 0)];
635 static int ftypeKind(Class<?> ftype) {
636 if (ftype.isPrimitive()) {
637 return Wrapper.forPrimitiveType(ftype).ordinal();
638 } else if (ftype.isInterface() || ftype.isAssignableFrom(Object.class)) {
639 // retyping can be done without a cast
640 return FT_UNCHECKED_REF;
641 } else {
642 return FT_CHECKED_REF;
643 }
644 }
645
646 /**
647 * Create a LF which can access the given field.
648 * Cache and share this structure among all fields with
649 * the same basicType and refKind.
650 */
651 private static LambdaForm preparedFieldLambdaForm(MemberName m) {
652 Class<?> ftype = m.getFieldType();
653 boolean isVolatile = m.isVolatile();
654 byte formOp = switch (m.getReferenceKind()) {
655 case REF_getField -> AF_GETFIELD;
656 case REF_putField -> AF_PUTFIELD;
657 case REF_getStatic -> AF_GETSTATIC;
658 case REF_putStatic -> AF_PUTSTATIC;
659 default -> throw new InternalError(m.toString());
660 };
661 if (shouldBeInitialized(m)) {
662 // precompute the barrier-free version:
663 preparedFieldLambdaForm(formOp, isVolatile, ftype);
664 assert((AF_GETSTATIC_INIT - AF_GETSTATIC) ==
665 (AF_PUTSTATIC_INIT - AF_PUTSTATIC));
666 formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
667 }
668 LambdaForm lform = preparedFieldLambdaForm(formOp, isVolatile, ftype);
669 maybeCompile(lform, m);
670 assert(lform.methodType().dropParameterTypes(0, 1)
671 .equals(m.getInvocationType().basicType()))
672 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
673 return lform;
674 }
675 private static LambdaForm preparedFieldLambdaForm(byte formOp, boolean isVolatile, Class<?> ftype) {
676 int ftypeKind = ftypeKind(ftype);
677 int afIndex = afIndex(formOp, isVolatile, ftypeKind);
678 LambdaForm lform = ACCESSOR_FORMS[afIndex];
679 if (lform != null) return lform;
680 lform = makePreparedFieldLambdaForm(formOp, isVolatile, ftypeKind);
681 ACCESSOR_FORMS[afIndex] = lform; // don't bother with a CAS
682 return lform;
683 }
684
685 private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
686
687 private static Kind getFieldKind(boolean isGetter, boolean isVolatile, Wrapper wrapper) {
688 if (isGetter) {
689 if (isVolatile) {
690 switch (wrapper) {
691 case BOOLEAN: return GET_BOOLEAN_VOLATILE;
692 case BYTE: return GET_BYTE_VOLATILE;
693 case SHORT: return GET_SHORT_VOLATILE;
694 case CHAR: return GET_CHAR_VOLATILE;
695 case INT: return GET_INT_VOLATILE;
696 case LONG: return GET_LONG_VOLATILE;
697 case FLOAT: return GET_FLOAT_VOLATILE;
698 case DOUBLE: return GET_DOUBLE_VOLATILE;
699 case OBJECT: return GET_REFERENCE_VOLATILE;
700 }
701 } else {
702 switch (wrapper) {
703 case BOOLEAN: return GET_BOOLEAN;
704 case BYTE: return GET_BYTE;
705 case SHORT: return GET_SHORT;
706 case CHAR: return GET_CHAR;
707 case INT: return GET_INT;
708 case LONG: return GET_LONG;
709 case FLOAT: return GET_FLOAT;
710 case DOUBLE: return GET_DOUBLE;
711 case OBJECT: return GET_REFERENCE;
712 }
713 }
714 } else {
715 if (isVolatile) {
716 switch (wrapper) {
717 case BOOLEAN: return PUT_BOOLEAN_VOLATILE;
718 case BYTE: return PUT_BYTE_VOLATILE;
719 case SHORT: return PUT_SHORT_VOLATILE;
720 case CHAR: return PUT_CHAR_VOLATILE;
721 case INT: return PUT_INT_VOLATILE;
722 case LONG: return PUT_LONG_VOLATILE;
723 case FLOAT: return PUT_FLOAT_VOLATILE;
724 case DOUBLE: return PUT_DOUBLE_VOLATILE;
725 case OBJECT: return PUT_REFERENCE_VOLATILE;
726 }
727 } else {
728 switch (wrapper) {
729 case BOOLEAN: return PUT_BOOLEAN;
730 case BYTE: return PUT_BYTE;
731 case SHORT: return PUT_SHORT;
732 case CHAR: return PUT_CHAR;
733 case INT: return PUT_INT;
734 case LONG: return PUT_LONG;
735 case FLOAT: return PUT_FLOAT;
736 case DOUBLE: return PUT_DOUBLE;
737 case OBJECT: return PUT_REFERENCE;
738 }
739 }
740 }
741 throw new AssertionError("Invalid arguments");
742 }
743
744 static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
745 boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1);
746 boolean isStatic = (formOp >= AF_GETSTATIC);
747 boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
748 boolean needsCast = (ftypeKind == FT_CHECKED_REF);
749 Wrapper fw = (needsCast ? Wrapper.OBJECT : ALL_WRAPPERS[ftypeKind]);
750 Class<?> ft = fw.primitiveType();
751 assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
752
753 // getObject, putIntVolatile, etc.
754 Kind kind = getFieldKind(isGetter, isVolatile, fw);
755
756 MethodType linkerType;
757 if (isGetter)
758 linkerType = MethodType.methodType(ft, Object.class, long.class);
759 else
760 linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
761 MemberName linker = new MemberName(Unsafe.class, kind.methodName, linkerType, REF_invokeVirtual);
762 try {
763 linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, LM_TRUSTED,
764 NoSuchMethodException.class);
765 } catch (ReflectiveOperationException ex) {
766 throw newInternalError(ex);
767 }
768
769 // What is the external type of the lambda form?
770 MethodType mtype;
771 if (isGetter)
772 mtype = MethodType.methodType(ft);
773 else
774 mtype = MethodType.methodType(void.class, ft);
775 mtype = mtype.basicType(); // erase short to int, etc.
776 if (!isStatic)
777 mtype = mtype.insertParameterTypes(0, Object.class);
778 final int DMH_THIS = 0;
779 final int ARG_BASE = 1;
780 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
781 // if this is for non-static access, the base pointer is stored at this index:
782 final int OBJ_BASE = isStatic ? -1 : ARG_BASE;
783 // if this is for write access, the value to be written is stored at this index:
784 final int SET_VALUE = isGetter ? -1 : ARG_LIMIT - 1;
785 int nameCursor = ARG_LIMIT;
786 final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any
787 final int F_OFFSET = nameCursor++; // Either static offset or field offset.
788 final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
789 final int U_HOLDER = nameCursor++; // UNSAFE holder
790 final int INIT_BAR = (needsInit ? nameCursor++ : -1);
791 final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
792 final int LINKER_CALL = nameCursor++;
793 final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
794 final int RESULT = nameCursor-1; // either the call or the cast
795 Name[] names = invokeArguments(nameCursor - ARG_LIMIT, mtype);
796 if (needsInit)
797 names[INIT_BAR] = new Name(getFunction(NF_ensureInitialized), names[DMH_THIS]);
798 if (needsCast && !isGetter)
799 names[PRE_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[SET_VALUE]);
800 Object[] outArgs = new Object[1 + linkerType.parameterCount()];
801 assert(outArgs.length == (isGetter ? 3 : 4));
802 outArgs[0] = names[U_HOLDER] = new Name(getFunction(NF_UNSAFE));
803 if (isStatic) {
804 outArgs[1] = names[F_HOLDER] = new Name(getFunction(NF_staticBase), names[DMH_THIS]);
805 outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_staticOffset), names[DMH_THIS]);
806 } else {
807 outArgs[1] = names[OBJ_CHECK] = new Name(getFunction(NF_checkBase), names[OBJ_BASE]);
808 outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_fieldOffset), names[DMH_THIS]);
809 }
810 if (!isGetter) {
811 outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
812 }
813 for (Object a : outArgs) assert(a != null);
814 names[LINKER_CALL] = new Name(linker, outArgs);
815 if (needsCast && isGetter)
816 names[POST_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[LINKER_CALL]);
817 for (Name n : names) assert(n != null);
818
819 LambdaForm form;
820 if (needsCast || needsInit) {
821 // can't use the pre-generated form when casting and/or initializing
822 form = LambdaForm.create(ARG_LIMIT, names, RESULT);
823 } else {
824 form = LambdaForm.create(ARG_LIMIT, names, RESULT, kind);
825 }
826
827 if (LambdaForm.debugNames()) {
828 // add some detail to the lambdaForm debugname,
829 // significant only for debugging
830 StringBuilder nameBuilder = new StringBuilder(kind.methodName);
831 if (isStatic) {
832 nameBuilder.append("Static");
833 } else {
834 nameBuilder.append("Field");
835 }
836 if (needsCast) {
842 LambdaForm.associateWithDebugName(form, nameBuilder.toString());
843 }
844 return form;
845 }
846
847 /**
848 * Pre-initialized NamedFunctions for bootstrapping purposes.
849 */
850 static final byte NF_internalMemberName = 0,
851 NF_internalMemberNameEnsureInit = 1,
852 NF_ensureInitialized = 2,
853 NF_fieldOffset = 3,
854 NF_checkBase = 4,
855 NF_staticBase = 5,
856 NF_staticOffset = 6,
857 NF_checkCast = 7,
858 NF_allocateInstance = 8,
859 NF_constructorMethod = 9,
860 NF_UNSAFE = 10,
861 NF_checkReceiver = 11,
862 NF_LIMIT = 12;
863
864 private static final @Stable NamedFunction[] NFS = new NamedFunction[NF_LIMIT];
865
866 private static NamedFunction getFunction(byte func) {
867 NamedFunction nf = NFS[func];
868 if (nf != null) {
869 return nf;
870 }
871 // Each nf must be statically invocable or we get tied up in our bootstraps.
872 nf = NFS[func] = createFunction(func);
873 assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf));
874 return nf;
875 }
876
877 private static final MethodType OBJ_OBJ_TYPE = MethodType.methodType(Object.class, Object.class);
878
879 private static final MethodType LONG_OBJ_TYPE = MethodType.methodType(long.class, Object.class);
880
881 private static NamedFunction createFunction(byte func) {
882 try {
883 switch (func) {
884 case NF_internalMemberName:
885 return getNamedFunction("internalMemberName", OBJ_OBJ_TYPE);
886 case NF_internalMemberNameEnsureInit:
887 return getNamedFunction("internalMemberNameEnsureInit", OBJ_OBJ_TYPE);
888 case NF_ensureInitialized:
889 return getNamedFunction("ensureInitialized", MethodType.methodType(void.class, Object.class));
890 case NF_fieldOffset:
891 return getNamedFunction("fieldOffset", LONG_OBJ_TYPE);
892 case NF_checkBase:
893 return getNamedFunction("checkBase", OBJ_OBJ_TYPE);
894 case NF_staticBase:
895 return getNamedFunction("staticBase", OBJ_OBJ_TYPE);
896 case NF_staticOffset:
897 return getNamedFunction("staticOffset", LONG_OBJ_TYPE);
898 case NF_checkCast:
899 return getNamedFunction("checkCast", MethodType.methodType(Object.class, Object.class, Object.class));
900 case NF_allocateInstance:
901 return getNamedFunction("allocateInstance", OBJ_OBJ_TYPE);
902 case NF_constructorMethod:
903 return getNamedFunction("constructorMethod", OBJ_OBJ_TYPE);
904 case NF_UNSAFE:
905 MemberName member = new MemberName(MethodHandleStatics.class, "UNSAFE", Unsafe.class, REF_getStatic);
906 return new NamedFunction(
907 MemberName.getFactory().resolveOrFail(REF_getStatic, member,
908 DirectMethodHandle.class, LM_TRUSTED,
909 NoSuchFieldException.class));
910 case NF_checkReceiver:
911 member = new MemberName(DirectMethodHandle.class, "checkReceiver", OBJ_OBJ_TYPE, REF_invokeVirtual);
912 return new NamedFunction(
913 MemberName.getFactory().resolveOrFail(REF_invokeVirtual, member,
914 DirectMethodHandle.class, LM_TRUSTED,
915 NoSuchMethodException.class));
916 default:
917 throw newInternalError("Unknown function: " + func);
918 }
919 } catch (ReflectiveOperationException ex) {
920 throw newInternalError(ex);
921 }
922 }
923
924 private static NamedFunction getNamedFunction(String name, MethodType type)
925 throws ReflectiveOperationException
926 {
927 MemberName member = new MemberName(DirectMethodHandle.class, name, type, REF_invokeStatic);
928 return new NamedFunction(
929 MemberName.getFactory().resolveOrFail(REF_invokeStatic, member,
930 DirectMethodHandle.class, LM_TRUSTED,
931 NoSuchMethodException.class));
932 }
933
934 static {
935 // The Holder class will contain pre-generated DirectMethodHandles resolved
|
115 return new StaticAccessor(mtype, lform, member, true, base, offset);
116 } else {
117 long offset = MethodHandleNatives.objectFieldOffset(member);
118 assert(offset == (int)offset);
119 return new Accessor(mtype, lform, member, true, (int)offset);
120 }
121 }
122 }
123 static DirectMethodHandle make(Class<?> refc, MemberName member) {
124 byte refKind = member.getReferenceKind();
125 if (refKind == REF_invokeSpecial)
126 refKind = REF_invokeVirtual;
127 return make(refKind, refc, member, null /* no callerClass context */);
128 }
129 static DirectMethodHandle make(MemberName member) {
130 if (member.isConstructor())
131 return makeAllocator(member.getDeclaringClass(), member);
132 return make(member.getDeclaringClass(), member);
133 }
134 static DirectMethodHandle makeAllocator(Class<?> instanceClass, MemberName ctor) {
135 assert(ctor.isConstructor()) : ctor;
136 ctor = ctor.asConstructor();
137 assert(ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
138 MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
139 LambdaForm lform = preparedLambdaForm(ctor);
140 MemberName init = ctor.asSpecial();
141 assert(init.getMethodType().returnType() == void.class);
142 return new Constructor(mtype, lform, ctor, true, init, instanceClass);
143 }
144
145 @Override
146 BoundMethodHandle rebind() {
147 return BoundMethodHandle.makeReinvoker(this);
148 }
149
150 @Override
151 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
152 assert(this.getClass() == DirectMethodHandle.class); // must override in subclasses
153 return new DirectMethodHandle(mt, lf, member, crackable);
154 }
155
156 @Override
157 MethodHandle viewAsType(MethodType newType, boolean strict) {
587 }
588
589 @ForceInline
590 /*non-public*/
591 static Object staticBase(Object accessorObj) {
592 return ((StaticAccessor)accessorObj).staticBase;
593 }
594
595 @ForceInline
596 /*non-public*/
597 static long staticOffset(Object accessorObj) {
598 return ((StaticAccessor)accessorObj).staticOffset;
599 }
600
601 @ForceInline
602 /*non-public*/
603 static Object checkCast(Object mh, Object obj) {
604 return ((DirectMethodHandle) mh).checkCast(obj);
605 }
606
607 @ForceInline
608 /*non-public*/ static Class<?> fieldType(Object accessorObj) {
609 return ((Accessor) accessorObj).fieldType;
610 }
611
612 @ForceInline
613 /*non-public*/ static Class<?> staticFieldType(Object accessorObj) {
614 return ((StaticAccessor) accessorObj).fieldType;
615 }
616
617 @ForceInline
618 /*non-public*/ static Object zeroInstanceIfNull(Class<?> fieldType, Object obj) {
619 return obj != null ? obj : UNSAFE.uninitializedDefaultValue(fieldType);
620 }
621
622 Object checkCast(Object obj) {
623 return member.getMethodType().returnType().cast(obj);
624 }
625
626 // Caching machinery for field accessors:
627 static final byte
628 AF_GETFIELD = 0,
629 AF_PUTFIELD = 1,
630 AF_GETSTATIC = 2,
631 AF_PUTSTATIC = 3,
632 AF_GETSTATIC_INIT = 4,
633 AF_PUTSTATIC_INIT = 5,
634 AF_LIMIT = 6;
635 // Enumerate the different field kinds using Wrapper,
636 // with an extra case added for checked references and value field access
637 static final int
638 FT_LAST_WRAPPER = Wrapper.COUNT-1,
639 FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(),
640 FT_CHECKED_REF = FT_LAST_WRAPPER+1,
641 FT_CHECKED_VALUE = FT_LAST_WRAPPER+2, // flat vs non-flat x null value vs null-restricted value
642 FT_LIMIT = FT_LAST_WRAPPER+6;
643 private static int afIndex(byte formOp, boolean isVolatile, boolean isFlat, boolean isNullRestricted, int ftypeKind) {
644 return ((formOp * FT_LIMIT * 2)
645 + (isVolatile ? FT_LIMIT : 0)
646 + (isFlat ? 1 : 0)
647 + (isNullRestricted ? 1 : 0)
648 + ftypeKind);
649 }
650 @Stable
651 private static final LambdaForm[] ACCESSOR_FORMS
652 = new LambdaForm[afIndex(AF_LIMIT, false, false, false, 0)];
653 static int ftypeKind(Class<?> ftype) {
654 if (ftype.isPrimitive()) {
655 return Wrapper.forPrimitiveType(ftype).ordinal();
656 } else if (ftype.isInterface() || ftype.isAssignableFrom(Object.class)) {
657 // retyping can be done without a cast
658 return FT_UNCHECKED_REF;
659 } else {
660 return ftype.isValue() ? FT_CHECKED_VALUE : FT_CHECKED_REF;
661 }
662 }
663
664 /**
665 * Create a LF which can access the given field.
666 * Cache and share this structure among all fields with
667 * the same basicType and refKind.
668 */
669 private static LambdaForm preparedFieldLambdaForm(MemberName m) {
670 Class<?> ftype = m.getFieldType();
671 byte formOp = switch (m.getReferenceKind()) {
672 case REF_getField -> AF_GETFIELD;
673 case REF_putField -> AF_PUTFIELD;
674 case REF_getStatic -> AF_GETSTATIC;
675 case REF_putStatic -> AF_PUTSTATIC;
676 default -> throw new InternalError(m.toString());
677 };
678 if (shouldBeInitialized(m)) {
679 // precompute the barrier-free version:
680 preparedFieldLambdaForm(formOp, m.isVolatile(), m.isFlat(), m.isNullRestricted(), ftype);
681 assert((AF_GETSTATIC_INIT - AF_GETSTATIC) ==
682 (AF_PUTSTATIC_INIT - AF_PUTSTATIC));
683 formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
684 }
685 LambdaForm lform = preparedFieldLambdaForm(formOp, m.isVolatile(), m.isFlat(), m.isNullRestricted(), ftype);
686 maybeCompile(lform, m);
687 assert(lform.methodType().dropParameterTypes(0, 1)
688 .equals(m.getInvocationType().basicType()))
689 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
690 return lform;
691 }
692
693 private static LambdaForm preparedFieldLambdaForm(byte formOp, boolean isVolatile,
694 boolean isFlat, boolean isNullRestricted, Class<?> ftype) {
695 int ftypeKind = ftypeKind(ftype);
696 int afIndex = afIndex(formOp, isVolatile, isFlat, isNullRestricted, ftypeKind);
697 LambdaForm lform = ACCESSOR_FORMS[afIndex];
698 if (lform != null) return lform;
699 lform = makePreparedFieldLambdaForm(formOp, isVolatile,isFlat, isNullRestricted, ftypeKind);
700 ACCESSOR_FORMS[afIndex] = lform; // don't bother with a CAS
701 return lform;
702 }
703
704 private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
705
706 private static Kind getFieldKind(boolean isGetter, boolean isVolatile, boolean isFlat, Wrapper wrapper) {
707 if (isGetter) {
708 if (isVolatile) {
709 switch (wrapper) {
710 case BOOLEAN: return GET_BOOLEAN_VOLATILE;
711 case BYTE: return GET_BYTE_VOLATILE;
712 case SHORT: return GET_SHORT_VOLATILE;
713 case CHAR: return GET_CHAR_VOLATILE;
714 case INT: return GET_INT_VOLATILE;
715 case LONG: return GET_LONG_VOLATILE;
716 case FLOAT: return GET_FLOAT_VOLATILE;
717 case DOUBLE: return GET_DOUBLE_VOLATILE;
718 case OBJECT: return isFlat ? GET_VALUE_VOLATILE : GET_REFERENCE_VOLATILE;
719 }
720 } else {
721 switch (wrapper) {
722 case BOOLEAN: return GET_BOOLEAN;
723 case BYTE: return GET_BYTE;
724 case SHORT: return GET_SHORT;
725 case CHAR: return GET_CHAR;
726 case INT: return GET_INT;
727 case LONG: return GET_LONG;
728 case FLOAT: return GET_FLOAT;
729 case DOUBLE: return GET_DOUBLE;
730 case OBJECT: return isFlat ? GET_VALUE : GET_REFERENCE;
731 }
732 }
733 } else {
734 if (isVolatile) {
735 switch (wrapper) {
736 case BOOLEAN: return PUT_BOOLEAN_VOLATILE;
737 case BYTE: return PUT_BYTE_VOLATILE;
738 case SHORT: return PUT_SHORT_VOLATILE;
739 case CHAR: return PUT_CHAR_VOLATILE;
740 case INT: return PUT_INT_VOLATILE;
741 case LONG: return PUT_LONG_VOLATILE;
742 case FLOAT: return PUT_FLOAT_VOLATILE;
743 case DOUBLE: return PUT_DOUBLE_VOLATILE;
744 case OBJECT: return isFlat ? PUT_VALUE_VOLATILE : PUT_REFERENCE_VOLATILE;
745 }
746 } else {
747 switch (wrapper) {
748 case BOOLEAN: return PUT_BOOLEAN;
749 case BYTE: return PUT_BYTE;
750 case SHORT: return PUT_SHORT;
751 case CHAR: return PUT_CHAR;
752 case INT: return PUT_INT;
753 case LONG: return PUT_LONG;
754 case FLOAT: return PUT_FLOAT;
755 case DOUBLE: return PUT_DOUBLE;
756 case OBJECT: return isFlat ? PUT_VALUE : PUT_REFERENCE;
757 }
758 }
759 }
760 throw new AssertionError("Invalid arguments");
761 }
762
763 /** invoked by GenerateJLIClassesHelper */
764 static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftype) {
765 return makePreparedFieldLambdaForm(formOp, isVolatile, false, false, ftype);
766 }
767
768 private static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile,
769 boolean isFlat, boolean isNullRestricted, int ftypeKind) {
770 boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1);
771 boolean isStatic = (formOp >= AF_GETSTATIC);
772 boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
773 boolean needsCast = (ftypeKind == FT_CHECKED_REF || ftypeKind == FT_CHECKED_VALUE);
774 Wrapper fw = (needsCast ? Wrapper.OBJECT : ALL_WRAPPERS[ftypeKind]);
775 Class<?> ft = fw.primitiveType();
776 assert(needsCast ? true : ftypeKind(ft) == ftypeKind);
777
778 // getObject, putIntVolatile, etc.
779 Kind kind = getFieldKind(isGetter, isVolatile, isFlat, fw);
780
781 MethodType linkerType;
782 if (isGetter) {
783 linkerType = isFlat
784 ? MethodType.methodType(ft, Object.class, long.class, Class.class)
785 : MethodType.methodType(ft, Object.class, long.class);
786 } else {
787 linkerType = isFlat
788 ? MethodType.methodType(void.class, Object.class, long.class, Class.class, ft)
789 : MethodType.methodType(void.class, Object.class, long.class, ft);
790 }
791 MemberName linker = new MemberName(Unsafe.class, kind.methodName, linkerType, REF_invokeVirtual);
792 try {
793 linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, LM_TRUSTED,
794 NoSuchMethodException.class);
795 } catch (ReflectiveOperationException ex) {
796 throw newInternalError(ex);
797 }
798
799 // What is the external type of the lambda form?
800 MethodType mtype;
801 if (isGetter)
802 mtype = MethodType.methodType(ft);
803 else
804 mtype = MethodType.methodType(void.class, ft);
805 mtype = mtype.basicType(); // erase short to int, etc.
806 if (!isStatic)
807 mtype = mtype.insertParameterTypes(0, Object.class);
808 final int DMH_THIS = 0;
809 final int ARG_BASE = 1;
810 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
811 // if this is for non-static access, the base pointer is stored at this index:
812 final int OBJ_BASE = isStatic ? -1 : ARG_BASE;
813 // if this is for write access, the value to be written is stored at this index:
814 final int SET_VALUE = isGetter ? -1 : ARG_LIMIT - 1;
815 int nameCursor = ARG_LIMIT;
816 final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any
817 final int F_OFFSET = nameCursor++; // Either static offset or field offset.
818 final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
819 final int U_HOLDER = nameCursor++; // UNSAFE holder
820 final int INIT_BAR = (needsInit ? nameCursor++ : -1);
821 final int VALUE_TYPE = (isFlat ? nameCursor++ : -1);
822 final int NULL_CHECK = (isNullRestricted && !isGetter ? nameCursor++ : -1);
823 final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
824 final int LINKER_CALL = nameCursor++;
825 final int FIELD_TYPE = (isNullRestricted && isGetter ? nameCursor++ : -1);
826 final int ZERO_INSTANCE = (isNullRestricted && isGetter ? nameCursor++ : -1);
827 final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
828 final int RESULT = nameCursor-1; // either the call, zero instance, or the cast
829 Name[] names = invokeArguments(nameCursor - ARG_LIMIT, mtype);
830 if (needsInit)
831 names[INIT_BAR] = new Name(getFunction(NF_ensureInitialized), names[DMH_THIS]);
832 if (!isGetter) {
833 if (isNullRestricted)
834 names[NULL_CHECK] = new Name(getFunction(NF_nullCheck), names[SET_VALUE]);
835 if (needsCast)
836 names[PRE_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[SET_VALUE]);
837 }
838 Object[] outArgs = new Object[1 + linkerType.parameterCount()];
839 assert (outArgs.length == (isGetter ? 3 : 4) + (isFlat ? 1 : 0));
840 outArgs[0] = names[U_HOLDER] = new Name(getFunction(NF_UNSAFE));
841 if (isStatic) {
842 outArgs[1] = names[F_HOLDER] = new Name(getFunction(NF_staticBase), names[DMH_THIS]);
843 outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_staticOffset), names[DMH_THIS]);
844 } else {
845 outArgs[1] = names[OBJ_CHECK] = new Name(getFunction(NF_checkBase), names[OBJ_BASE]);
846 outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_fieldOffset), names[DMH_THIS]);
847 }
848 int x = 3;
849 if (isFlat) {
850 outArgs[x++] = names[VALUE_TYPE] = isStatic ? new Name(getFunction(NF_staticFieldType), names[DMH_THIS])
851 : new Name(getFunction(NF_fieldType), names[DMH_THIS]);
852 }
853 if (!isGetter) {
854 outArgs[x] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
855 }
856 for (Object a : outArgs) assert(a != null);
857 names[LINKER_CALL] = new Name(linker, outArgs);
858 if (isGetter) {
859 int argIndex = LINKER_CALL;
860 if (isNullRestricted) {
861 names[FIELD_TYPE] = isStatic ? new Name(getFunction(NF_staticFieldType), names[DMH_THIS])
862 : new Name(getFunction(NF_fieldType), names[DMH_THIS]);
863 names[ZERO_INSTANCE] = new Name(getFunction(NF_zeroInstance), names[FIELD_TYPE], names[LINKER_CALL]);
864 argIndex = ZERO_INSTANCE;
865 }
866 if (needsCast)
867 names[POST_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[argIndex]);
868 }
869 for (Name n : names) assert(n != null);
870
871 LambdaForm form;
872 if (needsCast || needsInit) {
873 // can't use the pre-generated form when casting and/or initializing
874 form = LambdaForm.create(ARG_LIMIT, names, RESULT);
875 } else {
876 form = LambdaForm.create(ARG_LIMIT, names, RESULT, kind);
877 }
878
879 if (LambdaForm.debugNames()) {
880 // add some detail to the lambdaForm debugname,
881 // significant only for debugging
882 StringBuilder nameBuilder = new StringBuilder(kind.methodName);
883 if (isStatic) {
884 nameBuilder.append("Static");
885 } else {
886 nameBuilder.append("Field");
887 }
888 if (needsCast) {
894 LambdaForm.associateWithDebugName(form, nameBuilder.toString());
895 }
896 return form;
897 }
898
899 /**
900 * Pre-initialized NamedFunctions for bootstrapping purposes.
901 */
902 static final byte NF_internalMemberName = 0,
903 NF_internalMemberNameEnsureInit = 1,
904 NF_ensureInitialized = 2,
905 NF_fieldOffset = 3,
906 NF_checkBase = 4,
907 NF_staticBase = 5,
908 NF_staticOffset = 6,
909 NF_checkCast = 7,
910 NF_allocateInstance = 8,
911 NF_constructorMethod = 9,
912 NF_UNSAFE = 10,
913 NF_checkReceiver = 11,
914 NF_fieldType = 12,
915 NF_staticFieldType = 13,
916 NF_zeroInstance = 14,
917 NF_nullCheck = 15,
918 NF_LIMIT = 16;
919
920 private static final @Stable NamedFunction[] NFS = new NamedFunction[NF_LIMIT];
921
922 private static NamedFunction getFunction(byte func) {
923 NamedFunction nf = NFS[func];
924 if (nf != null) {
925 return nf;
926 }
927 // Each nf must be statically invocable or we get tied up in our bootstraps.
928 nf = NFS[func] = createFunction(func);
929 assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf));
930 return nf;
931 }
932
933 private static final MethodType CLS_OBJ_TYPE = MethodType.methodType(Class.class, Object.class);
934
935 private static final MethodType OBJ_OBJ_TYPE = MethodType.methodType(Object.class, Object.class);
936
937 private static final MethodType LONG_OBJ_TYPE = MethodType.methodType(long.class, Object.class);
938
939 private static NamedFunction createFunction(byte func) {
940 try {
941 switch (func) {
942 case NF_internalMemberName:
943 return getNamedFunction("internalMemberName", OBJ_OBJ_TYPE);
944 case NF_internalMemberNameEnsureInit:
945 return getNamedFunction("internalMemberNameEnsureInit", OBJ_OBJ_TYPE);
946 case NF_ensureInitialized:
947 return getNamedFunction("ensureInitialized", MethodType.methodType(void.class, Object.class));
948 case NF_fieldOffset:
949 return getNamedFunction("fieldOffset", LONG_OBJ_TYPE);
950 case NF_checkBase:
951 return getNamedFunction("checkBase", OBJ_OBJ_TYPE);
952 case NF_staticBase:
953 return getNamedFunction("staticBase", OBJ_OBJ_TYPE);
954 case NF_staticOffset:
955 return getNamedFunction("staticOffset", LONG_OBJ_TYPE);
956 case NF_checkCast:
957 return getNamedFunction("checkCast", MethodType.methodType(Object.class, Object.class, Object.class));
958 case NF_allocateInstance:
959 return getNamedFunction("allocateInstance", OBJ_OBJ_TYPE);
960 case NF_constructorMethod:
961 return getNamedFunction("constructorMethod", OBJ_OBJ_TYPE);
962 case NF_UNSAFE:
963 MemberName member = new MemberName(MethodHandleStatics.class, "UNSAFE", Unsafe.class, REF_getStatic);
964 return new NamedFunction(
965 MemberName.getFactory().resolveOrFail(REF_getStatic, member,
966 DirectMethodHandle.class, LM_TRUSTED,
967 NoSuchFieldException.class));
968 case NF_checkReceiver:
969 member = new MemberName(DirectMethodHandle.class, "checkReceiver", OBJ_OBJ_TYPE, REF_invokeVirtual);
970 return new NamedFunction(
971 MemberName.getFactory().resolveOrFail(REF_invokeVirtual, member,
972 DirectMethodHandle.class, LM_TRUSTED,
973 NoSuchMethodException.class));
974 case NF_fieldType:
975 return getNamedFunction("fieldType", CLS_OBJ_TYPE);
976 case NF_staticFieldType:
977 return getNamedFunction("staticFieldType", CLS_OBJ_TYPE);
978 case NF_zeroInstance:
979 return getNamedFunction("zeroInstanceIfNull", MethodType.methodType(Object.class, Class.class, Object.class));
980 case NF_nullCheck:
981 return getNamedFunction("nullCheck", OBJ_OBJ_TYPE);
982 default:
983 throw newInternalError("Unknown function: " + func);
984 }
985 } catch (ReflectiveOperationException ex) {
986 throw newInternalError(ex);
987 }
988 }
989
990 private static NamedFunction getNamedFunction(String name, MethodType type)
991 throws ReflectiveOperationException
992 {
993 MemberName member = new MemberName(DirectMethodHandle.class, name, type, REF_invokeStatic);
994 return new NamedFunction(
995 MemberName.getFactory().resolveOrFail(REF_invokeStatic, member,
996 DirectMethodHandle.class, LM_TRUSTED,
997 NoSuchMethodException.class));
998 }
999
1000 static {
1001 // The Holder class will contain pre-generated DirectMethodHandles resolved
|