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