< prev index next >

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

Print this page
rev 47249 : 8187826: Avoid using reflection to bootstrap NamedFunctions
Reviewed-by: TBD


 736             NF_staticOffset = 6,
 737             NF_checkCast = 7,
 738             NF_allocateInstance = 8,
 739             NF_constructorMethod = 9,
 740             NF_UNSAFE = 10,
 741             NF_LIMIT = 11;
 742 
 743     private static final @Stable NamedFunction[] NFS = new NamedFunction[NF_LIMIT];
 744 
 745     private static NamedFunction getFunction(byte func) {
 746         NamedFunction nf = NFS[func];
 747         if (nf != null) {
 748             return nf;
 749         }
 750         // Each nf must be statically invocable or we get tied up in our bootstraps.
 751         nf = NFS[func] = createFunction(func);
 752         assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf));
 753         return nf;
 754     }
 755 




 756     private static NamedFunction createFunction(byte func) {
 757         try {
 758             switch (func) {
 759                 case NF_internalMemberName:
 760                     return new NamedFunction(DirectMethodHandle.class
 761                             .getDeclaredMethod("internalMemberName", Object.class));
 762                 case NF_internalMemberNameEnsureInit:
 763                     return new NamedFunction(DirectMethodHandle.class
 764                             .getDeclaredMethod("internalMemberNameEnsureInit", Object.class));
 765                 case NF_ensureInitialized:
 766                     return new NamedFunction(DirectMethodHandle.class
 767                             .getDeclaredMethod("ensureInitialized", Object.class));
 768                 case NF_fieldOffset:
 769                     return new NamedFunction(DirectMethodHandle.class
 770                             .getDeclaredMethod("fieldOffset", Object.class));
 771                 case NF_checkBase:
 772                     return new NamedFunction(DirectMethodHandle.class
 773                             .getDeclaredMethod("checkBase", Object.class));
 774                 case NF_staticBase:
 775                     return new NamedFunction(DirectMethodHandle.class
 776                             .getDeclaredMethod("staticBase", Object.class));
 777                 case NF_staticOffset:
 778                     return new NamedFunction(DirectMethodHandle.class
 779                             .getDeclaredMethod("staticOffset", Object.class));
 780                 case NF_checkCast:
 781                     return new NamedFunction(DirectMethodHandle.class
 782                             .getDeclaredMethod("checkCast", Object.class, Object.class));
 783                 case NF_allocateInstance:
 784                     return new NamedFunction(DirectMethodHandle.class
 785                             .getDeclaredMethod("allocateInstance", Object.class));
 786                 case NF_constructorMethod:
 787                     return new NamedFunction(DirectMethodHandle.class
 788                             .getDeclaredMethod("constructorMethod", Object.class));
 789                 case NF_UNSAFE:
 790                     return new NamedFunction(new MemberName(MethodHandleStatics.class
 791                             .getDeclaredField("UNSAFE")));


 792                 default:
 793                     throw newInternalError("Unknown function: " + func);
 794             }
 795         } catch (ReflectiveOperationException ex) {
 796             throw newInternalError(ex);
 797         }









 798     }
 799 
 800     static {
 801         // The Holder class will contain pre-generated DirectMethodHandles resolved
 802         // speculatively using MemberName.getFactory().resolveOrNull. However, that
 803         // doesn't initialize the class, which subtly breaks inlining etc. By forcing
 804         // initialization of the Holder class we avoid these issues.
 805         UNSAFE.ensureClassInitialized(Holder.class);
 806     }
 807 
 808     /* Placeholder class for DirectMethodHandles generated ahead of time */
 809     final class Holder {}
 810 }


 736             NF_staticOffset = 6,
 737             NF_checkCast = 7,
 738             NF_allocateInstance = 8,
 739             NF_constructorMethod = 9,
 740             NF_UNSAFE = 10,
 741             NF_LIMIT = 11;
 742 
 743     private static final @Stable NamedFunction[] NFS = new NamedFunction[NF_LIMIT];
 744 
 745     private static NamedFunction getFunction(byte func) {
 746         NamedFunction nf = NFS[func];
 747         if (nf != null) {
 748             return nf;
 749         }
 750         // Each nf must be statically invocable or we get tied up in our bootstraps.
 751         nf = NFS[func] = createFunction(func);
 752         assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf));
 753         return nf;
 754     }
 755 
 756     private static final MethodType OBJ_OBJ_TYPE = MethodType.methodType(Object.class, Object.class);
 757 
 758     private static final MethodType LONG_OBJ_TYPE = MethodType.methodType(long.class, Object.class);
 759 
 760     private static NamedFunction createFunction(byte func) {
 761         try {
 762             switch (func) {
 763                 case NF_internalMemberName:
 764                     return getNamedFunction("internalMemberName", OBJ_OBJ_TYPE);

 765                 case NF_internalMemberNameEnsureInit:
 766                     return getNamedFunction("internalMemberNameEnsureInit", OBJ_OBJ_TYPE);

 767                 case NF_ensureInitialized:
 768                     return getNamedFunction("ensureInitialized", MethodType.methodType(void.class, Object.class));

 769                 case NF_fieldOffset:
 770                     return getNamedFunction("fieldOffset", LONG_OBJ_TYPE);

 771                 case NF_checkBase:
 772                     return getNamedFunction("checkBase", OBJ_OBJ_TYPE);

 773                 case NF_staticBase:
 774                     return getNamedFunction("staticBase", OBJ_OBJ_TYPE);

 775                 case NF_staticOffset:
 776                     return getNamedFunction("staticOffset", LONG_OBJ_TYPE);

 777                 case NF_checkCast:
 778                     return getNamedFunction("checkCast", MethodType.methodType(Object.class, Object.class, Object.class));

 779                 case NF_allocateInstance:
 780                     return getNamedFunction("allocateInstance", OBJ_OBJ_TYPE);

 781                 case NF_constructorMethod:
 782                     return getNamedFunction("constructorMethod", OBJ_OBJ_TYPE);

 783                 case NF_UNSAFE:
 784                     MemberName member = new MemberName(MethodHandleStatics.class, "UNSAFE", Unsafe.class, REF_getField);
 785                     return new NamedFunction(
 786                             MemberName.getFactory()
 787                                     .resolveOrFail(REF_getField, member, DirectMethodHandle.class, NoSuchMethodException.class));
 788                 default:
 789                     throw newInternalError("Unknown function: " + func);
 790             }
 791         } catch (ReflectiveOperationException ex) {
 792             throw newInternalError(ex);
 793         }
 794     }
 795 
 796     private static NamedFunction getNamedFunction(String name, MethodType type)
 797         throws ReflectiveOperationException
 798     {
 799         MemberName member = new MemberName(DirectMethodHandle.class, name, type, REF_invokeStatic);
 800         return new NamedFunction(
 801             MemberName.getFactory()
 802                 .resolveOrFail(REF_invokeStatic, member, DirectMethodHandle.class, NoSuchMethodException.class));
 803     }
 804 
 805     static {
 806         // The Holder class will contain pre-generated DirectMethodHandles resolved
 807         // speculatively using MemberName.getFactory().resolveOrNull. However, that
 808         // doesn't initialize the class, which subtly breaks inlining etc. By forcing
 809         // initialization of the Holder class we avoid these issues.
 810         UNSAFE.ensureClassInitialized(Holder.class);
 811     }
 812 
 813     /* Placeholder class for DirectMethodHandles generated ahead of time */
 814     final class Holder {}
 815 }
< prev index next >