8187826: Avoid using reflection to bootstrap NamedFunctions
authorredestad
Wed, 27 Sep 2017 17:56:00 +0200
changeset 47280 95192765a858
parent 47279 4f48d7ecf2db
child 47281 24d5b83fca46
8187826: Avoid using reflection to bootstrap NamedFunctions Reviewed-by: psandoz
src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java
src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java
src/java.base/share/classes/java/lang/invoke/Invokers.java
--- a/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java	Wed Sep 27 17:09:52 2017 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java	Wed Sep 27 17:56:00 2017 +0200
@@ -28,6 +28,7 @@
 import java.util.Arrays;
 import static java.lang.invoke.LambdaForm.*;
 import static java.lang.invoke.LambdaForm.Kind.*;
+import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeVirtual;
 import static java.lang.invoke.MethodHandleStatics.*;
 
 /**
@@ -158,8 +159,11 @@
     static final NamedFunction NF_getTarget;
     static {
         try {
-            NF_getTarget = new NamedFunction(DelegatingMethodHandle.class
-                                             .getDeclaredMethod("getTarget"));
+            MemberName member = new MemberName(DelegatingMethodHandle.class, "getTarget",
+                    MethodType.methodType(MethodHandle.class), REF_invokeVirtual);
+            NF_getTarget = new NamedFunction(
+                    MemberName.getFactory()
+                            .resolveOrFail(REF_invokeVirtual, member, DelegatingMethodHandle.class, NoSuchMethodException.class));
         } catch (ReflectiveOperationException ex) {
             throw newInternalError(ex);
         }
--- a/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Wed Sep 27 17:09:52 2017 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Wed Sep 27 17:56:00 2017 +0200
@@ -753,42 +753,38 @@
         return nf;
     }
 
+    private static final MethodType OBJ_OBJ_TYPE = MethodType.methodType(Object.class, Object.class);
+
+    private static final MethodType LONG_OBJ_TYPE = MethodType.methodType(long.class, Object.class);
+
     private static NamedFunction createFunction(byte func) {
         try {
             switch (func) {
                 case NF_internalMemberName:
-                    return new NamedFunction(DirectMethodHandle.class
-                            .getDeclaredMethod("internalMemberName", Object.class));
+                    return getNamedFunction("internalMemberName", OBJ_OBJ_TYPE);
                 case NF_internalMemberNameEnsureInit:
-                    return new NamedFunction(DirectMethodHandle.class
-                            .getDeclaredMethod("internalMemberNameEnsureInit", Object.class));
+                    return getNamedFunction("internalMemberNameEnsureInit", OBJ_OBJ_TYPE);
                 case NF_ensureInitialized:
-                    return new NamedFunction(DirectMethodHandle.class
-                            .getDeclaredMethod("ensureInitialized", Object.class));
+                    return getNamedFunction("ensureInitialized", MethodType.methodType(void.class, Object.class));
                 case NF_fieldOffset:
-                    return new NamedFunction(DirectMethodHandle.class
-                            .getDeclaredMethod("fieldOffset", Object.class));
+                    return getNamedFunction("fieldOffset", LONG_OBJ_TYPE);
                 case NF_checkBase:
-                    return new NamedFunction(DirectMethodHandle.class
-                            .getDeclaredMethod("checkBase", Object.class));
+                    return getNamedFunction("checkBase", OBJ_OBJ_TYPE);
                 case NF_staticBase:
-                    return new NamedFunction(DirectMethodHandle.class
-                            .getDeclaredMethod("staticBase", Object.class));
+                    return getNamedFunction("staticBase", OBJ_OBJ_TYPE);
                 case NF_staticOffset:
-                    return new NamedFunction(DirectMethodHandle.class
-                            .getDeclaredMethod("staticOffset", Object.class));
+                    return getNamedFunction("staticOffset", LONG_OBJ_TYPE);
                 case NF_checkCast:
-                    return new NamedFunction(DirectMethodHandle.class
-                            .getDeclaredMethod("checkCast", Object.class, Object.class));
+                    return getNamedFunction("checkCast", MethodType.methodType(Object.class, Object.class, Object.class));
                 case NF_allocateInstance:
-                    return new NamedFunction(DirectMethodHandle.class
-                            .getDeclaredMethod("allocateInstance", Object.class));
+                    return getNamedFunction("allocateInstance", OBJ_OBJ_TYPE);
                 case NF_constructorMethod:
-                    return new NamedFunction(DirectMethodHandle.class
-                            .getDeclaredMethod("constructorMethod", Object.class));
+                    return getNamedFunction("constructorMethod", OBJ_OBJ_TYPE);
                 case NF_UNSAFE:
-                    return new NamedFunction(new MemberName(MethodHandleStatics.class
-                            .getDeclaredField("UNSAFE")));
+                    MemberName member = new MemberName(MethodHandleStatics.class, "UNSAFE", Unsafe.class, REF_getField);
+                    return new NamedFunction(
+                            MemberName.getFactory()
+                                    .resolveOrFail(REF_getField, member, DirectMethodHandle.class, NoSuchMethodException.class));
                 default:
                     throw newInternalError("Unknown function: " + func);
             }
@@ -797,6 +793,15 @@
         }
     }
 
+    private static NamedFunction getNamedFunction(String name, MethodType type)
+        throws ReflectiveOperationException
+    {
+        MemberName member = new MemberName(DirectMethodHandle.class, name, type, REF_invokeStatic);
+        return new NamedFunction(
+            MemberName.getFactory()
+                .resolveOrFail(REF_invokeStatic, member, DirectMethodHandle.class, NoSuchMethodException.class));
+    }
+
     static {
         // The Holder class will contain pre-generated DirectMethodHandles resolved
         // speculatively using MemberName.getFactory().resolveOrNull. However, that
--- a/src/java.base/share/classes/java/lang/invoke/Invokers.java	Wed Sep 27 17:09:52 2017 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/Invokers.java	Wed Sep 27 17:56:00 2017 +0200
@@ -611,23 +611,17 @@
         try {
             switch (func) {
                 case NF_checkExactType:
-                    return new NamedFunction(Invokers.class
-                        .getDeclaredMethod("checkExactType", MethodHandle.class,  MethodType.class));
+                    return getNamedFunction("checkExactType", MethodType.methodType(void.class, MethodHandle.class, MethodType.class));
                 case NF_checkGenericType:
-                    return new NamedFunction(Invokers.class
-                        .getDeclaredMethod("checkGenericType", MethodHandle.class,  MethodType.class));
+                    return getNamedFunction("checkGenericType", MethodType.methodType(MethodHandle.class, MethodHandle.class, MethodType.class));
                 case NF_getCallSiteTarget:
-                    return new NamedFunction(Invokers.class
-                        .getDeclaredMethod("getCallSiteTarget", CallSite.class));
+                    return getNamedFunction("getCallSiteTarget", MethodType.methodType(MethodHandle.class, CallSite.class));
                 case NF_checkCustomized:
-                    return new NamedFunction(Invokers.class
-                        .getDeclaredMethod("checkCustomized", MethodHandle.class));
+                    return getNamedFunction("checkCustomized", MethodType.methodType(void.class, MethodHandle.class));
                 case NF_checkVarHandleGenericType:
-                    return new NamedFunction(Invokers.class
-                        .getDeclaredMethod("checkVarHandleGenericType", VarHandle.class, VarHandle.AccessDescriptor.class));
+                    return getNamedFunction("checkVarHandleGenericType", MethodType.methodType(MethodHandle.class, VarHandle.class, VarHandle.AccessDescriptor.class));
                 case NF_checkVarHandleExactType:
-                    return new NamedFunction(Invokers.class
-                        .getDeclaredMethod("checkVarHandleExactType", VarHandle.class, VarHandle.AccessDescriptor.class));
+                    return getNamedFunction("checkVarHandleExactType", MethodType.methodType(MethodHandle.class, VarHandle.class, VarHandle.AccessDescriptor.class));
                 default:
                     throw newInternalError("Unknown function: " + func);
             }
@@ -636,6 +630,15 @@
         }
     }
 
+    private static NamedFunction getNamedFunction(String name, MethodType type)
+        throws ReflectiveOperationException
+    {
+        MemberName member = new MemberName(Invokers.class, name, type, REF_invokeStatic);
+        return new NamedFunction(
+                MemberName.getFactory()
+                        .resolveOrFail(REF_invokeStatic, member, Invokers.class, NoSuchMethodException.class));
+    }
+
     private static class Lazy {
         private static final MethodHandle MH_asSpreader;