From 3e4b897664aaab85bc75b8cd267d11d31fc5b221 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Tue, 24 Jan 2017 17:04:34 +0300 Subject: [PATCH] javac ast indices: do not use DirtyScopeHolder lock in VFS listener (IDEA-167028) --- .../backwardRefs/DirtyScopeHolder.java | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/backwardRefs/DirtyScopeHolder.java b/java/compiler/impl/src/com/intellij/compiler/backwardRefs/DirtyScopeHolder.java index 1a011e64c1f6..8b91e281a695 100644 --- a/java/compiler/impl/src/com/intellij/compiler/backwardRefs/DirtyScopeHolder.java +++ b/java/compiler/impl/src/com/intellij/compiler/backwardRefs/DirtyScopeHolder.java @@ -57,12 +57,14 @@ public class DirtyScopeHolder extends UserDataHolderBase { private final PsiDocumentManager myPsiDocManager; private final Object myLock = new Object(); - private final Set myVFSChangedModules = ContainerUtil.newHashSet(); // guarded by myLock - private final Set myChangedModulesDuringCompilation = ContainerUtil.newHashSet(); // guarded by myLock + @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized") + private Set myChangedBeforeCompilationModules; // guarded by myVFSChangedModules private final List myExcludedDescriptions = new SmartList<>(); // guarded by myLock private boolean myCompilationPhase; // guarded by myLock private volatile GlobalSearchScope myExcludedFilesScope; // calculated outside myLock + private final Set myCompilationAffectedModules = ContainerUtil.newConcurrentSet(); // used outside myLock + private final Set myVFSChangedModules = Collections.synchronizedSet(ContainerUtil.newTroveSet()); // used outside myLock public DirtyScopeHolder(@NotNull CompilerReferenceServiceImpl service, @@ -99,6 +101,7 @@ public class DirtyScopeHolder extends UserDataHolderBase { Collections.addAll(myExcludedDescriptions, CompilerConfiguration.getInstance(myService.getProject()).getExcludedEntriesConfiguration().getExcludeEntryDescriptions()); myExcludedFilesScope = null; myCompilationAffectedModules.clear(); + myChangedBeforeCompilationModules = getAndClearVfsChangedModules(); } } @@ -113,7 +116,7 @@ public class DirtyScopeHolder extends UserDataHolderBase { return ModuleManager.getInstance(project).getModules(); }); if (modules == null) return; - ContainerUtil.addAll(myVFSChangedModules, modules); + Collections.addAll(myVFSChangedModules, modules); } }); } @@ -129,7 +132,7 @@ public class DirtyScopeHolder extends UserDataHolderBase { return myCompilationAffectedModules.stream().map(moduleManager::findModuleByName).collect(Collectors.toList()); }); if (compiledModules == null) return; - myVFSChangedModules.removeAll(compiledModules); + myChangedBeforeCompilationModules.removeAll(compiledModules); }); } @@ -139,10 +142,10 @@ public class DirtyScopeHolder extends UserDataHolderBase { myCompilationPhase = false; action.run(); myCompilationAffectedModules.clear(); - myVFSChangedModules.addAll(myChangedModulesDuringCompilation); - myChangedModulesDuringCompilation.clear(); descriptions = myExcludedDescriptions.toArray(new ExcludeEntryDescription[myExcludedDescriptions.size()]); myExcludedDescriptions.clear(); + myVFSChangedModules.addAll(myChangedBeforeCompilationModules); + myChangedBeforeCompilationModules = null; } myExcludedFilesScope = ExcludedFromCompileFilesUtil.getExcludedFilesScope(descriptions, myService.getFileTypes(), myService.getProject(), myService.getFileIndex()); @@ -172,8 +175,8 @@ public class DirtyScopeHolder extends UserDataHolderBase { } @NotNull - Set getAllDirtyModules() { - final Set dirtyModules = new THashSet<>(myVFSChangedModules); + private Set getAllDirtyModules() { + final Set dirtyModules = ContainerUtil.newTroveSet(myVFSChangedModules); for (Document document : myFileDocManager.getUnsavedDocuments()) { final VirtualFile file = myFileDocManager.getFile(document); if (file == null) continue; @@ -240,13 +243,7 @@ public class DirtyScopeHolder extends UserDataHolderBase { void fileChanged(VirtualFile file) { final Module module = getModuleForSourceContentFile(file); if (module != null) { - synchronized (myLock) { - if (myCompilationPhase) { - myChangedModulesDuringCompilation.add(module); - } else { - myVFSChangedModules.add(module); - } - } + myVFSChangedModules.add(module); } } }, myService.getProject()); @@ -259,6 +256,14 @@ public class DirtyScopeHolder extends UserDataHolderBase { return null; } + private Set getAndClearVfsChangedModules() { + synchronized (myVFSChangedModules) { + final THashSet result = ContainerUtil.newTroveSet(myVFSChangedModules); + myVFSChangedModules.clear(); + return result; + } + } + @TestOnly @NotNull public Set getAllDirtyModulesForTest() {