From 3bb38bf874d2409438bbde4c9bc41dee8a5b2921 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Sun, 5 Feb 2017 18:30:58 -0800 Subject: [PATCH] Bug 509898 - IndexFileSet.containsDeclaration is slow and is causing UI freezes Added debug logging of time spent in IndexFileSet.containsDeclaration. Change-Id: I4523abac4f56c4284ef03da5e82fd39b6dc1d412 --- .../core/dom/parser/ASTTranslationUnit.java | 9 +++++++++ .../cdt/internal/core/index/IndexFileSet.java | 17 +++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java index 24f88372e94..9859d4dc144 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java @@ -47,6 +47,7 @@ import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.parser.ISignificantMacros; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.index.IndexBasedFileContentProvider; +import org.eclipse.cdt.internal.core.index.IndexFileSet; import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver; import org.eclipse.cdt.internal.core.parser.scanner.ISkippedIndexedFilesListener; import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent; @@ -459,6 +460,14 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat return PROCESS_CONTINUE; } }); + + if (IndexFileSet.sDEBUG_INDEX_FILE_SET && fIndexFileSet != null && fASTFileSet != null) { + long t = ((IndexFileSet) fIndexFileSet).getTimingContainsDeclarationNanos() + + ((IndexFileSet) fASTFileSet).getTimingContainsDeclarationNanos(); + String forName = fOriginatingTranslationUnit == null ? + "" : " for " + fOriginatingTranslationUnit.getElementName(); //$NON-NLS-1$ //$NON-NLS-2$ + System.out.println(String.format("IndexFileSet.containsDeclaration%s took %.2g ms", forName, t / 1.e6)); //$NON-NLS-1$ + } } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileSet.java index 4a8a92036dd..f713d0cf87a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileSet.java @@ -35,6 +35,7 @@ public class IndexFileSet implements IIndexFileSet { private IIndexFileSet fInverse; private final HashMap fSubSets= new HashMap<>(); private final Map fDeclarationContainmentCache = new HashMap<>(); + private long timingContainsDeclarationNanos; public IndexFileSet() { } @@ -69,6 +70,16 @@ public class IndexFileSet implements IIndexFileSet { if (cachedValue != null) return cachedValue; + long startTime = sDEBUG_INDEX_FILE_SET ? System.nanoTime() : 0; + boolean contains = computeContainsDeclaration(binding); + fDeclarationContainmentCache.put(binding, contains); + if (sDEBUG_INDEX_FILE_SET) { + timingContainsDeclarationNanos += System.nanoTime() - startTime; + } + return contains; + } + + private boolean computeContainsDeclaration(IIndexBinding binding) { int iterationCount = 0; for (Map.Entry entry : fSubSets.entrySet()) { IIndexFragment fragment = entry.getKey(); @@ -83,7 +94,6 @@ public class IndexFileSet implements IIndexFileSet { while ((nameRecord = nameIterator.next()) != 0) { long fileRecord = PDOMName.getFileRecord(db, nameRecord); if (pdomFileSet.containsFile(fileRecord)) { - fDeclarationContainmentCache.put(binding, true); if (sDEBUG_INDEX_FILE_SET && iterationCount >= 200) { System.out.println( String.format("IndexFileSet: %s (%s) found after %d iterations", //$NON-NLS-1$ @@ -113,10 +123,13 @@ public class IndexFileSet implements IIndexFileSet { binding.getClass().getSimpleName(), iterationCount)); } - fDeclarationContainmentCache.put(binding, false); return false; } + public long getTimingContainsDeclarationNanos() { + return timingContainsDeclarationNanos; + } + @Override public boolean containsNonLocalDeclaration(IBinding binding, IIndexFragment ignore) { for (Map.Entry entry : fSubSets.entrySet()) {