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 2021/06/26 05:00:48 UTC
[groovy] 01/01: Avoid cache method repeatedly
This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch danielsun/tweak-cache-20210626
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 26a27fa92a5e5f1cb4dcf1a25a6f52dc5e03b5c2
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sat Jun 26 12:58:44 2021 +0800
Avoid cache method repeatedly
---
src/main/java/groovy/lang/MetaClassImpl.java | 67 ++++++++++++++++------------
1 file changed, 39 insertions(+), 28 deletions(-)
diff --git a/src/main/java/groovy/lang/MetaClassImpl.java b/src/main/java/groovy/lang/MetaClassImpl.java
index e8068f2..7624e41 100644
--- a/src/main/java/groovy/lang/MetaClassImpl.java
+++ b/src/main/java/groovy/lang/MetaClassImpl.java
@@ -115,6 +115,7 @@ import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.function.Function;
import static groovy.lang.Tuple.tuple;
import static java.lang.Character.isUpperCase;
@@ -122,6 +123,7 @@ import static org.apache.groovy.util.Arrays.concat;
import static org.codehaus.groovy.ast.tools.GeneralUtils.inSamePackage;
import static org.codehaus.groovy.reflection.ReflectionCache.isAssignableFrom;
import static org.codehaus.groovy.reflection.ReflectionUtils.parameterTypeMatches;
+import static org.codehaus.groovy.runtime.MetaClassHelper.castArgumentsToClassArray;
/**
* Allows methods to be dynamically added to existing classes at runtime
@@ -262,7 +264,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
*/
@Override
public List respondsTo(final Object obj, final String name, final Object[] argTypes) {
- Class[] classes = MetaClassHelper.castArgumentsToClassArray(argTypes);
+ Class[] classes = castArgumentsToClassArray(argTypes);
MetaMethod m = getMetaMethod(name, classes);
if (m != null) {
return Collections.singletonList(m);
@@ -322,7 +324,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
*/
@Override
public MetaMethod getStaticMetaMethod(final String name, final Object[] argTypes) {
- Class[] classes = MetaClassHelper.castArgumentsToClassArray(argTypes);
+ Class[] classes = castArgumentsToClassArray(argTypes);
return pickStaticMethod(name, classes);
}
@@ -331,7 +333,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
*/
@Override
public MetaMethod getMetaMethod(final String name, final Object[] argTypes) {
- Class[] classes = MetaClassHelper.castArgumentsToClassArray(argTypes);
+ Class[] classes = castArgumentsToClassArray(argTypes);
return pickMethod(name, classes);
}
@@ -926,7 +928,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
if (theClass != instanceKlazz && theClass.isAssignableFrom(instanceKlazz))
instanceKlazz = theClass;
- Class<?>[] argClasses = MetaClassHelper.castArgumentsToClassArray(arguments);
+ Class<?>[] argClasses = castArgumentsToClassArray(arguments);
MetaMethod method = findMixinMethod(methodName, argClasses);
if (method != null) {
@@ -1177,16 +1179,15 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
final Class<?> receiverClass = object.getClass();
if (isCallToSuper) {
if (null == lookup) throw mme;
- Class[] argTypes = MetaClassHelper.castArgumentsToClassArray(originalArguments);
- Method superMethod = findMethod(sender, methodName, argTypes);
- if (null == superMethod) throw mme;
- MethodHandle superMethodHandle;
- try {
- superMethodHandle = lookup.unreflectSpecial(superMethod, receiverClass);
- } catch (IllegalAccessException e) {
- throw mme;
- }
- cacheMethod(sender, superMethod);
+ MethodHandles.Lookup tmpLookup = lookup;
+ MethodHandle superMethodHandle = findMethod(sender, methodName, castArgumentsToClassArray(originalArguments), superMethod -> {
+ try {
+ return tmpLookup.unreflectSpecial(superMethod, receiverClass);
+ } catch (IllegalAccessException e) {
+ return null;
+ }
+ });
+ if (null == superMethodHandle) throw mme;
try {
return superMethodHandle.bindTo(object).invokeWithArguments(originalArguments);
} catch (Throwable t) {
@@ -1213,16 +1214,15 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
throw mme;
}
}
- Class[] argTypes = MetaClassHelper.castArgumentsToClassArray(originalArguments);
- Method thisMethod = findMethod(receiverClass, methodName, argTypes);
- if (null == thisMethod) throw mme;
- MethodHandle thisMethodHandle;
- try {
- thisMethodHandle = lookup.unreflect(thisMethod);
- } catch (IllegalAccessException e) {
- throw mme;
- }
- cacheMethod(receiverClass, thisMethod);
+ MethodHandles.Lookup tmpLookup = lookup;
+ MethodHandle thisMethodHandle = findMethod(receiverClass, methodName, castArgumentsToClassArray(originalArguments), thisMethod -> {
+ try {
+ return tmpLookup.unreflect(thisMethod);
+ } catch (IllegalAccessException e) {
+ return null;
+ }
+ });
+ if (null == thisMethodHandle) throw mme;
try {
return thisMethodHandle.bindTo(object).invokeWithArguments(originalArguments);
} catch (Throwable t) {
@@ -1231,24 +1231,35 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
}
}
- private static void cacheMethod(Class clazz, Method method) {
+ private static void cacheMethod(Class<?> clazz, Method method) {
SPECIAL_METHODS_MAP.get(clazz)
.computeIfAbsent(method.getName(), k -> Collections.newSetFromMap(new ConcurrentHashMap<>(2)))
.add(method);
}
- private static Method findMethod(Class clazz, String methodName, Class[] argTypes) {
+ private static MethodHandle findMethod(Class<?> clazz, String methodName, Class[] argTypes, Function<Method, MethodHandle> mhFunc) {
Set<Method> methods = SPECIAL_METHODS_MAP.get(clazz).get(methodName);
+ Method foundMethod = null;
if (null != methods) {
for (Method method : methods) {
if (parameterTypeMatches(method.getParameterTypes(), argTypes)) {
- return method;
+ foundMethod = method;
+ break;
}
}
}
- return doFindMethod(clazz, methodName, argTypes);
+ if (null == foundMethod) {
+ foundMethod = doFindMethod(clazz, methodName, argTypes);
+ if (null == foundMethod) return null;
+ cacheMethod(clazz, foundMethod);
+ }
+
+ MethodHandle methodHandle = mhFunc.apply(foundMethod);
+ if (null == methodHandle) return null;
+
+ return methodHandle;
}
private static Method doFindMethod(Class clazz, String messageName, Class[] argTypes) {