< prev index next >

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

Print this page

 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
< prev index next >