10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import jdk.internal.misc.CDS;
29 import jdk.internal.misc.Unsafe;
30 import jdk.internal.vm.annotation.AOTSafeClassInitializer;
31 import jdk.internal.vm.annotation.ForceInline;
32 import jdk.internal.vm.annotation.Stable;
33 import sun.invoke.util.ValueConversions;
34 import sun.invoke.util.VerifyAccess;
35 import sun.invoke.util.Wrapper;
36
37 import java.util.Arrays;
38 import java.util.Objects;
39 import java.util.function.Function;
40
41 import static java.lang.invoke.LambdaForm.*;
42 import static java.lang.invoke.LambdaForm.Kind.*;
43 import static java.lang.invoke.MethodHandleNatives.Constants.*;
44 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
45 import static java.lang.invoke.MethodHandleStatics.newInternalError;
46 import static java.lang.invoke.MethodTypeForm.*;
47
48 /**
49 * The flavor of method handle which implements a constant reference
118 return new StaticAccessor(mtype, lform, member, true, base, offset);
119 } else {
120 long offset = MethodHandleNatives.objectFieldOffset(member);
121 assert(offset == (int)offset);
122 return new Accessor(mtype, lform, member, true, (int)offset);
123 }
124 }
125 }
126 static DirectMethodHandle make(Class<?> refc, MemberName member) {
127 byte refKind = member.getReferenceKind();
128 if (refKind == REF_invokeSpecial)
129 refKind = REF_invokeVirtual;
130 return make(refKind, refc, member, null /* no callerClass context */);
131 }
132 static DirectMethodHandle make(MemberName member) {
133 if (member.isConstructor())
134 return makeAllocator(member.getDeclaringClass(), member);
135 return make(member.getDeclaringClass(), member);
136 }
137 static DirectMethodHandle makeAllocator(Class<?> instanceClass, MemberName ctor) {
138 assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
139 ctor = ctor.asConstructor();
140 assert(ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
141 MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
142 LambdaForm lform = preparedLambdaForm(ctor);
143 MemberName init = ctor.asSpecial();
144 assert(init.getMethodType().returnType() == void.class);
145 return new Constructor(mtype, lform, ctor, true, init, instanceClass);
146 }
147
148 @Override
149 BoundMethodHandle rebind() {
150 return BoundMethodHandle.makeReinvoker(this);
151 }
152
153 @Override
154 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
155 assert(this.getClass() == DirectMethodHandle.class); // must override in subclasses
156 return new DirectMethodHandle(mt, lf, member, crackable);
157 }
158
159 @Override
160 MethodHandle viewAsType(MethodType newType, boolean strict) {
352 }
353 Class<?> cls = member.getDeclaringClass();
354 if (cls == ValueConversions.class ||
355 cls == MethodHandleImpl.class ||
356 cls == Invokers.class) {
357 // These guys have lots of <clinit> DMH creation but we know
358 // the MHs will not be used until the system is booted.
359 return false;
360 }
361 if (VerifyAccess.isSamePackage(MethodHandle.class, cls) ||
362 VerifyAccess.isSamePackage(ValueConversions.class, cls)) {
363 // It is a system class. It is probably in the process of
364 // being initialized, but we will help it along just to be safe.
365 UNSAFE.ensureClassInitialized(cls);
366 return CDS.needsClassInitBarrier(cls);
367 }
368 return UNSAFE.shouldBeInitialized(cls) || CDS.needsClassInitBarrier(cls);
369 }
370
371 private void ensureInitialized() {
372 if (checkInitialized(member)) {
373 // The coast is clear. Delete the <clinit> barrier.
374 updateForm(new Function<>() {
375 public LambdaForm apply(LambdaForm oldForm) {
376 return (member.isField() ? preparedFieldLambdaForm(member)
377 : preparedLambdaForm(member));
378 }
379 });
380 }
381 }
382 private static boolean checkInitialized(MemberName member) {
383 Class<?> defc = member.getDeclaringClass();
384 UNSAFE.ensureClassInitialized(defc);
385 // Once we get here either defc was fully initialized by another thread, or
386 // defc was already being initialized by the current thread. In the latter case
387 // the barrier must remain. We can detect this simply by checking if initialization
388 // is still needed.
389 return !UNSAFE.shouldBeInitialized(defc);
390 }
391
392 /*non-public*/
393 static void ensureInitialized(Object mh) {
394 ((DirectMethodHandle)mh).ensureInitialized();
395 }
396
397 /** This subclass represents invokespecial instructions. */
398 static final class Special extends DirectMethodHandle {
399 private final Class<?> caller;
400 private Special(MethodType mtype, LambdaForm form, MemberName member, boolean crackable, Class<?> caller) {
401 super(mtype, form, member, crackable);
402 this.caller = caller;
403 }
404 @Override
405 boolean isInvokeSpecial() {
406 return true;
407 }
408 @Override
409 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
490 return new Constructor(newType, form, member, false, initMethod, instanceClass);
491 }
492 }
493
494 /*non-public*/
495 static Object constructorMethod(Object mh) {
496 Constructor dmh = (Constructor)mh;
497 return dmh.initMethod;
498 }
499
500 /*non-public*/
501 static Object allocateInstance(Object mh) throws InstantiationException {
502 Constructor dmh = (Constructor)mh;
503 return UNSAFE.allocateInstance(dmh.instanceClass);
504 }
505
506 /** This subclass handles non-static field references. */
507 static final class Accessor extends DirectMethodHandle {
508 final Class<?> fieldType;
509 final int fieldOffset;
510 private Accessor(MethodType mtype, LambdaForm form, MemberName member,
511 boolean crackable, int fieldOffset) {
512 super(mtype, form, member, crackable);
513 this.fieldType = member.getFieldType();
514 this.fieldOffset = fieldOffset;
515 }
516
517 @Override Object checkCast(Object obj) {
518 return fieldType.cast(obj);
519 }
520 @Override
521 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
522 return new Accessor(mt, lf, member, crackable, fieldOffset);
523 }
524 @Override
525 MethodHandle viewAsType(MethodType newType, boolean strict) {
526 assert(viewAsTypeChecks(newType, strict));
527 return new Accessor(newType, form, member, false, fieldOffset);
528 }
529 }
530
531 @ForceInline
532 /*non-public*/
533 static long fieldOffset(Object accessorObj) {
534 // Note: We return a long because that is what Unsafe.getObject likes.
584 }
585
586 @ForceInline
587 /*non-public*/
588 static Object staticBase(Object accessorObj) {
589 return ((StaticAccessor)accessorObj).staticBase;
590 }
591
592 @ForceInline
593 /*non-public*/
594 static long staticOffset(Object accessorObj) {
595 return ((StaticAccessor)accessorObj).staticOffset;
596 }
597
598 @ForceInline
599 /*non-public*/
600 static Object checkCast(Object mh, Object obj) {
601 return ((DirectMethodHandle) mh).checkCast(obj);
602 }
603
604 Object checkCast(Object obj) {
605 return member.getMethodType().returnType().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.
619 static final int
620 FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(),
621 FT_CHECKED_REF = Wrapper.VOID.ordinal(),
622 FT_LIMIT = Wrapper.COUNT;
623 private static int afIndex(byte formOp, boolean isVolatile, int ftypeKind) {
624 return ((formOp * FT_LIMIT * 2)
625 + (isVolatile ? FT_LIMIT : 0)
626 + ftypeKind);
627 }
628 @Stable
629 private static final LambdaForm[] ACCESSOR_FORMS
630 = new LambdaForm[afIndex(AF_LIMIT, false, 0)];
631 static int ftypeKind(Class<?> ftype) {
632 if (ftype.isPrimitive()) {
633 return Wrapper.forPrimitiveType(ftype).ordinal();
634 } else if (ftype.isInterface() || ftype.isAssignableFrom(Object.class)) {
635 // retyping can be done without a cast
636 return FT_UNCHECKED_REF;
637 } else {
638 return FT_CHECKED_REF;
639 }
640 }
641
642 /**
643 * Create a LF which can access the given field.
644 * Cache and share this structure among all fields with
645 * the same basicType and refKind.
646 */
647 private static LambdaForm preparedFieldLambdaForm(MemberName m) {
648 Class<?> ftype = m.getFieldType();
649 boolean isVolatile = m.isVolatile();
650 byte formOp = switch (m.getReferenceKind()) {
651 case REF_getField -> AF_GETFIELD;
652 case REF_putField -> AF_PUTFIELD;
653 case REF_getStatic -> AF_GETSTATIC;
654 case REF_putStatic -> AF_PUTSTATIC;
655 default -> throw new InternalError(m.toString());
656 };
657 if (shouldBeInitialized(m)) {
658 // precompute the barrier-free version:
659 preparedFieldLambdaForm(formOp, isVolatile, ftype);
660 assert((AF_GETSTATIC_INIT - AF_GETSTATIC) ==
661 (AF_PUTSTATIC_INIT - AF_PUTSTATIC));
662 formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
663 }
664 LambdaForm lform = preparedFieldLambdaForm(formOp, isVolatile, ftype);
665 assert(lform.methodType().dropParameterTypes(0, 1)
666 .equals(m.getInvocationType().basicType()))
667 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
668 return lform;
669 }
670 private static LambdaForm preparedFieldLambdaForm(byte formOp, boolean isVolatile, Class<?> ftype) {
671 int ftypeKind = ftypeKind(ftype);
672 int afIndex = afIndex(formOp, isVolatile, ftypeKind);
673 LambdaForm lform = ACCESSOR_FORMS[afIndex];
674 if (lform != null) return lform;
675 lform = makePreparedFieldLambdaForm(formOp, isVolatile, ftypeKind);
676 ACCESSOR_FORMS[afIndex] = lform; // don't bother with a CAS
677 return lform;
678 }
679
680 private static final @Stable Wrapper[] ALL_WRAPPERS = Wrapper.values();
681
682 // Names in kind may overload but differ from their basic type
683 private static Kind getFieldKind(boolean isVolatile, boolean needsInit, boolean needsCast, Wrapper wrapper) {
684 if (isVolatile) {
685 if (needsInit) {
686 return switch (wrapper) {
687 case BYTE -> VOLATILE_FIELD_ACCESS_INIT_B;
688 case CHAR -> VOLATILE_FIELD_ACCESS_INIT_C;
689 case SHORT -> VOLATILE_FIELD_ACCESS_INIT_S;
690 case BOOLEAN -> VOLATILE_FIELD_ACCESS_INIT_Z;
691 default -> needsCast ? VOLATILE_FIELD_ACCESS_INIT_CAST : VOLATILE_FIELD_ACCESS_INIT;
692 };
693 } else {
694 return switch (wrapper) {
695 case BYTE -> VOLATILE_FIELD_ACCESS_B;
696 case CHAR -> VOLATILE_FIELD_ACCESS_C;
697 case SHORT -> VOLATILE_FIELD_ACCESS_S;
698 case BOOLEAN -> VOLATILE_FIELD_ACCESS_Z;
699 default -> needsCast ? VOLATILE_FIELD_ACCESS_CAST : VOLATILE_FIELD_ACCESS;
700 };
701 }
702 } else {
703 if (needsInit) {
704 return switch (wrapper) {
705 case BYTE -> FIELD_ACCESS_INIT_B;
706 case CHAR -> FIELD_ACCESS_INIT_C;
707 case SHORT -> FIELD_ACCESS_INIT_S;
708 case BOOLEAN -> FIELD_ACCESS_INIT_Z;
709 default -> needsCast ? FIELD_ACCESS_INIT_CAST : FIELD_ACCESS_INIT;
710 };
711 } else {
712 return switch (wrapper) {
713 case BYTE -> FIELD_ACCESS_B;
714 case CHAR -> FIELD_ACCESS_C;
715 case SHORT -> FIELD_ACCESS_S;
716 case BOOLEAN -> FIELD_ACCESS_Z;
717 default -> needsCast ? FIELD_ACCESS_CAST : FIELD_ACCESS;
718 };
719 }
720 }
721 }
722
723 private static String unsafeMethodName(boolean isGetter, boolean isVolatile, Wrapper wrapper) {
724 var name = switch (wrapper) {
725 case BOOLEAN -> "Boolean";
726 case BYTE -> "Byte";
727 case CHAR -> "Char";
728 case SHORT -> "Short";
729 case INT -> "Int";
730 case FLOAT -> "Float";
731 case LONG -> "Long";
732 case DOUBLE -> "Double";
733 case OBJECT -> "Reference";
734 case VOID -> throw new InternalError();
735 };
736 var sb = new StringBuilder(3 + name.length() + (isVolatile ? 8 : 0))
737 .append(isGetter ? "get" : "put")
738 .append(name);
739 if (isVolatile) {
740 sb.append("Volatile");
741 }
742 return sb.toString();
743 }
744
745 static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
746 boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1);
747 boolean isStatic = (formOp >= AF_GETSTATIC);
748 boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
749 boolean needsCast = (ftypeKind == FT_CHECKED_REF);
750 Wrapper fw = (needsCast ? Wrapper.OBJECT : ALL_WRAPPERS[ftypeKind]);
751 Class<?> ft = fw.primitiveType();
752 assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
753
754 // getObject, putIntVolatile, etc.
755 String unsafeMethodName = unsafeMethodName(isGetter, isVolatile, fw);
756 // isGetter and isStatic is reflected in field type; basic type clash for subwords
757 Kind kind = getFieldKind(isVolatile, needsInit, needsCast, fw);
758
759 MethodType linkerType;
760 if (isGetter)
761 linkerType = MethodType.methodType(ft, Object.class, long.class);
762 else
763 linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
764 MemberName linker = new MemberName(Unsafe.class, unsafeMethodName, linkerType, REF_invokeVirtual);
765 try {
766 linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, LM_TRUSTED,
767 NoSuchMethodException.class);
768 } catch (ReflectiveOperationException ex) {
769 throw newInternalError(ex);
770 }
771
772 // What is the external type of the lambda form?
773 MethodType mtype;
774 if (isGetter)
775 mtype = MethodType.methodType(ft);
776 else
777 mtype = MethodType.methodType(void.class, ft);
778 mtype = mtype.basicType(); // erase short to int, etc.
779 if (!isStatic)
780 mtype = mtype.insertParameterTypes(0, Object.class);
781 final int DMH_THIS = 0;
782 final int ARG_BASE = 1;
783 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
784 // if this is for non-static access, the base pointer is stored at this index:
785 final int OBJ_BASE = isStatic ? -1 : ARG_BASE;
786 // if this is for write access, the value to be written is stored at this index:
787 final int SET_VALUE = isGetter ? -1 : ARG_LIMIT - 1;
788 int nameCursor = ARG_LIMIT;
789 final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any
790 final int F_OFFSET = nameCursor++; // Either static offset or field offset.
791 final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
792 final int U_HOLDER = nameCursor++; // UNSAFE holder
793 final int INIT_BAR = (needsInit ? nameCursor++ : -1);
794 final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
795 final int LINKER_CALL = nameCursor++;
796 final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
797 final int RESULT = nameCursor-1; // either the call or the cast
798 Name[] names = invokeArguments(nameCursor - ARG_LIMIT, mtype);
799 if (needsInit)
800 names[INIT_BAR] = new Name(getFunction(NF_ensureInitialized), names[DMH_THIS]);
801 if (needsCast && !isGetter)
802 names[PRE_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[SET_VALUE]);
803 Object[] outArgs = new Object[1 + linkerType.parameterCount()];
804 assert(outArgs.length == (isGetter ? 3 : 4));
805 outArgs[0] = names[U_HOLDER] = new Name(getFunction(NF_UNSAFE));
806 if (isStatic) {
807 outArgs[1] = names[F_HOLDER] = new Name(getFunction(NF_staticBase), names[DMH_THIS]);
808 outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_staticOffset), names[DMH_THIS]);
809 } else {
810 outArgs[1] = names[OBJ_CHECK] = new Name(getFunction(NF_checkBase), names[OBJ_BASE]);
811 outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_fieldOffset), names[DMH_THIS]);
812 }
813 if (!isGetter) {
814 outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
815 }
816 for (Object a : outArgs) assert(a != null);
817 names[LINKER_CALL] = new Name(linker, outArgs);
818 if (needsCast && isGetter)
819 names[POST_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[LINKER_CALL]);
820 for (Name n : names) assert(n != null);
821
822 LambdaForm form = LambdaForm.create(ARG_LIMIT, names, RESULT, kind);
823
824 if (LambdaForm.debugNames()) {
825 // add some detail to the lambdaForm debugname,
826 // significant only for debugging
827 StringBuilder nameBuilder = new StringBuilder(unsafeMethodName);
828 if (isStatic) {
829 nameBuilder.append("Static");
830 } else {
831 nameBuilder.append("Field");
832 }
833 if (needsCast) {
834 nameBuilder.append("Cast");
835 }
836 if (needsInit) {
837 nameBuilder.append("Init");
838 }
839 LambdaForm.associateWithDebugName(form, nameBuilder.toString());
840 }
841
842 // NF_UNSAFE uses field form, avoid circular dependency in interpreter
843 form.compileToBytecode();
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
|
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import jdk.internal.misc.CDS;
29 import jdk.internal.misc.Unsafe;
30 import jdk.internal.value.ValueClass;
31 import jdk.internal.vm.annotation.AOTSafeClassInitializer;
32 import jdk.internal.vm.annotation.ForceInline;
33 import jdk.internal.vm.annotation.Stable;
34 import sun.invoke.util.ValueConversions;
35 import sun.invoke.util.VerifyAccess;
36 import sun.invoke.util.Wrapper;
37
38 import java.util.Arrays;
39 import java.util.Objects;
40 import java.util.function.Function;
41
42 import static java.lang.invoke.LambdaForm.*;
43 import static java.lang.invoke.LambdaForm.Kind.*;
44 import static java.lang.invoke.MethodHandleNatives.Constants.*;
45 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
46 import static java.lang.invoke.MethodHandleStatics.newInternalError;
47 import static java.lang.invoke.MethodTypeForm.*;
48
49 /**
50 * The flavor of method handle which implements a constant reference
119 return new StaticAccessor(mtype, lform, member, true, base, offset);
120 } else {
121 long offset = MethodHandleNatives.objectFieldOffset(member);
122 assert(offset == (int)offset);
123 return new Accessor(mtype, lform, member, true, (int)offset);
124 }
125 }
126 }
127 static DirectMethodHandle make(Class<?> refc, MemberName member) {
128 byte refKind = member.getReferenceKind();
129 if (refKind == REF_invokeSpecial)
130 refKind = REF_invokeVirtual;
131 return make(refKind, refc, member, null /* no callerClass context */);
132 }
133 static DirectMethodHandle make(MemberName member) {
134 if (member.isConstructor())
135 return makeAllocator(member.getDeclaringClass(), member);
136 return make(member.getDeclaringClass(), member);
137 }
138 static DirectMethodHandle makeAllocator(Class<?> instanceClass, MemberName ctor) {
139 assert(ctor.isConstructor()) : ctor;
140 ctor = ctor.asConstructor();
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) {
353 }
354 Class<?> cls = member.getDeclaringClass();
355 if (cls == ValueConversions.class ||
356 cls == MethodHandleImpl.class ||
357 cls == Invokers.class) {
358 // These guys have lots of <clinit> DMH creation but we know
359 // the MHs will not be used until the system is booted.
360 return false;
361 }
362 if (VerifyAccess.isSamePackage(MethodHandle.class, cls) ||
363 VerifyAccess.isSamePackage(ValueConversions.class, cls)) {
364 // It is a system class. It is probably in the process of
365 // being initialized, but we will help it along just to be safe.
366 UNSAFE.ensureClassInitialized(cls);
367 return CDS.needsClassInitBarrier(cls);
368 }
369 return UNSAFE.shouldBeInitialized(cls) || CDS.needsClassInitBarrier(cls);
370 }
371
372 private void ensureInitialized() {
373 if (checkInitialized()) {
374 // The coast is clear. Delete the <clinit> barrier.
375 updateForm(new Function<>() {
376 public LambdaForm apply(LambdaForm oldForm) {
377 return (member.isField() ? preparedFieldLambdaForm(member)
378 : preparedLambdaForm(member));
379 }
380 });
381 }
382 }
383 private boolean checkInitialized() {
384 Class<?> defc = member.getDeclaringClass();
385 UNSAFE.ensureClassInitialized(defc);
386 // Once we get here either defc was fully initialized by another thread, or
387 // defc was already being initialized by the current thread. In the latter case
388 // the barrier must remain. We can detect this simply by checking if initialization
389 // is still needed.
390 boolean initializingStill = UNSAFE.shouldBeInitialized(defc);
391 if (initializingStill && member.isStrict()) {
392 // while <clinit> is running, we track access to strict static fields
393 UNSAFE.notifyStrictStaticAccess(defc, staticOffset(this), member.isSetter());
394 }
395 return !initializingStill;
396 }
397
398 /*non-public*/
399 static void ensureInitialized(Object mh) {
400 ((DirectMethodHandle)mh).ensureInitialized();
401 }
402
403 /** This subclass represents invokespecial instructions. */
404 static final class Special extends DirectMethodHandle {
405 private final Class<?> caller;
406 private Special(MethodType mtype, LambdaForm form, MemberName member, boolean crackable, Class<?> caller) {
407 super(mtype, form, member, crackable);
408 this.caller = caller;
409 }
410 @Override
411 boolean isInvokeSpecial() {
412 return true;
413 }
414 @Override
415 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
496 return new Constructor(newType, form, member, false, initMethod, instanceClass);
497 }
498 }
499
500 /*non-public*/
501 static Object constructorMethod(Object mh) {
502 Constructor dmh = (Constructor)mh;
503 return dmh.initMethod;
504 }
505
506 /*non-public*/
507 static Object allocateInstance(Object mh) throws InstantiationException {
508 Constructor dmh = (Constructor)mh;
509 return UNSAFE.allocateInstance(dmh.instanceClass);
510 }
511
512 /** This subclass handles non-static field references. */
513 static final class Accessor extends DirectMethodHandle {
514 final Class<?> fieldType;
515 final int fieldOffset;
516 final int layout;
517 private Accessor(MethodType mtype, LambdaForm form, MemberName member,
518 boolean crackable, int fieldOffset) {
519 super(mtype, form, member, crackable);
520 this.fieldType = member.getFieldType();
521 this.fieldOffset = fieldOffset;
522 this.layout = member.getLayout();
523 }
524
525 @Override Object checkCast(Object obj) {
526 return fieldType.cast(obj);
527 }
528 @Override
529 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
530 return new Accessor(mt, lf, member, crackable, fieldOffset);
531 }
532 @Override
533 MethodHandle viewAsType(MethodType newType, boolean strict) {
534 assert(viewAsTypeChecks(newType, strict));
535 return new Accessor(newType, form, member, false, fieldOffset);
536 }
537 }
538
539 @ForceInline
540 /*non-public*/
541 static long fieldOffset(Object accessorObj) {
542 // Note: We return a long because that is what Unsafe.getObject likes.
592 }
593
594 @ForceInline
595 /*non-public*/
596 static Object staticBase(Object accessorObj) {
597 return ((StaticAccessor)accessorObj).staticBase;
598 }
599
600 @ForceInline
601 /*non-public*/
602 static long staticOffset(Object accessorObj) {
603 return ((StaticAccessor)accessorObj).staticOffset;
604 }
605
606 @ForceInline
607 /*non-public*/
608 static Object checkCast(Object mh, Object obj) {
609 return ((DirectMethodHandle) mh).checkCast(obj);
610 }
611
612 @ForceInline
613 /*non-public*/ static Class<?> fieldType(Object accessorObj) {
614 return ((Accessor) accessorObj).fieldType;
615 }
616
617 @ForceInline
618 static int fieldLayout(Object accessorObj) {
619 return ((Accessor) accessorObj).layout;
620 }
621
622 @ForceInline
623 /*non-public*/ static Class<?> staticFieldType(Object accessorObj) {
624 return ((StaticAccessor) accessorObj).fieldType;
625 }
626
627 Object checkCast(Object obj) {
628 return member.getMethodType().returnType().cast(obj);
629 }
630
631 // Caching machinery for field accessors:
632 static final byte
633 AF_GETFIELD = 0,
634 AF_PUTFIELD = 1,
635 AF_GETSTATIC = 2,
636 AF_PUTSTATIC = 3,
637 AF_GETSTATIC_INIT = 4,
638 AF_PUTSTATIC_INIT = 5,
639 AF_LIMIT = 6;
640 // Enumerate the different field kinds using Wrapper,
641 // with an extra case added for checked references and value field access
642 static final int
643 FT_FIRST_REFERENCE = 8,
644 // Any oop, same sig (Runnable?)
645 FT_UNCHECKED_REF = FT_FIRST_REFERENCE,
646 // Oop with type checks (Number?)
647 FT_CHECKED_REF = FT_FIRST_REFERENCE + 1,
648 // Oop with null checks, (Runnable!)
649 FT_UNCHECKED_NR_REF = FT_FIRST_REFERENCE + 2,
650 // Oop with null and type checks, (Number!)
651 FT_CHECKED_NR_REF = FT_FIRST_REFERENCE + 3,
652 FT_FIRST_FLAT = FT_FIRST_REFERENCE + 4,
653 // nullable flat (must check type), (Integer?)
654 FT_NULLABLE_FLAT = FT_FIRST_FLAT,
655 // Null restricted flat (must check type), (Integer!)
656 FT_NR_FLAT = FT_FIRST_FLAT + 1,
657 FT_LIMIT = FT_FIRST_FLAT + 2;
658
659 static {
660 assert FT_FIRST_REFERENCE == Wrapper.OBJECT.ordinal();
661 }
662
663 private static int afIndex(byte formOp, boolean isVolatile, int ftypeKind) {
664 return ((formOp * FT_LIMIT * 2)
665 + (isVolatile ? FT_LIMIT : 0)
666 + ftypeKind);
667 }
668 @Stable
669 private static final LambdaForm[] ACCESSOR_FORMS
670 = new LambdaForm[afIndex(AF_LIMIT, false, 0)];
671 static int ftypeKind(Class<?> ftype, boolean isFlat, boolean isNullRestricted) {
672 if (ftype.isPrimitive()) {
673 assert !isFlat && !isNullRestricted : ftype;
674 return Wrapper.forPrimitiveType(ftype).ordinal();
675 } else if (ftype.isInterface() || ftype.isAssignableFrom(Object.class)) {
676 assert !isFlat : ftype;
677 // retyping can be done without a cast
678 return isNullRestricted ? FT_UNCHECKED_NR_REF : FT_UNCHECKED_REF;
679 }
680 if (isFlat) {
681 assert ValueClass.isConcreteValueClass(ftype) : ftype;
682 return isNullRestricted ? FT_NR_FLAT : FT_NULLABLE_FLAT;
683 }
684 return isNullRestricted ? FT_CHECKED_NR_REF : FT_CHECKED_REF;
685 }
686
687 /**
688 * Create a LF which can access the given field.
689 * Cache and share this structure among all fields with
690 * the same basicType and refKind.
691 */
692 private static LambdaForm preparedFieldLambdaForm(MemberName m) {
693 Class<?> ftype = m.getFieldType();
694 byte formOp = switch (m.getReferenceKind()) {
695 case REF_getField -> AF_GETFIELD;
696 case REF_putField -> AF_PUTFIELD;
697 case REF_getStatic -> AF_GETSTATIC;
698 case REF_putStatic -> AF_PUTSTATIC;
699 default -> throw new InternalError(m.toString());
700 };
701 if (shouldBeInitialized(m)) {
702 // precompute the barrier-free version:
703 preparedFieldLambdaForm(formOp, m.isVolatile(), m.isFlat(), m.isNullRestricted(), ftype);
704 assert((AF_GETSTATIC_INIT - AF_GETSTATIC) ==
705 (AF_PUTSTATIC_INIT - AF_PUTSTATIC));
706 formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
707 }
708 LambdaForm lform = preparedFieldLambdaForm(formOp, m.isVolatile(), m.isFlat(), m.isNullRestricted(), ftype);
709 assert(lform.methodType().dropParameterTypes(0, 1)
710 .equals(m.getInvocationType().basicType()))
711 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
712 return lform;
713 }
714
715 private static LambdaForm preparedFieldLambdaForm(byte formOp, boolean isVolatile,
716 boolean isFlat, boolean isNullRestricted, Class<?> ftype) {
717 int ftypeKind = ftypeKind(ftype, isFlat, isNullRestricted);
718 return preparedFieldLambdaForm(formOp, isVolatile, ftypeKind);
719 }
720
721 private static LambdaForm preparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
722 int afIndex = afIndex(formOp, isVolatile, ftypeKind);
723 LambdaForm lform = ACCESSOR_FORMS[afIndex];
724 if (lform != null) return lform;
725 lform = makePreparedFieldLambdaForm(formOp, isVolatile, ftypeKind);
726 ACCESSOR_FORMS[afIndex] = lform; // don't bother with a CAS
727 return lform;
728 }
729
730 private static final @Stable Wrapper[] ALL_WRAPPERS = Wrapper.values();
731
732 // Names in kind may overload but differ from their basic type
733 private static Kind getFieldKind(boolean isGetter,
734 boolean isVolatile,
735 boolean needsInit,
736 boolean needsCast,
737 boolean isFlat,
738 boolean isNullRestricted,
739 Wrapper wrapper) {
740 if (!wrapper.isOther()) {
741 // primitives
742 assert !isFlat && !isNullRestricted && !needsCast;
743 return switch (wrapper) {
744 case BYTE -> isVolatile
745 ? (needsInit ? VOLATILE_FIELD_ACCESS_INIT_B : VOLATILE_FIELD_ACCESS_B)
746 : (needsInit ? FIELD_ACCESS_INIT_B : FIELD_ACCESS_B);
747 case CHAR -> isVolatile
748 ? (needsInit ? VOLATILE_FIELD_ACCESS_INIT_C : VOLATILE_FIELD_ACCESS_C)
749 : (needsInit ? FIELD_ACCESS_INIT_C : FIELD_ACCESS_C);
750 case SHORT -> isVolatile
751 ? (needsInit ? VOLATILE_FIELD_ACCESS_INIT_S : VOLATILE_FIELD_ACCESS_S)
752 : (needsInit ? FIELD_ACCESS_INIT_S : FIELD_ACCESS_S);
753 case BOOLEAN -> isVolatile
754 ? (needsInit ? VOLATILE_FIELD_ACCESS_INIT_Z : VOLATILE_FIELD_ACCESS_Z)
755 : (needsInit ? FIELD_ACCESS_INIT_Z : FIELD_ACCESS_Z);
756 // basic types
757 default -> isVolatile
758 ? (needsInit ? VOLATILE_FIELD_ACCESS_INIT : VOLATILE_FIELD_ACCESS)
759 : (needsInit ? FIELD_ACCESS_INIT : FIELD_ACCESS);
760 };
761 }
762
763 assert !(isGetter && isNullRestricted);
764 if (isVolatile) {
765 if (isFlat) {
766 assert !needsInit && needsCast;
767 return isNullRestricted ? VOLATILE_PUT_NULL_RESTRICTED_FLAT_VALUE : VOLATILE_FIELD_ACCESS_FLAT;
768 } else if (needsCast) {
769 if (needsInit) {
770 return isNullRestricted ? VOLATILE_PUT_NULL_RESTRICTED_REFERENCE_CAST_INIT : VOLATILE_FIELD_ACCESS_INIT_CAST;
771 } else {
772 return isNullRestricted ? VOLATILE_PUT_NULL_RESTRICTED_REFERENCE_CAST : VOLATILE_FIELD_ACCESS_CAST;
773 }
774 } else {
775 if (needsInit) {
776 return isNullRestricted ? VOLATILE_PUT_NULL_RESTRICTED_REFERENCE_INIT : VOLATILE_FIELD_ACCESS_INIT;
777 } else {
778 return isNullRestricted ? VOLATILE_PUT_NULL_RESTRICTED_REFERENCE : VOLATILE_FIELD_ACCESS;
779 }
780 }
781 } else {
782 if (isFlat) {
783 assert !needsInit && needsCast;
784 return isNullRestricted ? PUT_NULL_RESTRICTED_FLAT_VALUE : FIELD_ACCESS_FLAT;
785 } else if (needsCast) {
786 if (needsInit) {
787 return isNullRestricted ? PUT_NULL_RESTRICTED_REFERENCE_CAST_INIT : FIELD_ACCESS_INIT_CAST;
788 } else {
789 return isNullRestricted ? PUT_NULL_RESTRICTED_REFERENCE_CAST : FIELD_ACCESS_CAST;
790 }
791 } else {
792 if (needsInit) {
793 return isNullRestricted ? PUT_NULL_RESTRICTED_REFERENCE_INIT : FIELD_ACCESS_INIT;
794 } else {
795 return isNullRestricted ? PUT_NULL_RESTRICTED_REFERENCE : FIELD_ACCESS;
796 }
797 }
798 }
799 }
800
801 private static String unsafeMethodName(boolean isGetter,
802 boolean isVolatile,
803 Wrapper wrapper) {
804 var name = switch (wrapper) {
805 case BOOLEAN -> "Boolean";
806 case BYTE -> "Byte";
807 case CHAR -> "Char";
808 case SHORT -> "Short";
809 case INT -> "Int";
810 case FLOAT -> "Float";
811 case LONG -> "Long";
812 case DOUBLE -> "Double";
813 case OBJECT -> "Reference";
814 case VOID -> "FlatValue";
815 };
816 var sb = new StringBuilder(3 + name.length() + (isVolatile ? 8 : 0))
817 .append(isGetter ? "get" : "put")
818 .append(name);
819 if (isVolatile) {
820 sb.append("Volatile");
821 }
822 return sb.toString();
823 }
824
825 static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
826 boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1);
827 boolean isStatic = (formOp >= AF_GETSTATIC);
828 boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
829 boolean isFlat = (ftypeKind >= FT_FIRST_FLAT);
830 boolean isNullRestricted = (ftypeKind == FT_NR_FLAT || ftypeKind == FT_CHECKED_NR_REF || ftypeKind == FT_UNCHECKED_NR_REF);
831 boolean needsCast = (isFlat || ftypeKind == FT_CHECKED_REF || ftypeKind == FT_CHECKED_NR_REF);
832
833 if (isGetter && isNullRestricted) {
834 int newKind = switch (ftypeKind) {
835 case FT_NR_FLAT -> FT_NULLABLE_FLAT;
836 case FT_CHECKED_NR_REF -> FT_CHECKED_REF;
837 case FT_UNCHECKED_NR_REF -> FT_UNCHECKED_REF;
838 default -> throw new InternalError();
839 };
840 return preparedFieldLambdaForm(formOp, isVolatile, newKind);
841 }
842
843 if (isFlat && isStatic)
844 throw new InternalError("Static flat not supported yet");
845
846 // primitives, reference, and void for flat
847 Wrapper fw = ftypeKind < FT_FIRST_REFERENCE ? ALL_WRAPPERS[ftypeKind] :
848 isFlat ? Wrapper.VOID : Wrapper.OBJECT;
849
850 // getObject, putIntVolatile, etc.
851 String unsafeMethodName = unsafeMethodName(isGetter, isVolatile, fw);
852 // isGetter and isStatic is reflected in field type;
853 // flat, NR distinguished
854 // basic type clash for subwords
855 Kind kind = getFieldKind(isGetter, isVolatile, needsInit, needsCast, isFlat, isNullRestricted, fw);
856
857 Class<?> ft = ftypeKind < FT_FIRST_REFERENCE ? fw.primitiveType() : Object.class;
858 MethodType linkerType;
859 if (isGetter) {
860 linkerType = isFlat
861 ? MethodType.methodType(ft, Object.class, long.class, int.class, Class.class)
862 : MethodType.methodType(ft, Object.class, long.class);
863 } else {
864 linkerType = isFlat
865 ? MethodType.methodType(void.class, Object.class, long.class, int.class, Class.class, ft)
866 : MethodType.methodType(void.class, Object.class, long.class, ft);
867 }
868 MemberName linker = new MemberName(Unsafe.class, unsafeMethodName, linkerType, REF_invokeVirtual);
869 try {
870 linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, LM_TRUSTED,
871 NoSuchMethodException.class);
872 } catch (ReflectiveOperationException ex) {
873 throw newInternalError(ex);
874 }
875
876 // What is the external type of the lambda form?
877 MethodType mtype;
878 if (isGetter)
879 mtype = MethodType.methodType(ft);
880 else
881 mtype = MethodType.methodType(void.class, ft);
882 mtype = mtype.basicType(); // erase short to int, etc.
883 if (!isStatic)
884 mtype = mtype.insertParameterTypes(0, Object.class);
885 final int DMH_THIS = 0;
886 final int ARG_BASE = 1;
887 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
888 // if this is for non-static access, the base pointer is stored at this index:
889 final int OBJ_BASE = isStatic ? -1 : ARG_BASE;
890 // if this is for write access, the value to be written is stored at this index:
891 final int SET_VALUE = isGetter ? -1 : ARG_LIMIT - 1;
892 int nameCursor = ARG_LIMIT;
893 final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any
894 final int F_OFFSET = nameCursor++; // Either static offset or field offset.
895 final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
896 final int U_HOLDER = nameCursor++; // UNSAFE holder
897 final int INIT_BAR = (needsInit ? nameCursor++ : -1);
898 final int LAYOUT = (isFlat ? nameCursor++ : -1); // field must be instance
899 final int VALUE_TYPE = (isFlat ? nameCursor++ : -1);
900 final int NULL_CHECK = (isNullRestricted && !isGetter ? nameCursor++ : -1);
901 final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
902 final int LINKER_CALL = nameCursor++;
903 final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
904 final int RESULT = nameCursor-1; // either the call, or the cast
905 Name[] names = invokeArguments(nameCursor - ARG_LIMIT, mtype);
906 if (needsInit)
907 names[INIT_BAR] = new Name(getFunction(NF_ensureInitialized), names[DMH_THIS]);
908 if (!isGetter) {
909 if (isNullRestricted)
910 names[NULL_CHECK] = new Name(getFunction(NF_nullCheck), names[SET_VALUE]);
911 if (needsCast)
912 names[PRE_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[SET_VALUE]);
913 }
914 Object[] outArgs = new Object[1 + linkerType.parameterCount()];
915 assert (outArgs.length == (isGetter ? 3 : 4) + (isFlat ? 2 : 0));
916 outArgs[0] = names[U_HOLDER] = new Name(getFunction(NF_UNSAFE));
917 if (isStatic) {
918 outArgs[1] = names[F_HOLDER] = new Name(getFunction(NF_staticBase), names[DMH_THIS]);
919 outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_staticOffset), names[DMH_THIS]);
920 } else {
921 outArgs[1] = names[OBJ_CHECK] = new Name(getFunction(NF_checkBase), names[OBJ_BASE]);
922 outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_fieldOffset), names[DMH_THIS]);
923 }
924 int x = 3;
925 if (isFlat) {
926 outArgs[x++] = names[LAYOUT] = new Name(getFunction(NF_fieldLayout), names[DMH_THIS]);
927 outArgs[x++] = names[VALUE_TYPE] = isStatic ? new Name(getFunction(NF_staticFieldType), names[DMH_THIS])
928 : new Name(getFunction(NF_fieldType), names[DMH_THIS]);
929 }
930 if (!isGetter) {
931 outArgs[x] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
932 }
933 for (Object a : outArgs) assert(a != null);
934 names[LINKER_CALL] = new Name(linker, outArgs);
935 if (needsCast && isGetter)
936 names[POST_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[LINKER_CALL]);
937 for (Name n : names) assert(n != null);
938
939 LambdaForm form = LambdaForm.create(ARG_LIMIT, names, RESULT, kind);
940
941 if (LambdaForm.debugNames()) {
942 // add some detail to the lambdaForm debugname,
943 // significant only for debugging
944 StringBuilder nameBuilder = new StringBuilder(unsafeMethodName);
945 if (isStatic) {
946 nameBuilder.append("Static");
947 } else {
948 nameBuilder.append("Field");
949 }
950 if (isNullRestricted) {
951 nameBuilder.append("NullRestricted");
952 }
953 if (needsCast) {
954 nameBuilder.append("Cast");
955 }
956 if (needsInit) {
957 nameBuilder.append("Init");
958 }
959 LambdaForm.associateWithDebugName(form, nameBuilder.toString());
960 }
961
962 // NF_UNSAFE uses field form, avoid circular dependency in interpreter
963 form.compileToBytecode();
964 return form;
965 }
966
967 /**
968 * Pre-initialized NamedFunctions for bootstrapping purposes.
969 */
970 static final byte NF_internalMemberName = 0,
971 NF_internalMemberNameEnsureInit = 1,
972 NF_ensureInitialized = 2,
973 NF_fieldOffset = 3,
974 NF_checkBase = 4,
975 NF_staticBase = 5,
976 NF_staticOffset = 6,
977 NF_checkCast = 7,
978 NF_allocateInstance = 8,
979 NF_constructorMethod = 9,
980 NF_UNSAFE = 10,
981 NF_checkReceiver = 11,
982 NF_fieldType = 12,
983 NF_staticFieldType = 13,
984 NF_fieldLayout = 14,
985 NF_nullCheck = 15,
986 NF_LIMIT = 16;
987
988 private static final @Stable NamedFunction[] NFS = new NamedFunction[NF_LIMIT];
989
990 private static NamedFunction getFunction(byte func) {
991 NamedFunction nf = NFS[func];
992 if (nf != null) {
993 return nf;
994 }
995 // Each nf must be statically invocable or we get tied up in our bootstraps.
996 nf = NFS[func] = createFunction(func);
997 assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf));
998 return nf;
999 }
1000
1001 private static final MethodType CLS_OBJ_TYPE = MethodType.methodType(Class.class, Object.class);
1002 private static final MethodType INT_OBJ_TYPE = MethodType.methodType(int.class, Object.class);
1003
1004 private static final MethodType OBJ_OBJ_TYPE = MethodType.methodType(Object.class, Object.class);
1005
1006 private static final MethodType LONG_OBJ_TYPE = MethodType.methodType(long.class, Object.class);
1007
1008 private static NamedFunction createFunction(byte func) {
1009 try {
1010 switch (func) {
1011 case NF_internalMemberName:
1012 return getNamedFunction("internalMemberName", OBJ_OBJ_TYPE);
1013 case NF_internalMemberNameEnsureInit:
1014 return getNamedFunction("internalMemberNameEnsureInit", OBJ_OBJ_TYPE);
1015 case NF_ensureInitialized:
1016 return getNamedFunction("ensureInitialized", MethodType.methodType(void.class, Object.class));
1017 case NF_fieldOffset:
1018 return getNamedFunction("fieldOffset", LONG_OBJ_TYPE);
1019 case NF_checkBase:
1020 return getNamedFunction("checkBase", OBJ_OBJ_TYPE);
1021 case NF_staticBase:
1022 return getNamedFunction("staticBase", OBJ_OBJ_TYPE);
1023 case NF_staticOffset:
1024 return getNamedFunction("staticOffset", LONG_OBJ_TYPE);
1025 case NF_checkCast:
1026 return getNamedFunction("checkCast", MethodType.methodType(Object.class, Object.class, Object.class));
1027 case NF_allocateInstance:
1028 return getNamedFunction("allocateInstance", OBJ_OBJ_TYPE);
1029 case NF_constructorMethod:
1030 return getNamedFunction("constructorMethod", OBJ_OBJ_TYPE);
1031 case NF_UNSAFE:
1032 MemberName member = new MemberName(MethodHandleStatics.class, "UNSAFE", Unsafe.class, REF_getStatic);
1033 return new NamedFunction(
1034 MemberName.getFactory().resolveOrFail(REF_getStatic, member,
1035 DirectMethodHandle.class, LM_TRUSTED,
1036 NoSuchFieldException.class));
1037 case NF_checkReceiver:
1038 member = new MemberName(DirectMethodHandle.class, "checkReceiver", OBJ_OBJ_TYPE, REF_invokeVirtual);
1039 return new NamedFunction(
1040 MemberName.getFactory().resolveOrFail(REF_invokeVirtual, member,
1041 DirectMethodHandle.class, LM_TRUSTED,
1042 NoSuchMethodException.class));
1043 case NF_fieldType:
1044 return getNamedFunction("fieldType", CLS_OBJ_TYPE);
1045 case NF_staticFieldType:
1046 return getNamedFunction("staticFieldType", CLS_OBJ_TYPE);
1047 case NF_nullCheck:
1048 return getNamedFunction("nullCheck", OBJ_OBJ_TYPE);
1049 case NF_fieldLayout:
1050 return getNamedFunction("fieldLayout", INT_OBJ_TYPE);
1051 default:
1052 throw newInternalError("Unknown function: " + func);
1053 }
1054 } catch (ReflectiveOperationException ex) {
1055 throw newInternalError(ex);
1056 }
1057 }
1058
1059 private static NamedFunction getNamedFunction(String name, MethodType type)
1060 throws ReflectiveOperationException
1061 {
1062 MemberName member = new MemberName(DirectMethodHandle.class, name, type, REF_invokeStatic);
1063 return new NamedFunction(
1064 MemberName.getFactory().resolveOrFail(REF_invokeStatic, member,
1065 DirectMethodHandle.class, LM_TRUSTED,
1066 NoSuchMethodException.class));
1067 }
1068
1069 static {
1070 // The Holder class will contain pre-generated DirectMethodHandles resolved
|