8198755: Reduce cost of InvokerBytecodeGenerator::isStaticallyInvocable/-Nameable
authorredestad
Tue, 27 Feb 2018 21:05:07 +0100
changeset 48993 aef762ff9b23
parent 48992 b8cd2fcc98e2
child 48994 817e39d3a9e0
8198755: Reduce cost of InvokerBytecodeGenerator::isStaticallyInvocable/-Nameable Reviewed-by: vlivanov, psandoz, jrose
src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
--- a/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Tue Feb 27 12:47:58 2018 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Tue Feb 27 21:05:07 2018 +0100
@@ -928,6 +928,12 @@
         if (member == null)  return false;
         if (member.isConstructor())  return false;
         Class<?> cls = member.getDeclaringClass();
+        // Fast-path non-private members declared by MethodHandles, which is a common
+        // case
+        if (MethodHandle.class.isAssignableFrom(cls) && !member.isPrivate()) {
+            assert(isStaticallyInvocableType(member.getMethodOrFieldType()));
+            return true;
+        }
         if (cls.isArray() || cls.isPrimitive())
             return false;  // FIXME
         if (cls.isAnonymousClass() || cls.isLocalClass())
@@ -936,12 +942,8 @@
             return false;  // not on BCP
         if (ReflectUtil.isVMAnonymousClass(cls)) // FIXME: switch to supported API once it is added
             return false;
-        MethodType mtype = member.getMethodOrFieldType();
-        if (!isStaticallyNameable(mtype.returnType()))
+        if (!isStaticallyInvocableType(member.getMethodOrFieldType()))
             return false;
-        for (Class<?> ptype : mtype.parameterArray())
-            if (!isStaticallyNameable(ptype))
-                return false;
         if (!member.isPrivate() && VerifyAccess.isSamePackage(MethodHandle.class, cls))
             return true;   // in java.lang.invoke package
         if (member.isPublic() && isStaticallyNameable(cls))
@@ -949,9 +951,22 @@
         return false;
     }
 
+    private static boolean isStaticallyInvocableType(MethodType mtype) {
+        if (!isStaticallyNameable(mtype.returnType()))
+            return false;
+        for (Class<?> ptype : mtype.parameterArray())
+            if (!isStaticallyNameable(ptype))
+                return false;
+        return true;
+    }
+
     static boolean isStaticallyNameable(Class<?> cls) {
         if (cls == Object.class)
             return true;
+        if (MethodHandle.class.isAssignableFrom(cls)) {
+            assert(!ReflectUtil.isVMAnonymousClass(cls));
+            return true;
+        }
         while (cls.isArray())
             cls = cls.getComponentType();
         if (cls.isPrimitive())