You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2019/11/30 17:16:57 UTC

[groovy] branch GROOVY_3_0_X updated: Avoid transforming same meta methods repeatedly

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
     new 3c0810d  Avoid transforming same meta methods repeatedly
3c0810d is described below

commit 3c0810d58982f49e095327c4937e54af95d468c1
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sun Dec 1 00:28:17 2019 +0800

    Avoid transforming same meta methods repeatedly
    
    (cherry picked from commit 69dd93161d40e3697172cda760a1b08d1240188a)
---
 .../codehaus/groovy/reflection/CachedMethod.java   |  9 +++++
 .../org/codehaus/groovy/vmplugin/v9/Java9.java     | 42 +++++++++++++++-------
 2 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/reflection/CachedMethod.java b/src/main/java/org/codehaus/groovy/reflection/CachedMethod.java
index fec89fc..211079b 100644
--- a/src/main/java/org/codehaus/groovy/reflection/CachedMethod.java
+++ b/src/main/java/org/codehaus/groovy/reflection/CachedMethod.java
@@ -47,6 +47,7 @@ public class CachedMethod extends MetaMethod implements Comparable {
 
     private final Method cachedMethod;
     private int hashCode;
+    private CachedMethod transformedMethod;
 
     private static final MyComparator COMPARATOR = new MyComparator();
 
@@ -149,6 +150,14 @@ public class CachedMethod extends MetaMethod implements Comparable {
         return MethodHelper.isStatic(cachedMethod);
     }
 
+    public CachedMethod getTransformedMethod() {
+        return transformedMethod;
+    }
+
+    public void setTransformedMethod(CachedMethod transformedMethod) {
+        this.transformedMethod = transformedMethod;
+    }
+
     public int compareTo(Object o) {
       if (o instanceof CachedMethod)
         return compareToCachedMethod((CachedMethod)o);
diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v9/Java9.java b/src/main/java/org/codehaus/groovy/vmplugin/v9/Java9.java
index 5243df3..bbf56de 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v9/Java9.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v9/Java9.java
@@ -176,25 +176,41 @@ public class Java9 extends Java8 {
             return metaMethod;
         }
 
-        Class<?> declaringClass = methodDeclaringClass.getTheClass();
-
-        int methodModifiers = cachedMethod.getModifiers();
-
         if (null == caller) {
             caller = ReflectionUtils.class; // "set accessible" are done via `org.codehaus.groovy.reflection.ReflectionUtils` as shown in warnings
         }
 
+        return getOrTransformMetaMethod(metaClass, caller, cachedMethod);
+    }
+
+    private CachedMethod getOrTransformMetaMethod(MetaClass metaClass, Class<?> caller, CachedMethod cachedMethod) {
+        CachedMethod transformedMethod = cachedMethod.getTransformedMethod();
+        if (null != transformedMethod) {
+            return transformedMethod;
+        }
+
+        transformedMethod = doTransformMetaMethod(metaClass, cachedMethod, caller);
+        cachedMethod.setTransformedMethod(transformedMethod);
+
+        return transformedMethod;
+    }
+
+    private CachedMethod doTransformMetaMethod(MetaClass metaClass, CachedMethod metaMethod, Class<?> caller) {
+        CachedClass methodDeclaringClass = metaMethod.getDeclaringClass();
+        Class<?> declaringClass = methodDeclaringClass.getTheClass();
+        int methodModifiers = metaMethod.getModifiers();
+
         // if caller can access the method,
         // no need to transform the meta method
         if (checkAccessible(caller, declaringClass, methodModifiers, false)) {
             return metaMethod;
         }
 
-        Class<?>[] params = cachedMethod.getPT();
+        Class<?>[] params = metaMethod.getPT();
         Class<?> theClass = metaClass.getTheClass();
         if (declaringClass == theClass) {
             if (BigInteger.class == theClass) {
-                MetaMethod bigIntegerMetaMethod = transformBigIntegerMetaMethod(metaMethod, params);
+                CachedMethod bigIntegerMetaMethod = transformBigIntegerMetaMethod(metaMethod, params);
                 if (bigIntegerMetaMethod != metaMethod) {
                     return bigIntegerMetaMethod;
                 }
@@ -206,7 +222,7 @@ public class Java9 extends Java8 {
             classList.add(0, theClass);
 
             for (Class<?> sc : classList) {
-                Optional<MetaMethod> optionalMetaMethod = getAccessibleMetaMethod(metaMethod, params, caller, sc);
+                Optional<CachedMethod> optionalMetaMethod = getAccessibleMetaMethod(metaMethod, params, caller, sc);
                 if (optionalMetaMethod.isPresent()) {
                     return optionalMetaMethod.get();
                 }
@@ -221,7 +237,7 @@ public class Java9 extends Java8 {
         // e.g. StringBuilder sb = new StringBuilder(); sb.setLength(0);
         // `setLength` is the method of `AbstractStringBuilder`, which is `package-private`
         if (declaringClass.isAssignableFrom(theClass)) {
-            Optional<MetaMethod> optionalMetaMethod = getAccessibleMetaMethod(metaMethod, params, caller, theClass);
+            Optional<CachedMethod> optionalMetaMethod = getAccessibleMetaMethod(metaMethod, params, caller, theClass);
             if (optionalMetaMethod.isPresent()) {
                 return optionalMetaMethod.get();
             }
@@ -230,7 +246,7 @@ public class Java9 extends Java8 {
         return metaMethod;
     }
 
-    private static MetaMethod transformBigIntegerMetaMethod(MetaMethod metaMethod, Class<?>[] params) {
+    private static CachedMethod transformBigIntegerMetaMethod(CachedMethod metaMethod, Class<?>[] params) {
         if (1 == params.length && MULTIPLY.equals(metaMethod.getName())) {
             Class<?> param = params[0];
             if (Long.class == param || long.class == param
@@ -243,9 +259,9 @@ public class Java9 extends Java8 {
         return metaMethod;
     }
 
-    private Optional<MetaMethod> getAccessibleMetaMethod(MetaMethod metaMethod, Class<?>[] params, Class<?> caller, Class<?> sc) {
-        List<MetaMethod> metaMethodList = getMetaMethods(metaMethod, params, sc);
-        for (MetaMethod mm : metaMethodList) {
+    private Optional<CachedMethod> getAccessibleMetaMethod(CachedMethod metaMethod, Class<?>[] params, Class<?> caller, Class<?> sc) {
+        List<CachedMethod> metaMethodList = getMetaMethods(metaMethod, params, sc);
+        for (CachedMethod mm : metaMethodList) {
             if (checkAccessible(caller, mm.getDeclaringClass().getTheClass(), mm.getModifiers(), false)) {
                 return Optional.of(mm);
             }
@@ -253,7 +269,7 @@ public class Java9 extends Java8 {
         return Optional.empty();
     }
 
-    private static List<MetaMethod> getMetaMethods(MetaMethod metaMethod, Class<?>[] params, Class<?> sc) {
+    private static List<CachedMethod> getMetaMethods(CachedMethod metaMethod, Class<?>[] params, Class<?> sc) {
         List<Method> optionalMethod = ReflectionUtils.getMethods(sc, metaMethod.getName(), params);
         return optionalMethod.stream().map(CachedMethod::new).collect(Collectors.toList());
     }