From 73b608608af94c8e6b0a1d1275bb16095d1dd97f Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 13 Feb 2024 09:57:30 +0200 Subject: [PATCH] [FIR] Optimize PendingDiagnosticsCollectorWithSuppress PendingDiagnosticsCollectorWithSuppress is a special diagnostic collector, which aggregates diagnostics reported during checking of some specific element before actually reporting them, so its workflow looks like this: - start checking some element; - all reported diagnostics go to `pendingDiagnosticsByFilePath` map; - all checkers done their jobs; - diagnostics from `pendingDiagnosticsByFilePath` go to the resulting map of all diagnostics (not all, only ones which lay inside the checked according to PSI); - processed diagnostics removed from `pendingDiagnosticsByFilePath` This approach works fine, but there was one problem with it: `pendingDiagnosticsByFilePath` is not just a list of diagnostic, but map of lists, grouped by the containing file. And only those lists actually get cleared. But if some list was completely emptied, it still remained in the original `pendingDiagnosticsByFilePath` map This led to the performance problem in case, where there are no actual diagnostics in the `pendingDiagnosticsByFilePath`, but the map itself is not empty but full of empty lists. So collector iterated over this map on each visiting of each element And after KT-58881 this problem was uncovered, as number of visits of elements was twiced (because now we iterate over the whole tree twice, with Common and Platform checkers) The fix is quite trivial -- if some list in `pendingDiagnosticsByFilePath` becomes empty, remove it from the map ^KT-65579 Fixed --- .../impl/PendingDiagnosticsCollectorWithSuppress.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/frontend.common/src/org/jetbrains/kotlin/diagnostics/impl/PendingDiagnosticsCollectorWithSuppress.kt b/compiler/frontend.common/src/org/jetbrains/kotlin/diagnostics/impl/PendingDiagnosticsCollectorWithSuppress.kt index 480ba716f4c..a52c47faed7 100644 --- a/compiler/frontend.common/src/org/jetbrains/kotlin/diagnostics/impl/PendingDiagnosticsCollectorWithSuppress.kt +++ b/compiler/frontend.common/src/org/jetbrains/kotlin/diagnostics/impl/PendingDiagnosticsCollectorWithSuppress.kt @@ -33,8 +33,11 @@ class PendingDiagnosticsCollectorWithSuppress(override val rawReport: (Boolean, element: AbstractKtSourceElement, context: DiagnosticContext? ) { + if (pendingDiagnosticsByFilePath.isEmpty()) return val commitEverything = context == null - for ((path, pendingList) in pendingDiagnosticsByFilePath) { + val pendingIterator = pendingDiagnosticsByFilePath.iterator() + while (pendingIterator.hasNext()) { + val (path, pendingList) = pendingIterator.next() val committedList = _diagnosticsByFilePath.getOrPut(path) { mutableListOf() } val iterator = pendingList.iterator() while (iterator.hasNext()) { @@ -56,6 +59,9 @@ class PendingDiagnosticsCollectorWithSuppress(override val rawReport: (Boolean, } } } + if (pendingList.isEmpty()) { + pendingIterator.remove() + } } } }