From 5af0d0d828efcf46d38d99fbdaba4a8ba299157e Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 21 Mar 2012 12:49:53 +0400 Subject: [PATCH] revert optimisation no longer needed & soft reference resolved types --- .../impl/source/resolve/JavaResolveCache.java | 114 ++---------------- .../psi/impl/source/tree/JavaElementType.java | 3 +- .../tree/java/PsiBinaryExpressionImpl.java | 21 +--- 3 files changed, 15 insertions(+), 123 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java index 30c34b725ca9..613ea66a6794 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java @@ -26,22 +26,19 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.NotNullLazyKey; import com.intellij.psi.*; import com.intellij.psi.impl.AnyPsiChangeListener; -import com.intellij.psi.impl.DebugUtil; -import com.intellij.psi.impl.PsiManagerEx; import com.intellij.psi.impl.PsiManagerImpl; import com.intellij.psi.impl.source.PsiClassReferenceType; -import com.intellij.psi.impl.source.tree.TreeElement; import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.reference.SoftReference; import com.intellij.util.ConcurrencyUtil; import com.intellij.util.Function; -import com.intellij.util.Processor; import com.intellij.util.containers.ConcurrentWeakHashMap; -import com.intellij.util.containers.WeakHashMap; -import com.intellij.util.containers.WeakList; import com.intellij.util.messages.MessageBus; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.ref.Reference; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentMap; @@ -55,11 +52,7 @@ public class JavaResolveCache { return INSTANCE_KEY.getValue(project); } - private final ConcurrentMap myCalculatedTypes = new ConcurrentWeakHashMap(); - private final ConcurrentMap myCachedReferencesInPsiTypes = new ConcurrentWeakHashMap(); - // e.g. given FileOutputStream os, os2; - // PsiJavaCodeReferenceElement("FileOutputStream") -> [ PsiReferenceExpression("os"), PsiReferenceExpression("os2") ] - private final Map> myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere = new WeakHashMap>(); + private final ConcurrentMap> myCalculatedTypes = new ConcurrentWeakHashMap>(); private final Map myVarToConstValueMapPhysical; private final Map myVarToConstValueMapNonPhysical; @@ -86,39 +79,30 @@ public class JavaResolveCache { private void clearCaches(boolean isPhysical) { myCalculatedTypes.clear(); - myCachedReferencesInPsiTypes.clear(); - myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere.clear(); if (isPhysical) { myVarToConstValueMapPhysical.clear(); } myVarToConstValueMapNonPhysical.clear(); } - public boolean isTypeCached(@NotNull PsiExpression expr) { - return myCalculatedTypes.get(expr) != null; - } - @Nullable public PsiType getType(@NotNull T expr, @NotNull Function f) { - PsiType type = myCalculatedTypes.get(expr); + PsiType type = getCachedType(expr); if (type == null) { type = f.fun(expr); if (type == null) { type = TypeConversionUtil.NULL_TYPE; } - PsiType stored = ConcurrencyUtil.cacheOrGet(myCalculatedTypes, expr, type); + SoftReference ref = new SoftReference(type); + Reference storedRef = ConcurrencyUtil.cacheOrGet(myCalculatedTypes, expr, ref); - if (stored == type && DebugUtil.DO_EXPENSIVE_CHECKS) { - registerDiagnosticsHooks(expr, type); - } - - type = stored; + type = storedRef.get(); } if (!type.isValid()) { if (expr.isValid()) { PsiJavaCodeReferenceElement refInside = type instanceof PsiClassReferenceType ? ((PsiClassReferenceType)type).getReference() : null; - String typeinfo = type + " (" + type.getClass() + ")" + (refInside == null ? "" : "; ref inside: "+refInside + " ("+refInside.getClass()+") valid:"+refInside.isValid()); + @NonNls String typeinfo = type + " (" + type.getClass() + ")" + (refInside == null ? "" : "; ref inside: "+refInside + " ("+refInside.getClass()+") valid:"+refInside.isValid()); LOG.error("Type is invalid: " + typeinfo + "; expr: '" + expr + "' (" + expr.getClass() + ") is valid"); } else { @@ -129,83 +113,9 @@ public class JavaResolveCache { return type == TypeConversionUtil.NULL_TYPE ? null : type; } - private void registerDiagnosticsHooks(T expr, PsiType type) { - if (type instanceof PsiClassReferenceType) { - PsiJavaCodeReferenceElement reference = ((PsiClassReferenceType)type).getReference(); - ConcurrencyUtil.cacheOrGet(myCachedReferencesInPsiTypes, reference, type); - synchronized (myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere) { - WeakList refsTo = myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere.get(reference); - if (refsTo==null) { - refsTo = new WeakList(); - myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere.put(reference, refsTo); - } - refsTo.add(expr); - } - final PsiFile dummyHolder = reference.getContainingFile(); - if (dummyHolder != null && !dummyHolder.isPhysical()) { - PsiElement physicalContext = dummyHolder.getContext(); - PsiFile physicalFile; - if (physicalContext != null && - (physicalFile = physicalContext.getContainingFile()) != null && - physicalFile.getVirtualFile() != null && - !((PsiManagerEx)dummyHolder.getManager()).isAssertOnFileLoading(physicalFile.getVirtualFile())) { - DebugUtil.trackInvalidation(physicalContext, "dummy holder was invalidated", new Processor() { - @Override - public boolean process(PsiElement element) { - DebugUtil.onInvalidated((TreeElement)dummyHolder.getNode()); - return true; - } - }); - } - } - - DebugUtil.trackInvalidation(reference, "Reference inside PsiClassReferenceType was invalidated", new Processor() { - @Override - public boolean process(PsiElement element) { - PsiType cached = myCalculatedTypes.get(element); - if (cached != null) { - LOG.error(element + " (inside ref) is invalid and yet it is still cached: " + cached); - } - PsiType cachedRef = myCachedReferencesInPsiTypes.get(element); - if (cachedRef != null) { - LOG.error(element + " (inside ref) is invalid and yet it is still cached in ref cache: " + cachedRef); - } - - - synchronized (myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere) { - WeakList refsTo = myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere.get(element); - if (refsTo != null) { - for (PsiElement ref : refsTo) { - PsiType cachedT = myCalculatedTypes.get(ref); - if (cachedT != null && !cachedT.isValid()) { - LOG.error("During invalidation of " + element + " ("+element.getClass()+")"+ - " cached type " + cachedT + " of the ref "+ref+" ("+ref.getClass()+")"+ - " became invalid and yet it is still cached" - ); - } - } - } - } - - return true; - } - }); - } - DebugUtil.trackInvalidation(expr, "Expression invalidated", new Processor() { - @Override - public boolean process(PsiElement element) { - PsiType cached = myCalculatedTypes.get(element); - if (cached != null) { - LOG.error(element + " is invalid and yet it is still cached: " + cached); - } - - PsiType cachedRef = myCachedReferencesInPsiTypes.get(element); - if (cachedRef != null) { - LOG.error(element + " is invalid and yet it is still cached (inside PsiType): " + cachedRef); - } - return true; - } - }); + private PsiType getCachedType(T expr) { + Reference reference = myCalculatedTypes.get(expr); + return reference == null ? null : reference.get(); } @Nullable diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java index 1dd8689c4fd0..69476e9ef24d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java @@ -41,8 +41,7 @@ public interface JavaElementType { private final Constructor myConstructor; private JavaCompositeElementType(@NonNls final String debugName, final Class nodeClass) { - super(debugName); - myConstructor = ReflectionUtil.getDefaultConstructor(nodeClass); + this(debugName, nodeClass, false); } private JavaCompositeElementType(@NonNls final String debugName, final Class nodeClass, final boolean leftBound) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiBinaryExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiBinaryExpressionImpl.java index e0e03a36e1d1..561b54560263 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiBinaryExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiBinaryExpressionImpl.java @@ -17,7 +17,6 @@ package com.intellij.psi.impl.source.tree.java; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.progress.ProgressIndicatorProvider; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.JavaResolveCache; import com.intellij.psi.impl.source.tree.ChildRole; @@ -33,6 +32,8 @@ import org.jetbrains.annotations.NotNull; public class PsiBinaryExpressionImpl extends ExpressionPsiElement implements PsiBinaryExpression { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiBinaryExpressionImpl"); + /** used via reflection in {@link com.intellij.psi.impl.source.tree.JavaElementType.JavaCompositeElementType#JavaCompositeElementType(java.lang.String, java.lang.Class)} */ + @SuppressWarnings("UnusedDeclaration") public PsiBinaryExpressionImpl() { this(JavaElementType.BINARY_EXPRESSION); } @@ -79,24 +80,6 @@ public class PsiBinaryExpressionImpl extends ExpressionPsiElement implements Psi PsiType type = TypeConversionUtil.calcTypeForBinaryExpression(null, rType, sign, false); if (type != TypeConversionUtil.NULL_TYPE) return type; - if (lOperand instanceof PsiBinaryExpressionImpl && !JavaResolveCache.getInstance(param.getProject()).isTypeCached(lOperand)) { - // cache all intermediate expression types from bottom up - PsiBinaryExpressionImpl topLevel = param; - PsiElement element = param; - while (element instanceof PsiBinaryExpressionImpl) { - topLevel = (PsiBinaryExpressionImpl)element; - element = element.getParent(); - } - topLevel.accept(new JavaRecursiveElementWalkingVisitor() { - @Override - protected void elementFinished(PsiElement element) { - if (element instanceof PsiExpression) { - ProgressIndicatorProvider.checkCanceled(); - ((PsiExpression)element).getType(); - } - } - }); - } PsiType lType = lOperand.getType(); return TypeConversionUtil.calcTypeForBinaryExpression(lType, rType, sign, true); }