8199862: Examine ProxyBuilder::referencedTypes startup cost
authorredestad
Wed, 21 Mar 2018 10:13:49 +0100
changeset 49273 af8ab4f90a32
parent 49272 e137b71166c4
child 49274 9f3ce373370a
8199862: Examine ProxyBuilder::referencedTypes startup cost Reviewed-by: mchung
src/java.base/share/classes/java/lang/reflect/Constructor.java
src/java.base/share/classes/java/lang/reflect/Executable.java
src/java.base/share/classes/java/lang/reflect/Method.java
src/java.base/share/classes/java/lang/reflect/Proxy.java
--- a/src/java.base/share/classes/java/lang/reflect/Constructor.java	Wed Mar 21 10:13:14 2018 +0100
+++ b/src/java.base/share/classes/java/lang/reflect/Constructor.java	Wed Mar 21 10:13:49 2018 +0100
@@ -253,6 +253,11 @@
         return parameterTypes;
     }
 
+    @Override
+    Class<?>[] getSharedExceptionTypes() {
+        return exceptionTypes;
+    }
+
     /**
      * {@inheritDoc}
      */
--- a/src/java.base/share/classes/java/lang/reflect/Executable.java	Wed Mar 21 10:13:14 2018 +0100
+++ b/src/java.base/share/classes/java/lang/reflect/Executable.java	Wed Mar 21 10:13:49 2018 +0100
@@ -226,6 +226,10 @@
     // to the untrusted code...
     abstract Class<?>[] getSharedParameterTypes();
 
+    // returns shared array of exception types - must never give it out
+    // to the untrusted code...
+    abstract Class<?>[] getSharedExceptionTypes();
+
     /**
      * Returns an array of {@code Class} objects that represent the formal
      * parameter types, in declaration order, of the executable
--- a/src/java.base/share/classes/java/lang/reflect/Method.java	Wed Mar 21 10:13:14 2018 +0100
+++ b/src/java.base/share/classes/java/lang/reflect/Method.java	Wed Mar 21 10:13:49 2018 +0100
@@ -301,6 +301,11 @@
         return parameterTypes;
     }
 
+    @Override
+    Class<?>[] getSharedExceptionTypes() {
+        return exceptionTypes;
+    }
+
     /**
      * {@inheritDoc}
      */
--- a/src/java.base/share/classes/java/lang/reflect/Proxy.java	Wed Mar 21 10:13:14 2018 +0100
+++ b/src/java.base/share/classes/java/lang/reflect/Proxy.java	Wed Mar 21 10:13:49 2018 +0100
@@ -708,24 +708,32 @@
          */
         private static Set<Class<?>> referencedTypes(ClassLoader loader,
                                                      List<Class<?>> interfaces) {
-            return interfaces.stream()
-                 .flatMap(intf -> Stream.of(intf.getMethods())
-                                        .filter(m -> !Modifier.isStatic(m.getModifiers()))
-                                        .flatMap(ProxyBuilder::methodRefTypes)
-                                        .map(ProxyBuilder::getElementType)
-                                        .filter(t -> !t.isPrimitive()))
-                 .collect(Collectors.toSet());
+            var types = new HashSet<Class<?>>();
+            for (var intf : interfaces) {
+                for (Method m : intf.getMethods()) {
+                    if (!Modifier.isStatic(m.getModifiers())) {
+                        addElementType(types, m.getReturnType());
+                        addElementTypes(types, m.getSharedParameterTypes());
+                        addElementTypes(types, m.getSharedExceptionTypes());
+                    }
+                }
+            }
+            return types;
         }
 
-        /*
-         * Extracts all types referenced on a method signature including
-         * its return type, parameter types, and exception types.
-         */
-        private static Stream<Class<?>> methodRefTypes(Method m) {
-            return Stream.of(new Class<?>[] { m.getReturnType() },
-                             m.getParameterTypes(),
-                             m.getExceptionTypes())
-                         .flatMap(Stream::of);
+        private static void addElementTypes(HashSet<Class<?>> types,
+                                            Class<?> ... classes) {
+            for (var cls : classes) {
+                addElementType(types, cls);
+            }
+        }
+
+        private static void addElementType(HashSet<Class<?>> types,
+                                           Class<?> cls) {
+            var type = getElementType(cls);
+            if (!type.isPrimitive()) {
+                types.add(type);
+            }
         }
 
         /**