From commits-return-6754-archive-asf-public=cust-asf.ponee.io@groovy.apache.org Fri May 25 03:21:03 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id 80855180636 for ; Fri, 25 May 2018 03:21:02 +0200 (CEST) Received: (qmail 68507 invoked by uid 500); 25 May 2018 01:21:01 -0000 Mailing-List: contact commits-help@groovy.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@groovy.apache.org Delivered-To: mailing list commits@groovy.apache.org Received: (qmail 68489 invoked by uid 99); 25 May 2018 01:21:01 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 25 May 2018 01:21:01 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 86196E0B37; Fri, 25 May 2018 01:21:01 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: sunlan@apache.org To: commits@groovy.apache.org Message-Id: <13b5745a033849ab97ca3eafde412516@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: groovy git commit: GROOVY-8604: Cache the parameterized type for better performance(closes #721) Date: Fri, 25 May 2018 01:21:01 +0000 (UTC) Repository: groovy Updated Branches: refs/heads/GROOVY_2_5_X b492c874f -> b9ddf6b5c GROOVY-8604: Cache the parameterized type for better performance(closes #721) (cherry picked from commit 333dc40) Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/b9ddf6b5 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/b9ddf6b5 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/b9ddf6b5 Branch: refs/heads/GROOVY_2_5_X Commit: b9ddf6b5cf68d9c8504750ac2d857451aa403ff0 Parents: b492c87 Author: sunlan Authored: Fri May 25 09:15:21 2018 +0800 Committer: sunlan Committed: Fri May 25 09:20:56 2018 +0800 ---------------------------------------------------------------------- .../groovy/ast/tools/GenericsUtils.java | 70 ++++++++++++++++++-- .../stc/StaticTypeCheckingSupport.java | 2 +- .../stc/StaticTypeCheckingVisitor.java | 2 +- 3 files changed, 67 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/b9ddf6b5/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..906aab6 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.ConcurrentCommonCache; +import org.codehaus.groovy.runtime.memoize.EvictableCache; 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,27 @@ 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), new EvictableCache.ValueProvider() { + @Override + public ClassNode provide(ParameterizedTypeCacheKey key) { + return 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 +690,8 @@ public class GenericsUtils { GenericsType[] declaringGenericsTypes = genericsClass.getGenericsTypes(); - List classNodeList = new LinkedList<>(getAllSuperClassesAndInterfaces(actualReceiver)); - classNodeList.add(0, actualReceiver); + List classNodeList = new LinkedList<>(getAllSuperClassesAndInterfaces(actualType)); + classNodeList.add(0, actualType); for (ClassNode cn : classNodeList) { if (cn == genericsClass) { @@ -720,4 +737,47 @@ public class GenericsUtils { return superClassNodeList; } + + private static final EvictableCache PARAMETERIZED_TYPE_CACHE = new ConcurrentCommonCache<>(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/b9ddf6b5/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 5843aa3..d0c6086 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java @@ -1190,7 +1190,7 @@ public abstract class StaticTypeCheckingSupport { } private static Parameter[] makeRawTypes(Parameter[] params, ClassNode declaringClassForDistance, ClassNode actualReceiverForDistance) { - Map placeholderInfo = GenericsUtils.extractPlaceholders(GenericsUtils.findParameterizedType(declaringClassForDistance, actualReceiverForDistance)); + Map 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/b9ddf6b5/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 71d3298..d2371b4 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -616,7 +616,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));