116 return new StaticAccessor(mtype, lform, member, true, base, offset);
117 } else {
118 long offset = MethodHandleNatives.objectFieldOffset(member);
119 assert(offset == (int)offset);
120 return new Accessor(mtype, lform, member, true, (int)offset);
121 }
122 }
123 }
124 static DirectMethodHandle make(Class<?> refc, MemberName member) {
125 byte refKind = member.getReferenceKind();
126 if (refKind == REF_invokeSpecial)
127 refKind = REF_invokeVirtual;
128 return make(refKind, refc, member, null /* no callerClass context */);
129 }
130 static DirectMethodHandle make(MemberName member) {
131 if (member.isConstructor())
132 return makeAllocator(member.getDeclaringClass(), member);
133 return make(member.getDeclaringClass(), member);
134 }
135 static DirectMethodHandle makeAllocator(Class<?> instanceClass, MemberName ctor) {
136 assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
137 ctor = ctor.asConstructor();
138 assert(ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
139 MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
140 LambdaForm lform = preparedLambdaForm(ctor);
141 MemberName init = ctor.asSpecial();
142 assert(init.getMethodType().returnType() == void.class);
143 return new Constructor(mtype, lform, ctor, true, init, instanceClass);
144 }
145
146 @Override
147 BoundMethodHandle rebind() {
148 return BoundMethodHandle.makeReinvoker(this);
149 }
150
151 @Override
152 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
153 assert(this.getClass() == DirectMethodHandle.class); // must override in subclasses
154 return new DirectMethodHandle(mt, lf, member, crackable);
155 }
156
157 @Override
158 MethodHandle viewAsType(MethodType newType, boolean strict) {
357 }
358 Class<?> cls = member.getDeclaringClass();
359 if (cls == ValueConversions.class ||
360 cls == MethodHandleImpl.class ||
361 cls == Invokers.class) {
362 // These guys have lots of <clinit> DMH creation but we know
363 // the MHs will not be used until the system is booted.
364 return false;
365 }
366 if (VerifyAccess.isSamePackage(MethodHandle.class, cls) ||
367 VerifyAccess.isSamePackage(ValueConversions.class, cls)) {
368 // It is a system class. It is probably in the process of
369 // being initialized, but we will help it along just to be safe.
370 UNSAFE.ensureClassInitialized(cls);
371 return CDS.needsClassInitBarrier(cls);
372 }
373 return UNSAFE.shouldBeInitialized(cls) || CDS.needsClassInitBarrier(cls);
374 }
375
376 private void ensureInitialized() {
377 if (checkInitialized(member)) {
378 // The coast is clear. Delete the <clinit> barrier.
379 updateForm(new Function<>() {
380 public LambdaForm apply(LambdaForm oldForm) {
381 return (member.isField() ? preparedFieldLambdaForm(member)
382 : preparedLambdaForm(member));
383 }
384 });
385 }
386 }
387 private static boolean checkInitialized(MemberName member) {
388 Class<?> defc = member.getDeclaringClass();
389 UNSAFE.ensureClassInitialized(defc);
390 // Once we get here either defc was fully initialized by another thread, or
391 // defc was already being initialized by the current thread. In the latter case
392 // the barrier must remain. We can detect this simply by checking if initialization
393 // is still needed.
394 return !UNSAFE.shouldBeInitialized(defc);
395 }
396
397 /*non-public*/
398 static void ensureInitialized(Object mh) {
399 ((DirectMethodHandle)mh).ensureInitialized();
400 }
401
402 /** This subclass represents invokespecial instructions. */
403 static final class Special extends DirectMethodHandle {
404 private final Class<?> caller;
405 private Special(MethodType mtype, LambdaForm form, MemberName member, boolean crackable, Class<?> caller) {
406 super(mtype, form, member, crackable);
407 this.caller = caller;
408 }
409 @Override
410 boolean isInvokeSpecial() {
411 return true;
412 }
413 @Override
414 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
494 return new Constructor(newType, form, member, false, initMethod, instanceClass);
495 }
496 }
497
498 /*non-public*/
499 static Object constructorMethod(Object mh) {
500 Constructor dmh = (Constructor)mh;
501 return dmh.initMethod;
502 }
503
504 /*non-public*/
505 static Object allocateInstance(Object mh) throws InstantiationException {
506 Constructor dmh = (Constructor)mh;
507 return UNSAFE.allocateInstance(dmh.instanceClass);
508 }
509
510 /** This subclass handles non-static field references. */
511 static final class Accessor extends DirectMethodHandle {
512 final Class<?> fieldType;
513 final int fieldOffset;
514 private Accessor(MethodType mtype, LambdaForm form, MemberName member,
515 boolean crackable, int fieldOffset) {
516 super(mtype, form, member, crackable);
517 this.fieldType = member.getFieldType();
518 this.fieldOffset = fieldOffset;
519 }
520
521 @Override Object checkCast(Object obj) {
522 return fieldType.cast(obj);
523 }
524 @Override
525 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
526 return new Accessor(mt, lf, member, crackable, fieldOffset);
527 }
528 @Override
529 MethodHandle viewAsType(MethodType newType, boolean strict) {
530 assert(viewAsTypeChecks(newType, strict));
531 return new Accessor(newType, form, member, false, fieldOffset);
532 }
533 }
534
535 @ForceInline
536 /*non-public*/
537 static long fieldOffset(Object accessorObj) {
538 // Note: We return a long because that is what Unsafe.getObject likes.
588 }
589
590 @ForceInline
591 /*non-public*/
592 static Object staticBase(Object accessorObj) {
593 return ((StaticAccessor)accessorObj).staticBase;
594 }
595
596 @ForceInline
597 /*non-public*/
598 static long staticOffset(Object accessorObj) {
599 return ((StaticAccessor)accessorObj).staticOffset;
600 }
601
602 @ForceInline
603 /*non-public*/
604 static Object checkCast(Object mh, Object obj) {
605 return ((DirectMethodHandle) mh).checkCast(obj);
606 }
607
608 Object checkCast(Object obj) {
609 return member.getMethodType().returnType().cast(obj);
610 }
611
612 // Caching machinery for field accessors:
613 static final byte
614 AF_GETFIELD = 0,
615 AF_PUTFIELD = 1,
616 AF_GETSTATIC = 2,
617 AF_PUTSTATIC = 3,
618 AF_GETSTATIC_INIT = 4,
619 AF_PUTSTATIC_INIT = 5,
620 AF_LIMIT = 6;
621 // Enumerate the different field kinds using Wrapper,
622 // with an extra case added for checked references.
623 static final int
624 FT_LAST_WRAPPER = Wrapper.COUNT-1,
625 FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(),
626 FT_CHECKED_REF = FT_LAST_WRAPPER+1,
627 FT_LIMIT = FT_LAST_WRAPPER+2;
628 private static int afIndex(byte formOp, boolean isVolatile, int ftypeKind) {
629 return ((formOp * FT_LIMIT * 2)
630 + (isVolatile ? FT_LIMIT : 0)
631 + ftypeKind);
632 }
633 @Stable
634 private static final LambdaForm[] ACCESSOR_FORMS
635 = new LambdaForm[afIndex(AF_LIMIT, false, 0)];
636 static int ftypeKind(Class<?> ftype) {
637 if (ftype.isPrimitive()) {
638 return Wrapper.forPrimitiveType(ftype).ordinal();
639 } else if (ftype.isInterface() || ftype.isAssignableFrom(Object.class)) {
640 // retyping can be done without a cast
641 return FT_UNCHECKED_REF;
642 } else {
643 return FT_CHECKED_REF;
644 }
645 }
646
647 /**
648 * Create a LF which can access the given field.
649 * Cache and share this structure among all fields with
650 * the same basicType and refKind.
651 */
652 private static LambdaForm preparedFieldLambdaForm(MemberName m) {
653 Class<?> ftype = m.getFieldType();
654 boolean isVolatile = m.isVolatile();
655 byte formOp = switch (m.getReferenceKind()) {
656 case REF_getField -> AF_GETFIELD;
657 case REF_putField -> AF_PUTFIELD;
658 case REF_getStatic -> AF_GETSTATIC;
659 case REF_putStatic -> AF_PUTSTATIC;
660 default -> throw new InternalError(m.toString());
661 };
662 if (shouldBeInitialized(m)) {
663 // precompute the barrier-free version:
664 preparedFieldLambdaForm(formOp, isVolatile, ftype);
665 assert((AF_GETSTATIC_INIT - AF_GETSTATIC) ==
666 (AF_PUTSTATIC_INIT - AF_PUTSTATIC));
667 formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
668 }
669 LambdaForm lform = preparedFieldLambdaForm(formOp, isVolatile, ftype);
670 maybeCompile(lform, m);
671 assert(lform.methodType().dropParameterTypes(0, 1)
672 .equals(m.getInvocationType().basicType()))
673 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
674 return lform;
675 }
676 private static LambdaForm preparedFieldLambdaForm(byte formOp, boolean isVolatile, Class<?> ftype) {
677 int ftypeKind = ftypeKind(ftype);
678 int afIndex = afIndex(formOp, isVolatile, ftypeKind);
679 LambdaForm lform = ACCESSOR_FORMS[afIndex];
680 if (lform != null) return lform;
681 lform = makePreparedFieldLambdaForm(formOp, isVolatile, ftypeKind);
682 ACCESSOR_FORMS[afIndex] = lform; // don't bother with a CAS
683 return lform;
684 }
685
686 private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
687
688 private static Kind getFieldKind(boolean isGetter, boolean isVolatile, Wrapper wrapper) {
689 if (isGetter) {
690 if (isVolatile) {
691 switch (wrapper) {
692 case BOOLEAN: return GET_BOOLEAN_VOLATILE;
693 case BYTE: return GET_BYTE_VOLATILE;
694 case SHORT: return GET_SHORT_VOLATILE;
695 case CHAR: return GET_CHAR_VOLATILE;
696 case INT: return GET_INT_VOLATILE;
697 case LONG: return GET_LONG_VOLATILE;
698 case FLOAT: return GET_FLOAT_VOLATILE;
699 case DOUBLE: return GET_DOUBLE_VOLATILE;
700 case OBJECT: return GET_REFERENCE_VOLATILE;
701 }
702 } else {
703 switch (wrapper) {
704 case BOOLEAN: return GET_BOOLEAN;
705 case BYTE: return GET_BYTE;
706 case SHORT: return GET_SHORT;
707 case CHAR: return GET_CHAR;
708 case INT: return GET_INT;
709 case LONG: return GET_LONG;
710 case FLOAT: return GET_FLOAT;
711 case DOUBLE: return GET_DOUBLE;
712 case OBJECT: return GET_REFERENCE;
713 }
714 }
715 } else {
716 if (isVolatile) {
717 switch (wrapper) {
718 case BOOLEAN: return PUT_BOOLEAN_VOLATILE;
719 case BYTE: return PUT_BYTE_VOLATILE;
720 case SHORT: return PUT_SHORT_VOLATILE;
721 case CHAR: return PUT_CHAR_VOLATILE;
722 case INT: return PUT_INT_VOLATILE;
723 case LONG: return PUT_LONG_VOLATILE;
724 case FLOAT: return PUT_FLOAT_VOLATILE;
725 case DOUBLE: return PUT_DOUBLE_VOLATILE;
726 case OBJECT: return PUT_REFERENCE_VOLATILE;
727 }
728 } else {
729 switch (wrapper) {
730 case BOOLEAN: return PUT_BOOLEAN;
731 case BYTE: return PUT_BYTE;
732 case SHORT: return PUT_SHORT;
733 case CHAR: return PUT_CHAR;
734 case INT: return PUT_INT;
735 case LONG: return PUT_LONG;
736 case FLOAT: return PUT_FLOAT;
737 case DOUBLE: return PUT_DOUBLE;
738 case OBJECT: return PUT_REFERENCE;
739 }
740 }
741 }
742 throw new AssertionError("Invalid arguments");
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 Kind kind = getFieldKind(isGetter, isVolatile, fw);
756
757 MethodType linkerType;
758 if (isGetter)
759 linkerType = MethodType.methodType(ft, Object.class, long.class);
760 else
761 linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
762 MemberName linker = new MemberName(Unsafe.class, kind.methodName, linkerType, REF_invokeVirtual);
763 try {
764 linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, LM_TRUSTED,
765 NoSuchMethodException.class);
766 } catch (ReflectiveOperationException ex) {
767 throw newInternalError(ex);
768 }
769
770 // What is the external type of the lambda form?
771 MethodType mtype;
772 if (isGetter)
773 mtype = MethodType.methodType(ft);
774 else
775 mtype = MethodType.methodType(void.class, ft);
776 mtype = mtype.basicType(); // erase short to int, etc.
777 if (!isStatic)
778 mtype = mtype.insertParameterTypes(0, Object.class);
779 final int DMH_THIS = 0;
780 final int ARG_BASE = 1;
781 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
782 // if this is for non-static access, the base pointer is stored at this index:
783 final int OBJ_BASE = isStatic ? -1 : ARG_BASE;
784 // if this is for write access, the value to be written is stored at this index:
785 final int SET_VALUE = isGetter ? -1 : ARG_LIMIT - 1;
786 int nameCursor = ARG_LIMIT;
787 final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any
788 final int F_OFFSET = nameCursor++; // Either static offset or field offset.
789 final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
790 final int U_HOLDER = nameCursor++; // UNSAFE holder
791 final int INIT_BAR = (needsInit ? nameCursor++ : -1);
792 final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
793 final int LINKER_CALL = nameCursor++;
794 final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
795 final int RESULT = nameCursor-1; // either the call or the cast
796 Name[] names = invokeArguments(nameCursor - ARG_LIMIT, mtype);
797 if (needsInit)
798 names[INIT_BAR] = new Name(getFunction(NF_ensureInitialized), names[DMH_THIS]);
799 if (needsCast && !isGetter)
800 names[PRE_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[SET_VALUE]);
801 Object[] outArgs = new Object[1 + linkerType.parameterCount()];
802 assert(outArgs.length == (isGetter ? 3 : 4));
803 outArgs[0] = names[U_HOLDER] = new Name(getFunction(NF_UNSAFE));
804 if (isStatic) {
805 outArgs[1] = names[F_HOLDER] = new Name(getFunction(NF_staticBase), names[DMH_THIS]);
806 outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_staticOffset), names[DMH_THIS]);
807 } else {
808 outArgs[1] = names[OBJ_CHECK] = new Name(getFunction(NF_checkBase), names[OBJ_BASE]);
809 outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_fieldOffset), names[DMH_THIS]);
810 }
811 if (!isGetter) {
812 outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
813 }
814 for (Object a : outArgs) assert(a != null);
815 names[LINKER_CALL] = new Name(linker, outArgs);
816 if (needsCast && isGetter)
817 names[POST_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[LINKER_CALL]);
818 for (Name n : names) assert(n != null);
819
820 LambdaForm form;
821 if (needsCast || needsInit) {
822 // can't use the pre-generated form when casting and/or initializing
823 form = LambdaForm.create(ARG_LIMIT, names, RESULT);
824 } else {
825 form = LambdaForm.create(ARG_LIMIT, names, RESULT, kind);
826 }
827
828 if (LambdaForm.debugNames()) {
829 // add some detail to the lambdaForm debugname,
830 // significant only for debugging
831 StringBuilder nameBuilder = new StringBuilder(kind.methodName);
832 if (isStatic) {
843 LambdaForm.associateWithDebugName(form, nameBuilder.toString());
844 }
845 return form;
846 }
847
848 /**
849 * Pre-initialized NamedFunctions for bootstrapping purposes.
850 */
851 static final byte NF_internalMemberName = 0,
852 NF_internalMemberNameEnsureInit = 1,
853 NF_ensureInitialized = 2,
854 NF_fieldOffset = 3,
855 NF_checkBase = 4,
856 NF_staticBase = 5,
857 NF_staticOffset = 6,
858 NF_checkCast = 7,
859 NF_allocateInstance = 8,
860 NF_constructorMethod = 9,
861 NF_UNSAFE = 10,
862 NF_checkReceiver = 11,
863 NF_LIMIT = 12;
864
865 private static final @Stable NamedFunction[] NFS = new NamedFunction[NF_LIMIT];
866
867 private static NamedFunction getFunction(byte func) {
868 NamedFunction nf = NFS[func];
869 if (nf != null) {
870 return nf;
871 }
872 // Each nf must be statically invocable or we get tied up in our bootstraps.
873 nf = NFS[func] = createFunction(func);
874 assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf));
875 return nf;
876 }
877
878 private static final MethodType OBJ_OBJ_TYPE = MethodType.methodType(Object.class, Object.class);
879
880 private static final MethodType LONG_OBJ_TYPE = MethodType.methodType(long.class, Object.class);
881
882 private static NamedFunction createFunction(byte func) {
883 try {
884 switch (func) {
885 case NF_internalMemberName:
886 return getNamedFunction("internalMemberName", OBJ_OBJ_TYPE);
887 case NF_internalMemberNameEnsureInit:
888 return getNamedFunction("internalMemberNameEnsureInit", OBJ_OBJ_TYPE);
889 case NF_ensureInitialized:
890 return getNamedFunction("ensureInitialized", MethodType.methodType(void.class, Object.class));
891 case NF_fieldOffset:
892 return getNamedFunction("fieldOffset", LONG_OBJ_TYPE);
893 case NF_checkBase:
894 return getNamedFunction("checkBase", OBJ_OBJ_TYPE);
895 case NF_staticBase:
896 return getNamedFunction("staticBase", OBJ_OBJ_TYPE);
897 case NF_staticOffset:
898 return getNamedFunction("staticOffset", LONG_OBJ_TYPE);
899 case NF_checkCast:
900 return getNamedFunction("checkCast", MethodType.methodType(Object.class, Object.class, Object.class));
901 case NF_allocateInstance:
902 return getNamedFunction("allocateInstance", OBJ_OBJ_TYPE);
903 case NF_constructorMethod:
904 return getNamedFunction("constructorMethod", OBJ_OBJ_TYPE);
905 case NF_UNSAFE:
906 MemberName member = new MemberName(MethodHandleStatics.class, "UNSAFE", Unsafe.class, REF_getStatic);
907 return new NamedFunction(
908 MemberName.getFactory().resolveOrFail(REF_getStatic, member,
909 DirectMethodHandle.class, LM_TRUSTED,
910 NoSuchFieldException.class));
911 case NF_checkReceiver:
912 member = new MemberName(DirectMethodHandle.class, "checkReceiver", OBJ_OBJ_TYPE, REF_invokeVirtual);
913 return new NamedFunction(
914 MemberName.getFactory().resolveOrFail(REF_invokeVirtual, member,
915 DirectMethodHandle.class, LM_TRUSTED,
916 NoSuchMethodException.class));
917 default:
918 throw newInternalError("Unknown function: " + func);
919 }
920 } catch (ReflectiveOperationException ex) {
921 throw newInternalError(ex);
922 }
923 }
924
925 private static NamedFunction getNamedFunction(String name, MethodType type)
926 throws ReflectiveOperationException
927 {
928 MemberName member = new MemberName(DirectMethodHandle.class, name, type, REF_invokeStatic);
929 return new NamedFunction(
930 MemberName.getFactory().resolveOrFail(REF_invokeStatic, member,
931 DirectMethodHandle.class, LM_TRUSTED,
932 NoSuchMethodException.class));
933 }
934
935 static {
936 // The Holder class will contain pre-generated DirectMethodHandles resolved
|
116 return new StaticAccessor(mtype, lform, member, true, base, offset);
117 } else {
118 long offset = MethodHandleNatives.objectFieldOffset(member);
119 assert(offset == (int)offset);
120 return new Accessor(mtype, lform, member, true, (int)offset);
121 }
122 }
123 }
124 static DirectMethodHandle make(Class<?> refc, MemberName member) {
125 byte refKind = member.getReferenceKind();
126 if (refKind == REF_invokeSpecial)
127 refKind = REF_invokeVirtual;
128 return make(refKind, refc, member, null /* no callerClass context */);
129 }
130 static DirectMethodHandle make(MemberName member) {
131 if (member.isConstructor())
132 return makeAllocator(member.getDeclaringClass(), member);
133 return make(member.getDeclaringClass(), member);
134 }
135 static DirectMethodHandle makeAllocator(Class<?> instanceClass, MemberName ctor) {
136 assert(ctor.isConstructor()) : ctor;
137 ctor = ctor.asConstructor();
138 assert(ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
139 MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
140 LambdaForm lform = preparedLambdaForm(ctor);
141 MemberName init = ctor.asSpecial();
142 assert(init.getMethodType().returnType() == void.class);
143 return new Constructor(mtype, lform, ctor, true, init, instanceClass);
144 }
145
146 @Override
147 BoundMethodHandle rebind() {
148 return BoundMethodHandle.makeReinvoker(this);
149 }
150
151 @Override
152 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
153 assert(this.getClass() == DirectMethodHandle.class); // must override in subclasses
154 return new DirectMethodHandle(mt, lf, member, crackable);
155 }
156
157 @Override
158 MethodHandle viewAsType(MethodType newType, boolean strict) {
357 }
358 Class<?> cls = member.getDeclaringClass();
359 if (cls == ValueConversions.class ||
360 cls == MethodHandleImpl.class ||
361 cls == Invokers.class) {
362 // These guys have lots of <clinit> DMH creation but we know
363 // the MHs will not be used until the system is booted.
364 return false;
365 }
366 if (VerifyAccess.isSamePackage(MethodHandle.class, cls) ||
367 VerifyAccess.isSamePackage(ValueConversions.class, cls)) {
368 // It is a system class. It is probably in the process of
369 // being initialized, but we will help it along just to be safe.
370 UNSAFE.ensureClassInitialized(cls);
371 return CDS.needsClassInitBarrier(cls);
372 }
373 return UNSAFE.shouldBeInitialized(cls) || CDS.needsClassInitBarrier(cls);
374 }
375
376 private void ensureInitialized() {
377 if (checkInitialized()) {
378 // The coast is clear. Delete the <clinit> barrier.
379 updateForm(new Function<>() {
380 public LambdaForm apply(LambdaForm oldForm) {
381 return (member.isField() ? preparedFieldLambdaForm(member)
382 : preparedLambdaForm(member));
383 }
384 });
385 }
386 }
387 private boolean checkInitialized() {
388 Class<?> defc = member.getDeclaringClass();
389 UNSAFE.ensureClassInitialized(defc);
390 // Once we get here either defc was fully initialized by another thread, or
391 // defc was already being initialized by the current thread. In the latter case
392 // the barrier must remain. We can detect this simply by checking if initialization
393 // is still needed.
394 boolean initializingStill = UNSAFE.shouldBeInitialized(defc);
395 if (initializingStill && member.isStrict()) {
396 // while <clinit> is running, we track access to strict static fields
397 UNSAFE.notifyStrictStaticAccess(defc, staticOffset(this), member.isSetter());
398 }
399 return !initializingStill;
400 }
401
402 /*non-public*/
403 static void ensureInitialized(Object mh) {
404 ((DirectMethodHandle)mh).ensureInitialized();
405 }
406
407 /** This subclass represents invokespecial instructions. */
408 static final class Special extends DirectMethodHandle {
409 private final Class<?> caller;
410 private Special(MethodType mtype, LambdaForm form, MemberName member, boolean crackable, Class<?> caller) {
411 super(mtype, form, member, crackable);
412 this.caller = caller;
413 }
414 @Override
415 boolean isInvokeSpecial() {
416 return true;
417 }
418 @Override
419 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
499 return new Constructor(newType, form, member, false, initMethod, instanceClass);
500 }
501 }
502
503 /*non-public*/
504 static Object constructorMethod(Object mh) {
505 Constructor dmh = (Constructor)mh;
506 return dmh.initMethod;
507 }
508
509 /*non-public*/
510 static Object allocateInstance(Object mh) throws InstantiationException {
511 Constructor dmh = (Constructor)mh;
512 return UNSAFE.allocateInstance(dmh.instanceClass);
513 }
514
515 /** This subclass handles non-static field references. */
516 static final class Accessor extends DirectMethodHandle {
517 final Class<?> fieldType;
518 final int fieldOffset;
519 final int layout;
520 private Accessor(MethodType mtype, LambdaForm form, MemberName member,
521 boolean crackable, int fieldOffset) {
522 super(mtype, form, member, crackable);
523 this.fieldType = member.getFieldType();
524 this.fieldOffset = fieldOffset;
525 this.layout = member.getLayout();
526 }
527
528 @Override Object checkCast(Object obj) {
529 return fieldType.cast(obj);
530 }
531 @Override
532 MethodHandle copyWith(MethodType mt, LambdaForm lf) {
533 return new Accessor(mt, lf, member, crackable, fieldOffset);
534 }
535 @Override
536 MethodHandle viewAsType(MethodType newType, boolean strict) {
537 assert(viewAsTypeChecks(newType, strict));
538 return new Accessor(newType, form, member, false, fieldOffset);
539 }
540 }
541
542 @ForceInline
543 /*non-public*/
544 static long fieldOffset(Object accessorObj) {
545 // Note: We return a long because that is what Unsafe.getObject likes.
595 }
596
597 @ForceInline
598 /*non-public*/
599 static Object staticBase(Object accessorObj) {
600 return ((StaticAccessor)accessorObj).staticBase;
601 }
602
603 @ForceInline
604 /*non-public*/
605 static long staticOffset(Object accessorObj) {
606 return ((StaticAccessor)accessorObj).staticOffset;
607 }
608
609 @ForceInline
610 /*non-public*/
611 static Object checkCast(Object mh, Object obj) {
612 return ((DirectMethodHandle) mh).checkCast(obj);
613 }
614
615 @ForceInline
616 /*non-public*/ static Class<?> fieldType(Object accessorObj) {
617 return ((Accessor) accessorObj).fieldType;
618 }
619
620 @ForceInline
621 static int fieldLayout(Object accessorObj) {
622 return ((Accessor) accessorObj).layout;
623 }
624
625 @ForceInline
626 /*non-public*/ static Class<?> staticFieldType(Object accessorObj) {
627 return ((StaticAccessor) accessorObj).fieldType;
628 }
629
630 Object checkCast(Object obj) {
631 return member.getMethodType().returnType().cast(obj);
632 }
633
634 // Caching machinery for field accessors:
635 static final byte
636 AF_GETFIELD = 0,
637 AF_PUTFIELD = 1,
638 AF_GETSTATIC = 2,
639 AF_PUTSTATIC = 3,
640 AF_GETSTATIC_INIT = 4,
641 AF_PUTSTATIC_INIT = 5,
642 AF_LIMIT = 6;
643 // Enumerate the different field kinds using Wrapper,
644 // with an extra case added for checked references and value field access
645 static final int
646 FT_LAST_WRAPPER = Wrapper.COUNT-1,
647 FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(),
648 FT_CHECKED_REF = FT_LAST_WRAPPER+1,
649 FT_CHECKED_VALUE = FT_LAST_WRAPPER+2, // flat vs non-flat x null value vs null-restricted value
650 FT_LIMIT = FT_LAST_WRAPPER+6;
651 private static int afIndex(byte formOp, boolean isVolatile, boolean isFlat, boolean isNullRestricted, int ftypeKind) {
652 return ((formOp * FT_LIMIT * 2)
653 + (isVolatile ? FT_LIMIT : 0)
654 + (isFlat ? 1 : 0)
655 + (isNullRestricted ? 1 : 0)
656 + ftypeKind);
657 }
658 @Stable
659 private static final LambdaForm[] ACCESSOR_FORMS
660 = new LambdaForm[afIndex(AF_LIMIT, false, false, false, 0)];
661 static int ftypeKind(Class<?> ftype) {
662 if (ftype.isPrimitive()) {
663 return Wrapper.forPrimitiveType(ftype).ordinal();
664 } else if (ftype.isInterface() || ftype.isAssignableFrom(Object.class)) {
665 // retyping can be done without a cast
666 return FT_UNCHECKED_REF;
667 } else {
668 return ftype.isValue() ? FT_CHECKED_VALUE : FT_CHECKED_REF;
669 }
670 }
671
672 /**
673 * Create a LF which can access the given field.
674 * Cache and share this structure among all fields with
675 * the same basicType and refKind.
676 */
677 private static LambdaForm preparedFieldLambdaForm(MemberName m) {
678 Class<?> ftype = m.getFieldType();
679 byte formOp = switch (m.getReferenceKind()) {
680 case REF_getField -> AF_GETFIELD;
681 case REF_putField -> AF_PUTFIELD;
682 case REF_getStatic -> AF_GETSTATIC;
683 case REF_putStatic -> AF_PUTSTATIC;
684 default -> throw new InternalError(m.toString());
685 };
686 if (shouldBeInitialized(m)) {
687 // precompute the barrier-free version:
688 preparedFieldLambdaForm(formOp, m.isVolatile(), m.isFlat(), m.isNullRestricted(), ftype);
689 assert((AF_GETSTATIC_INIT - AF_GETSTATIC) ==
690 (AF_PUTSTATIC_INIT - AF_PUTSTATIC));
691 formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
692 }
693 LambdaForm lform = preparedFieldLambdaForm(formOp, m.isVolatile(), m.isFlat(), m.isNullRestricted(), ftype);
694 maybeCompile(lform, m);
695 assert(lform.methodType().dropParameterTypes(0, 1)
696 .equals(m.getInvocationType().basicType()))
697 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
698 return lform;
699 }
700
701 private static LambdaForm preparedFieldLambdaForm(byte formOp, boolean isVolatile,
702 boolean isFlat, boolean isNullRestricted, Class<?> ftype) {
703 int ftypeKind = ftypeKind(ftype);
704 int afIndex = afIndex(formOp, isVolatile, isFlat, isNullRestricted, ftypeKind);
705 LambdaForm lform = ACCESSOR_FORMS[afIndex];
706 if (lform != null) return lform;
707 lform = makePreparedFieldLambdaForm(formOp, isVolatile,isFlat, isNullRestricted, ftypeKind);
708 ACCESSOR_FORMS[afIndex] = lform; // don't bother with a CAS
709 return lform;
710 }
711
712 private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
713
714 private static Kind getFieldKind(boolean isGetter, boolean isVolatile, boolean isFlat, Wrapper wrapper) {
715 if (isGetter) {
716 if (isVolatile) {
717 switch (wrapper) {
718 case BOOLEAN: return GET_BOOLEAN_VOLATILE;
719 case BYTE: return GET_BYTE_VOLATILE;
720 case SHORT: return GET_SHORT_VOLATILE;
721 case CHAR: return GET_CHAR_VOLATILE;
722 case INT: return GET_INT_VOLATILE;
723 case LONG: return GET_LONG_VOLATILE;
724 case FLOAT: return GET_FLOAT_VOLATILE;
725 case DOUBLE: return GET_DOUBLE_VOLATILE;
726 case OBJECT: return isFlat ? GET_FLAT_VALUE_VOLATILE : GET_REFERENCE_VOLATILE;
727 }
728 } else {
729 switch (wrapper) {
730 case BOOLEAN: return GET_BOOLEAN;
731 case BYTE: return GET_BYTE;
732 case SHORT: return GET_SHORT;
733 case CHAR: return GET_CHAR;
734 case INT: return GET_INT;
735 case LONG: return GET_LONG;
736 case FLOAT: return GET_FLOAT;
737 case DOUBLE: return GET_DOUBLE;
738 case OBJECT: return isFlat ? GET_FLAT_VALUE : GET_REFERENCE;
739 }
740 }
741 } else {
742 if (isVolatile) {
743 switch (wrapper) {
744 case BOOLEAN: return PUT_BOOLEAN_VOLATILE;
745 case BYTE: return PUT_BYTE_VOLATILE;
746 case SHORT: return PUT_SHORT_VOLATILE;
747 case CHAR: return PUT_CHAR_VOLATILE;
748 case INT: return PUT_INT_VOLATILE;
749 case LONG: return PUT_LONG_VOLATILE;
750 case FLOAT: return PUT_FLOAT_VOLATILE;
751 case DOUBLE: return PUT_DOUBLE_VOLATILE;
752 case OBJECT: return isFlat ? PUT_FLAT_VALUE_VOLATILE : PUT_REFERENCE_VOLATILE;
753 }
754 } else {
755 switch (wrapper) {
756 case BOOLEAN: return PUT_BOOLEAN;
757 case BYTE: return PUT_BYTE;
758 case SHORT: return PUT_SHORT;
759 case CHAR: return PUT_CHAR;
760 case INT: return PUT_INT;
761 case LONG: return PUT_LONG;
762 case FLOAT: return PUT_FLOAT;
763 case DOUBLE: return PUT_DOUBLE;
764 case OBJECT: return isFlat ? PUT_FLAT_VALUE : PUT_REFERENCE;
765 }
766 }
767 }
768 throw new AssertionError("Invalid arguments");
769 }
770
771 /** invoked by GenerateJLIClassesHelper */
772 static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftype) {
773 return makePreparedFieldLambdaForm(formOp, isVolatile, false, false, ftype);
774 }
775
776 private static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile,
777 boolean isFlat, boolean isNullRestricted, int ftypeKind) {
778 boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1);
779 boolean isStatic = (formOp >= AF_GETSTATIC);
780 boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
781 boolean needsCast = (ftypeKind == FT_CHECKED_REF || ftypeKind == FT_CHECKED_VALUE);
782 Wrapper fw = (needsCast ? Wrapper.OBJECT : ALL_WRAPPERS[ftypeKind]);
783 Class<?> ft = fw.primitiveType();
784 assert(needsCast ? true : ftypeKind(ft) == ftypeKind);
785
786 // getObject, putIntVolatile, etc.
787 Kind kind = getFieldKind(isGetter, isVolatile, isFlat, fw);
788
789 MethodType linkerType;
790 if (isGetter) {
791 linkerType = isFlat
792 ? MethodType.methodType(ft, Object.class, long.class, int.class, Class.class)
793 : MethodType.methodType(ft, Object.class, long.class);
794 } else {
795 linkerType = isFlat
796 ? MethodType.methodType(void.class, Object.class, long.class, int.class, Class.class, ft)
797 : MethodType.methodType(void.class, Object.class, long.class, ft);
798 }
799 MemberName linker = new MemberName(Unsafe.class, kind.methodName, linkerType, REF_invokeVirtual);
800 try {
801 linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, LM_TRUSTED,
802 NoSuchMethodException.class);
803 } catch (ReflectiveOperationException ex) {
804 throw newInternalError(ex);
805 }
806
807 // What is the external type of the lambda form?
808 MethodType mtype;
809 if (isGetter)
810 mtype = MethodType.methodType(ft);
811 else
812 mtype = MethodType.methodType(void.class, ft);
813 mtype = mtype.basicType(); // erase short to int, etc.
814 if (!isStatic)
815 mtype = mtype.insertParameterTypes(0, Object.class);
816 final int DMH_THIS = 0;
817 final int ARG_BASE = 1;
818 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
819 // if this is for non-static access, the base pointer is stored at this index:
820 final int OBJ_BASE = isStatic ? -1 : ARG_BASE;
821 // if this is for write access, the value to be written is stored at this index:
822 final int SET_VALUE = isGetter ? -1 : ARG_LIMIT - 1;
823 int nameCursor = ARG_LIMIT;
824 final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any
825 final int F_OFFSET = nameCursor++; // Either static offset or field offset.
826 final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
827 final int U_HOLDER = nameCursor++; // UNSAFE holder
828 final int INIT_BAR = (needsInit ? nameCursor++ : -1);
829 final int LAYOUT = (isFlat ? nameCursor++ : -1); // field must be instance
830 final int VALUE_TYPE = (isFlat ? nameCursor++ : -1);
831 final int NULL_CHECK = (isNullRestricted && !isGetter ? nameCursor++ : -1);
832 final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
833 final int LINKER_CALL = nameCursor++;
834 final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
835 final int RESULT = nameCursor-1; // either the call, or the cast
836 Name[] names = invokeArguments(nameCursor - ARG_LIMIT, mtype);
837 if (needsInit)
838 names[INIT_BAR] = new Name(getFunction(NF_ensureInitialized), names[DMH_THIS]);
839 if (!isGetter) {
840 if (isNullRestricted)
841 names[NULL_CHECK] = new Name(getFunction(NF_nullCheck), names[SET_VALUE]);
842 if (needsCast)
843 names[PRE_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[SET_VALUE]);
844 }
845 Object[] outArgs = new Object[1 + linkerType.parameterCount()];
846 assert (outArgs.length == (isGetter ? 3 : 4) + (isFlat ? 2 : 0));
847 outArgs[0] = names[U_HOLDER] = new Name(getFunction(NF_UNSAFE));
848 if (isStatic) {
849 outArgs[1] = names[F_HOLDER] = new Name(getFunction(NF_staticBase), names[DMH_THIS]);
850 outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_staticOffset), names[DMH_THIS]);
851 } else {
852 outArgs[1] = names[OBJ_CHECK] = new Name(getFunction(NF_checkBase), names[OBJ_BASE]);
853 outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_fieldOffset), names[DMH_THIS]);
854 }
855 int x = 3;
856 if (isFlat) {
857 assert !isStatic : "static field is flat form requested";
858 outArgs[x++] = names[LAYOUT] = new Name(getFunction(NF_fieldLayout), names[DMH_THIS]);
859 outArgs[x++] = names[VALUE_TYPE] = isStatic ? new Name(getFunction(NF_staticFieldType), names[DMH_THIS])
860 : new Name(getFunction(NF_fieldType), names[DMH_THIS]);
861 }
862 if (!isGetter) {
863 outArgs[x] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
864 }
865 for (Object a : outArgs) assert(a != null);
866 names[LINKER_CALL] = new Name(linker, outArgs);
867 if (needsCast && isGetter)
868 names[POST_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[LINKER_CALL]);
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) {
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_fieldLayout = 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 private static final MethodType INT_OBJ_TYPE = MethodType.methodType(int.class, Object.class);
935
936 private static final MethodType OBJ_OBJ_TYPE = MethodType.methodType(Object.class, Object.class);
937
938 private static final MethodType LONG_OBJ_TYPE = MethodType.methodType(long.class, Object.class);
939
940 private static NamedFunction createFunction(byte func) {
941 try {
942 switch (func) {
943 case NF_internalMemberName:
944 return getNamedFunction("internalMemberName", OBJ_OBJ_TYPE);
945 case NF_internalMemberNameEnsureInit:
946 return getNamedFunction("internalMemberNameEnsureInit", OBJ_OBJ_TYPE);
947 case NF_ensureInitialized:
948 return getNamedFunction("ensureInitialized", MethodType.methodType(void.class, Object.class));
949 case NF_fieldOffset:
950 return getNamedFunction("fieldOffset", LONG_OBJ_TYPE);
951 case NF_checkBase:
952 return getNamedFunction("checkBase", OBJ_OBJ_TYPE);
953 case NF_staticBase:
954 return getNamedFunction("staticBase", OBJ_OBJ_TYPE);
955 case NF_staticOffset:
956 return getNamedFunction("staticOffset", LONG_OBJ_TYPE);
957 case NF_checkCast:
958 return getNamedFunction("checkCast", MethodType.methodType(Object.class, Object.class, Object.class));
959 case NF_allocateInstance:
960 return getNamedFunction("allocateInstance", OBJ_OBJ_TYPE);
961 case NF_constructorMethod:
962 return getNamedFunction("constructorMethod", OBJ_OBJ_TYPE);
963 case NF_UNSAFE:
964 MemberName member = new MemberName(MethodHandleStatics.class, "UNSAFE", Unsafe.class, REF_getStatic);
965 return new NamedFunction(
966 MemberName.getFactory().resolveOrFail(REF_getStatic, member,
967 DirectMethodHandle.class, LM_TRUSTED,
968 NoSuchFieldException.class));
969 case NF_checkReceiver:
970 member = new MemberName(DirectMethodHandle.class, "checkReceiver", OBJ_OBJ_TYPE, REF_invokeVirtual);
971 return new NamedFunction(
972 MemberName.getFactory().resolveOrFail(REF_invokeVirtual, member,
973 DirectMethodHandle.class, LM_TRUSTED,
974 NoSuchMethodException.class));
975 case NF_fieldType:
976 return getNamedFunction("fieldType", CLS_OBJ_TYPE);
977 case NF_staticFieldType:
978 return getNamedFunction("staticFieldType", CLS_OBJ_TYPE);
979 case NF_nullCheck:
980 return getNamedFunction("nullCheck", OBJ_OBJ_TYPE);
981 case NF_fieldLayout:
982 return getNamedFunction("fieldLayout", INT_OBJ_TYPE);
983 default:
984 throw newInternalError("Unknown function: " + func);
985 }
986 } catch (ReflectiveOperationException ex) {
987 throw newInternalError(ex);
988 }
989 }
990
991 private static NamedFunction getNamedFunction(String name, MethodType type)
992 throws ReflectiveOperationException
993 {
994 MemberName member = new MemberName(DirectMethodHandle.class, name, type, REF_invokeStatic);
995 return new NamedFunction(
996 MemberName.getFactory().resolveOrFail(REF_invokeStatic, member,
997 DirectMethodHandle.class, LM_TRUSTED,
998 NoSuchMethodException.class));
999 }
1000
1001 static {
1002 // The Holder class will contain pre-generated DirectMethodHandles resolved
|