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 2018/05/25 01:15:42 UTC
groovy git commit: GROOVY-8604: Cache the parameterized type for
better performance(closes #721)
Repository: groovy
Updated Branches:
refs/heads/master 90486ae10 -> ed71b35e7
GROOVY-8604: Cache the parameterized type for better performance(closes #721)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/ed71b35e
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/ed71b35e
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/ed71b35e
Branch: refs/heads/master
Commit: ed71b35e755090b1ae841e0e9888c0f61386d050
Parents: 90486ae
Author: sunlan <su...@apache.org>
Authored: Fri May 25 09:15:21 2018 +0800
Committer: sunlan <su...@apache.org>
Committed: Fri May 25 09:15:21 2018 +0800
----------------------------------------------------------------------
.../groovy/ast/tools/GenericsUtils.java | 65 ++++++++++++++++++--
.../stc/StaticTypeCheckingSupport.java | 2 +-
.../stc/StaticTypeCheckingVisitor.java | 2 +-
3 files changed, 62 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/ed71b35e/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
index 2e8a103..3d99e53 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
@@ -36,6 +36,8 @@ import org.codehaus.groovy.ast.stmt.EmptyStatement;
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.ResolveVisitor;
import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.runtime.memoize.EvictableCache;
+import org.codehaus.groovy.runtime.memoize.StampedCommonCache;
import org.codehaus.groovy.syntax.ParserException;
import org.codehaus.groovy.syntax.Reduction;
@@ -46,6 +48,7 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.getCorrectedClassNode;
@@ -658,13 +661,22 @@ public class GenericsUtils {
}
/**
- * Get the parameterized type by search the whole class hierarchy according to generics class and actual receiver
+ * Try to get the parameterized type from the cache.
+ * If no cached item found, cache and return the result of {@link #findParameterizedType(ClassNode, ClassNode)}
+ */
+ public static ClassNode findParameterizedTypeFromCache(final ClassNode genericsClass, final ClassNode actualType) {
+ return PARAMETERIZED_TYPE_CACHE.getAndPut(new ParameterizedTypeCacheKey(genericsClass, actualType), key -> findParameterizedType(key.getGenericsClass(), key.getActualType()));
+ }
+
+ /**
+ * Get the parameterized type by search the whole class hierarchy according to generics class and actual receiver.
+ * {@link #findParameterizedTypeFromCache(ClassNode, ClassNode)} is strongly recommended for better performance.
*
* @param genericsClass the generics class
- * @param actualReceiver the actual receiver
+ * @param actualType the actual type
* @return the parameterized type
*/
- public static ClassNode findParameterizedType(ClassNode genericsClass, ClassNode actualReceiver) {
+ public static ClassNode findParameterizedType(ClassNode genericsClass, ClassNode actualType) {
ClassNode parameterizedType = null;
if (null == genericsClass.getGenericsTypes()) {
@@ -673,8 +685,8 @@ public class GenericsUtils {
GenericsType[] declaringGenericsTypes = genericsClass.getGenericsTypes();
- List<ClassNode> classNodeList = new LinkedList<>(getAllSuperClassesAndInterfaces(actualReceiver));
- classNodeList.add(0, actualReceiver);
+ List<ClassNode> classNodeList = new LinkedList<>(getAllSuperClassesAndInterfaces(actualType));
+ classNodeList.add(0, actualType);
for (ClassNode cn : classNodeList) {
if (cn == genericsClass) {
@@ -720,4 +732,47 @@ public class GenericsUtils {
return superClassNodeList;
}
+
+ private static final EvictableCache<ParameterizedTypeCacheKey, ClassNode> PARAMETERIZED_TYPE_CACHE = new StampedCommonCache<>(128);
+ private static class ParameterizedTypeCacheKey {
+ private ClassNode genericsClass;
+ private ClassNode actualType;
+
+ public ParameterizedTypeCacheKey(ClassNode genericsClass, ClassNode actualType) {
+ this.genericsClass = genericsClass;
+ this.actualType = actualType;
+ }
+
+ public ClassNode getGenericsClass() {
+ return genericsClass;
+ }
+
+ public void setGenericsClass(ClassNode genericsClass) {
+ this.genericsClass = genericsClass;
+ }
+
+ public ClassNode getActualType() {
+ return actualType;
+ }
+
+ public void setActualType(ClassNode actualType) {
+ this.actualType = actualType;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ParameterizedTypeCacheKey cacheKey = (ParameterizedTypeCacheKey) o;
+
+ return genericsClass == cacheKey.genericsClass &&
+ actualType == cacheKey.actualType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(genericsClass, actualType);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/groovy/blob/ed71b35e/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index 316953b..cf92a6e 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1196,7 +1196,7 @@ public abstract class StaticTypeCheckingSupport {
}
private static Parameter[] makeRawTypes(Parameter[] params, ClassNode declaringClassForDistance, ClassNode actualReceiverForDistance) {
- Map<String, GenericsType> placeholderInfo = GenericsUtils.extractPlaceholders(GenericsUtils.findParameterizedType(declaringClassForDistance, actualReceiverForDistance));
+ Map<String, GenericsType> placeholderInfo = GenericsUtils.extractPlaceholders(GenericsUtils.findParameterizedTypeFromCache(declaringClassForDistance, actualReceiverForDistance));
Parameter[] newParam = new Parameter[params.length];
for (int i = 0; i < params.length; i++) {
http://git-wip-us.apache.org/repos/asf/groovy/blob/ed71b35e/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index efa7c26..9a13abe 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -620,7 +620,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
}
- ClassNode parameterizedType = GenericsUtils.findParameterizedType(fieldNode.getDeclaringClass(), typeCheckingContext.getEnclosingClassNode());
+ ClassNode parameterizedType = GenericsUtils.findParameterizedTypeFromCache(fieldNode.getDeclaringClass(), typeCheckingContext.getEnclosingClassNode());
if (null != parameterizedType) {
ClassNode originalType = fieldNode.getOriginType();
ClassNode actualType = findActualTypeByPlaceholderName(originalType.getUnresolvedName(), GenericsUtils.extractPlaceholders(parameterizedType));