Since we put object's hash code in toString, we end up in putting
non-stable hash code to constant table, which leads to unstable
binaries.
#KTI-1193 Fixed
- `SymbolProviderMerger` encapsulates some boilerplate, which should
make `mergeDependencySymbolProvidersInto` easier to read and also much
easier to extend.
- This Caffeine cache is limited to classes for now, but may also be
tried with callables.
- The cache has a small memory footprint, but still avoids most of the
unnecessary index accesses. In my local tests, this approach takes 50%
of the time compared to no caches. A full cache has no performance
advantage over the limited-size cache in my local tests.
- `NullableCaffeineCache` wraps a Caffeine cache and allows storing
`null` values returned by the computation in the form of explicit
`NullValue`s in the cache.
- Our current FIR caches are based on `ConcurrentMap` and thereby do not
support size and lifetime limits out of the box. For example,
first-layer caches with a limited size can speed up access of the most
frequently used elements, while having a small memory footprint.
- Caffeine is a modern and well optimized caching library that allows us
to create thread-safe and performant caches with various size or
lifetime limits.
- The cache must support concurrency because session components such as
symbol providers may be accessed concurrently once parallel resolve in
the Analysis API has been implemented (see KT-55750). Caffeine caches
support concurrency.
- Getting top-level names from `declarationProvider` directly instead of
from subordinate symbol providers has a lot of potential for
performance, but the current performance of the index access is worse
than the iterative version because scopes aren't optimized yet.
- This commit prepares `LLFirCombinedKotlinSymbolProvider` for the
switch to getting top-level names from `declarationProvider`.
- `LLFirCombinedKotlinSymbolProvider` combines multiple
`LLFirProvider$SymbolProvider`s. Its advantages are: combined "names
in package" optimization, caching, combined index access, classpath
order disambiguation.
- Scopes can still be optimized with a combined scope instead of a naive
union scope.
^KT-57314 fixed
- If a `KtClassLikeDeclaration` or all `KtFile`s which contain a
callable are already known, they can now be passed to
`LLFirProvider$SymbolProvider` directly. This avoids index accesses in
`providerHelper`.
`MfvcNodeWithSubnodesImpl` has two problems:
- Naming: its name makes one think that the class is inherited from
`MfvcNode` and implements `MfvcNodeWithSubnodes`.However, both
statements are false.
- Semantics: the class only makes unnecessary indirection between its
properties and code of `MfvcNodeWithSubnodes` class
Using of Kotlin reflection for simple operations like bean management is very slow
First time initialization time: 261 ms for `copyBean(K2JVMCompilerArguments())`
Subsequent calls of `copyBean(K2JVMCompilerArguments())` take 1.7 ms per call
Unfortunately compiler argument handling is also used in Kotlin IntelliJ plugin
to parse facet settings. Big projects may have thousands of Kotlin facets
The same `ArgumentUtilsKt.copyProperties` frame is seen across various freezes:
IDEA-252440 2-3 minutes freeze on Kotlin project reimporting in last 203 eap
IDEA-253107 A lot of short freezes (1-3 sec) during Kotlin project development
KTIJ-23501 Make main run configuration detection lighter
KTIJ-22435 Unresponsive UI with 100% cpu
Reflection issue:
KT-56358 KClasses.getMemberProperties takes too much time
This commit replaces all reflection stuff with a simple code generation
Now `K2JVMCompilerArguments().clone()` goes to hard-to-measure time