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 02:03:17 UTC
[groovy] 01/01: Trivial tweak: avoid creating method handle
repeatedly
This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch danielsun/trivial-tweak-20210626
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 23ca7082eee393b6d9a5e00dfce5270a80686f14
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sat Jun 26 10:02:09 2021 +0800
Trivial tweak: avoid creating method handle repeatedly
---
src/main/java/groovy/lang/MetaClassImpl.java | 88 +++++++++++++++-------------
1 file changed, 47 insertions(+), 41 deletions(-)
diff --git a/src/main/java/groovy/lang/MetaClassImpl.java b/src/main/java/groovy/lang/MetaClassImpl.java
index e8068f2..1f23830 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) {
@@ -1159,9 +1161,9 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
private MethodHandleHolder() {}
}
- private static final ClassValue<Map<String, Set<Method>>> SPECIAL_METHODS_MAP = new ClassValue<Map<String, Set<Method>>>() {
+ private static final ClassValue<Map<Method, MethodHandle>> SPECIAL_METHODS_MAP = new ClassValue<Map<Method, MethodHandle>>() {
@Override
- protected Map<String, Set<Method>> computeValue(Class<?> type) {
+ protected Map<Method, MethodHandle> computeValue(Class<?> type) {
return new ConcurrentHashMap<>(4);
}
};
@@ -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);
+ final MethodHandles.Lookup tmpLookup = lookup;
+ MethodHandle superMethodHandle = findMethodHandle(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);
+ final MethodHandles.Lookup tmpLook = lookup;
+ MethodHandle thisMethodHandle = findMethodHandle(receiverClass, methodName, castArgumentsToClassArray(originalArguments), thisMethod -> {
+ try {
+ return tmpLook.unreflect(thisMethod);
+ } catch (IllegalAccessException e) {
+ return null;
+ }
+ });
+ if (null == thisMethodHandle) throw mme;
try {
return thisMethodHandle.bindTo(object).invokeWithArguments(originalArguments);
} catch (Throwable t) {
@@ -1231,27 +1231,33 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
}
}
- 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) {
- Set<Method> methods = SPECIAL_METHODS_MAP.get(clazz).get(methodName);
+ private static MethodHandle findMethodHandle(Class<?> clazz, String methodName, Class[] argTypes, Function<? super Method, ? extends MethodHandle> mhFunc) {
+ Map<Method, MethodHandle> methods = SPECIAL_METHODS_MAP.get(clazz);
- if (null != methods) {
- for (Method method : methods) {
- if (parameterTypeMatches(method.getParameterTypes(), argTypes)) {
- return method;
- }
+ Method foundMethod = null;
+ for (Map.Entry<Method, MethodHandle> entry : methods.entrySet()) {
+ Method method = entry.getKey();
+ if (parameterTypeMatches(method.getParameterTypes(), argTypes)) {
+ foundMethod = method;
+ break;
}
}
- return doFindMethod(clazz, methodName, argTypes);
+ if (null == foundMethod) {
+ foundMethod = doFindMethod(clazz, methodName, argTypes);
+ }
+
+ if (null == foundMethod) return null;
+
+ MethodHandle methodHandle = mhFunc.apply(foundMethod);
+ if (null != methodHandle) {
+ methods.put(foundMethod, methodHandle);
+ }
+
+ return methodHandle;
}
- private static Method doFindMethod(Class clazz, String messageName, Class[] 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, argTypes);
if (!declaredMethodList.isEmpty()) {