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/19 02:58:44 UTC
[groovy] branch danielsun/tweak-build updated: Cache the special
methods
This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch danielsun/tweak-build
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/danielsun/tweak-build by this push:
new adabf7c Cache the special methods
adabf7c is described below
commit adabf7c6631685e7fd2498c8ab1f27080fcdbadc
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sat Jun 19 10:58:26 2021 +0800
Cache the special methods
---
src/main/java/groovy/lang/MetaClassImpl.java | 38 +++++++++++++++++++---
.../groovy/reflection/ReflectionUtils.java | 37 ++++++++++++---------
2 files changed, 55 insertions(+), 20 deletions(-)
diff --git a/src/main/java/groovy/lang/MetaClassImpl.java b/src/main/java/groovy/lang/MetaClassImpl.java
index 83a0e1d..1bf0d30 100644
--- a/src/main/java/groovy/lang/MetaClassImpl.java
+++ b/src/main/java/groovy/lang/MetaClassImpl.java
@@ -121,6 +121,7 @@ import static java.lang.Character.isUpperCase;
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;
/**
* Allows methods to be dynamically added to existing classes at runtime
@@ -1152,6 +1153,13 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
private MethodHolder() {}
}
+ private static final ClassValue<Set<Method>> SPECIAL_METHODS_MAP = new ClassValue<Set<Method>>() {
+ @Override
+ protected Set<Method> computeValue(Class<?> type) {
+ return Collections.newSetFromMap(new ConcurrentHashMap<>());
+ }
+ };
+
private Object doInvokeMethodFallback(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, MissingMethodException mme) {
MethodHandles.Lookup lookup = null;
if (object instanceof GroovyObject) {
@@ -1163,7 +1171,8 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
final Class<?> receiverClass = object.getClass();
if (isCallToSuper) {
if (null == lookup) throw mme;
- Method superMethod = findMethod(sender, methodName, originalArguments);
+ Class[] argTypes = MetaClassHelper.castArgumentsToClassArray(originalArguments);
+ Method superMethod = findMethod(sender, methodName, argTypes);
if (null == superMethod) throw mme;
MethodHandle superMethodHandle;
try {
@@ -1171,6 +1180,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
} catch (IllegalAccessException e) {
throw mme;
}
+ cacheMethod(sender, superMethod);
try {
return superMethodHandle.bindTo(object).invokeWithArguments(originalArguments);
} catch (Throwable t) {
@@ -1203,7 +1213,8 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
throw mme;
}
}
- Method thisMethod = findMethod(receiverClass, methodName, originalArguments);
+ Class[] argTypes = MetaClassHelper.castArgumentsToClassArray(originalArguments);
+ Method thisMethod = findMethod(receiverClass, methodName, argTypes);
if (null == thisMethod) throw mme;
MethodHandle thisMethodHandle;
try {
@@ -1211,6 +1222,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
} catch (IllegalAccessException e) {
throw mme;
}
+ cacheMethod(receiverClass, thisMethod);
try {
return thisMethodHandle.bindTo(object).invokeWithArguments(originalArguments);
} catch (Throwable t) {
@@ -1219,10 +1231,26 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
}
}
- private static Method findMethod(Class clazz, String messageName, Object[] messageArguments) {
- Class[] parameterTypes = MetaClassHelper.castArgumentsToClassArray(messageArguments);
+ private static void cacheMethod(Class clazz, Method method) {
+ Set<Method> methods = SPECIAL_METHODS_MAP.get(clazz);
+ methods.add(method);
+ }
+
+ private static Method findMethod(Class clazz, String messageName, Class[] argTypes) {
+ Set<Method> methods = SPECIAL_METHODS_MAP.get(clazz);
+
+ for (Method method : methods) {
+ if (method.getName().equals(messageName) && parameterTypeMatches(method.getParameterTypes(), argTypes)) {
+ return method;
+ }
+ }
+
+ return doFindMethod(clazz, messageName, argTypes);
+ }
+
+ private static Method doFindMethod(Class clazz, String messageName, Class[] argTypes) {
for (Class<?> c = clazz; null != c; c = c.getSuperclass()) {
- List<Method> declaredMethodList = ReflectionUtils.getDeclaredMethods(c, messageName, parameterTypes);
+ List<Method> declaredMethodList = ReflectionUtils.getDeclaredMethods(c, messageName, argTypes);
if (!declaredMethodList.isEmpty()) {
Method superMethod = declaredMethodList.get(0);
if (Modifier.isAbstract(superMethod.getModifiers())) {
diff --git a/src/main/java/org/codehaus/groovy/reflection/ReflectionUtils.java b/src/main/java/org/codehaus/groovy/reflection/ReflectionUtils.java
index e83b3d9..1adf13a 100644
--- a/src/main/java/org/codehaus/groovy/reflection/ReflectionUtils.java
+++ b/src/main/java/org/codehaus/groovy/reflection/ReflectionUtils.java
@@ -145,35 +145,42 @@ public class ReflectionUtils {
private static List<Method> doGetMethods(final Class<?> type, final String name, final Class<?>[] parameterTypes, final Function<? super Class<?>, ? extends Method[]> f) {
List<Method> methodList = new LinkedList<>();
- out:
for (Method m : f.apply(type)) {
if (!m.getName().equals(name)) {
continue;
}
-
Class<?>[] methodParameterTypes = m.getParameterTypes();
- if (methodParameterTypes.length != parameterTypes.length) {
+ if (!parameterTypeMatches(methodParameterTypes, parameterTypes)) {
continue;
}
- for (int i = 0, n = methodParameterTypes.length; i < n; i += 1) {
- Class<?> parameterType = TypeUtil.autoboxType(parameterTypes[i]);
- if (null == parameterType) {
- continue out;
- }
-
- Class<?> methodParameterType = TypeUtil.autoboxType(methodParameterTypes[i]);
- if (!methodParameterType.isAssignableFrom(parameterType)) {
- continue out;
- }
- }
-
methodList.add(m);
}
return methodList;
}
+ public static boolean parameterTypeMatches(final Class<?>[] parameterTypes, final Class<?>[] argTypes) {
+ if (parameterTypes.length != argTypes.length) {
+ return false;
+ }
+
+ for (int i = 0, n = parameterTypes.length; i < n; i += 1) {
+ Class<?> argType = argTypes[i];
+ Class<?> parameterType = parameterTypes[i];
+
+ if (parameterType == argType) continue;
+
+ Class<?> boxedArgType = TypeUtil.autoboxType(argType);
+ Class<?> boxedParameterType = TypeUtil.autoboxType(parameterType);
+ if (!boxedParameterType.isAssignableFrom(boxedArgType)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
public static boolean checkCanSetAccessible(final AccessibleObject accessibleObject, final Class<?> caller) {
return VM_PLUGIN.checkCanSetAccessible(accessibleObject, caller);
}