Commit Graph

452 Commits

Author SHA1 Message Date
Alexander Udalov 22329c7124 Do not sort fake overrides in DescriptorSerializer
Sorting invokes descriptor renderer, so the fewer descriptors we are
sorting, the better. This helps to save a few percent of compilation
time in a synthetic project from KT-52326.
2022-05-31 13:22:13 +02:00
Hung Nguyen 08e6eb07c1 [New IC] Reduce memory usage of classpath snapshot cache
- Remove soft references that are too old.
 - Compute memory usage based on Runtime.totalMemory() instead of
   Runtime.maxMemory() as the latter is not reliable.
 - Remove debug logs that haven't proved to be useful.
 - Collect metrics on the number of cache hits (in addition to cache
   misses).

#KT-52329 In Progress

[New IC] Reduce memory usage of classpath snapshot cache

Use object interning for commonly shared objects. These include:
  - supertypes of classes
  - package names of classes

One experiment showed that with the above optimization, memory usage was
reduced from 660 MB down to 280 MB (+ 4 MB for the interning pool).

More aggressive object interning didn't reduce memory usage much
further, but would increase interning overhead and code complexity, so
we didn't do this to more objects.

Note that this commit optimizes the size of classpath snapshots in
memory, not their serialized data on disk. (I attempted the latter,
but the size was only reduced from 160 MB down to 130 MB, while the code
complexity became much higher as multiple interning pools would need to
be stored to disk and later loaded from disk, each per classpath entry
snapshot or shrunk classpath snapshot.)

#KT-52329 Fixed
2022-05-25 12:59:20 +03:00
Hung Nguyen 9eb3c7ed76 [New IC] Optimize Java class snapshotting with ASM ClassWriter
To snapshot a Java class (+ its fields and methods), previously we used
Gson to serialize a class field/method to a string via reflection, and
hash that string.

We now use an ASM ClassWriter to write a placeholder class containing
the field/method of interest and hash the bytecode of that class.

One experiment showed that this new approach is ~10 times faster than
the previous approach (140s down to 16s when snapshotting 600 jars).

Test: Updated expectation files for JavaClassSnapshotterTest unit tests
      + Existing integration tests to prevent regression

^KT-52141 In Progress
2022-04-27 15:26:26 +00:00
Hung Nguyen 6d3e679a59 Implement cache eviction for classpath snapshot cache
Implement an in-memory cache that uses a combination of strong
references and `SoftReference`s so that it adapts to memory
availability.

Cache eviction is currently performed after loading a classpath snapshot
(this can be changed later if necessary).

Evicted cache entries' values will be converted from strong references
into `SoftReference`s so that they can still be used for as long as the
JVM allows them.

There are 2 types of cache eviction:
  - Least recently used: Oldest entries will be evicted
  - Memory usage limit: If memory is limited, all entries will be
    evicted

Test: Added InMemoryCacheWithEvictionTest unit test

^KT-51978 In Progress
2022-04-21 17:34:01 +00:00
Aleksei.Cherepanov 3d8f140d6b [JPS] Fix incremental build after changing Java enum used in Kotlin when
EnumWhenTracker implemented for tracking changed java enum class items, that used in kotlin when expression.

#KT-47824 Fixed
2022-04-19 18:39:41 +00:00
Aleksei.Cherepanov e0029b14ee Rebuild module on plugin classpaths change
Add another one reason for rebuild: if pluginClasspaths was changed or even its jar content, module will be marked for rebuild

Merge-request: KT-MR-5839
Merged-by: Aleksei Cherepanov <aleksei.cherepanov@jetbrains.com>
2022-04-18 11:06:15 +00:00
Ilya Chernikov c4a29651b0 FIR IC: fix test with behavior different from non-tight cycle variants 2022-03-30 08:34:51 +00:00
Ilya Chernikov 5abdf93d3b IC: Add IC test with fix on rename file with only class inside
"fails" on JS and JPS tests - the IC logic there is less precise.
2022-03-30 08:32:17 +00:00
Ilya Chernikov 6b61488099 Implement IC caches changes detection logic over frontend metadata 2022-03-30 08:31:02 +00:00
Hung Nguyen bd8f49c5d6 KT-45777: Count cache misses when loading classpath snapshot
to get more insights into the build performance of that step.

^KT-45777 In Progress
2022-03-29 11:36:41 +00:00
Hung Nguyen d70dbf3146 KT-45777: Add debug log messages for classpath snapshot feature
Also clean up classpath snapshot shrinking a bit to make it clearer.

^KT-45777 In Progress
2022-03-29 11:36:40 +00:00
Evgeniy.Zhelenskiy 28bf83ceac [IR] Unite inline class and multi-field value class representation
#KT-1179
2022-03-24 11:38:43 +00:00
Evgeniy.Zhelenskiy 282ab398c6 [IR] Generify lowerings
#KT-1179
2022-03-24 11:38:42 +00:00
nataliya.valtman c38dd1c004 Fix unstable testIncrementalCompilationAfterCacheHit test 2022-03-14 20:08:14 +03:00
Hung Nguyen 5f1cf34c79 KT-45777: Take coarse-grained snapshots of external libraries
to reduce the size of the snapshots.

- Track metrics for Gradle classpath snapshot artifact transform
- Format size metrics so it's more readable

^KT-45777 In Progress
2022-03-11 17:44:25 +01:00
Hung Nguyen d2193f3873 KT-45777: Allow 2 levels of granularity when tracking changes
1. CLASS_LEVEL: allows tracking whether a .class file has changed
     without tracking what specific parts of the .class file (e.g.,
     fields or methods) have changed.

  2. CLASS_MEMBER_LEVEL: allows tracking not only whether a .class file
     has changed but also what specific parts of the .class file (e.g.,
     fields or methods) have changed.

 The idea is that for better performance we will use CLASS_LEVEL for
 classpath entries that are usually unchanged, and CLASS_MEMBER_LEVEL
 for classpath entries that are frequently changed. We'll work out the
 specifics in a following commit after some measurements.

Support running kotlinc on Windows in ClasspathSnapshotTestCommon
Also add tests for different Kotlin class kinds.
Add unit tests for CLASS_LEVEL snapshotting and diffing

Test: Updated ClasspathSnapshotterTest + ClasspathChangesComputerTest
Add ClasspathChangesComputerTest.testMixedClassSnapshotGranularities
2022-02-17 10:46:19 +03:00
Hung Nguyen 39b7c6e326 KT-34862: Clean up tests for incremental compilation after cache hit
Make sure that:
  - Compilation with -Pkotlin.incremental.useClasspathSnapshot=true or
    -Dkotlin.incremental.classpath.snapshot.enabled=true is incremental
    after cache hit.
  - Default compilation (using build history files) is non-incremental
    after cache hit.

Also unify the related tests into
BuildCacheRelocationIT.testKotlinIncrementalCompilation*. We don't need
corresponding tests in BuildCacheIT because BuildCacheRelocationIT
already covers it.
2022-02-15 14:05:58 +03:00
nataliya.valtman d4d5c701fe Make statistic more readable 2022-02-11 17:23:38 +03:00
Hung Nguyen d018031cbf KT-45777: Clean up build cache tests for incremental compilation
- Clean up BuildCacheRelocationIT.testKotlinIncrementalCompilation
 - Delete BuildCacheIT.testKotlinCompileIncrementalBuildWithoutRelocation
   as it is already covered by the test in BuildCacheRelocationIT
 - Add BuildCacheRelocationIT.testKotlinIncrementalCompilation_withClasspathSnapshot
- Updated BuildCacheRelocationIT.testKotlinIncrementalCompilation_withClasspathSnapshot
2022-02-08 18:07:38 +03:00
Aleksei.Cherepanov a80d01265a Use possible incompatible metadata as a fallback for incremental analysis
If LeverVersion is set to greater than 1 of the current compiler version, metadata became null here org.jetbrains.kotlin.load.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor.createHeader, which leads to NPE during incremental analysis. Using the same incompatible data as fallback prevent it

#KTIJ-20954 Fixed

Merge-request: KT-MR-5680
Merged-by: Aleksei Cherepanov <aleksei.cherepanov@jetbrains.com>
2022-02-04 09:42:05 +00:00
Hung Nguyen 1cb509d529 KT-45777: Remove proto-based approach to compute Java class snapshots
as the ASM-based approach is better, and we have switched to the
ASM-based approach for a while now.
2022-02-01 12:41:53 +03:00
Hung Nguyen 37c6b1c2dc KT-45777: Track build time in nanoseconds instead of milliseconds
to ensure precision (otherwise, rounding errors to milliseconds may
add up and cause unexplainable gaps in the running time).

We can still use milliseconds in the final report after all the precise
sub-build-times have been aggregated.
2022-01-31 19:50:03 +03:00
nataliya.valtman 791762d7ea Update kotlin report properties
-add kotlin.build.report.output to add file/http/build_scan reports
-all reports verbose by default
-verbose reports includes compiler metrics
-fix "custom value exceed length limit"
2022-01-21 09:43:21 +00:00
Andrey Uskov 2adc851f1b Don't use global state for keeping incremental compilation state
Previously IC state was stored in System properties. As result parallel
compilation might cause incorrect state of IC, what led to corruption
of kotlin_module files. Now IC state is stored via CompilerArguments
and CompilerConfiguration
#KT-46038 Fixed
2022-01-12 13:37:46 +03:00
Hung Nguyen 78f10d9142 KT-45777: Keep only package facades whose members are looked up
to reduce the size of the shrunk classpath snapshot further.
2021-12-25 00:20:31 +03:00
Hung Nguyen 9b96dbe2d2 KT-45777: Parse classes only once with ASM
to get both constants and inline functions.

Also add BasicClassInfo to ClassFileWithContents to simplify the code.
2021-12-24 18:31:49 +03:00
Hung Nguyen 9a995af0df KT-44741: Improve handling of constants defined in companion objects 2021-12-24 18:31:49 +03:00
Hung Nguyen a900f2b66d KT-45777: Reorganize unit test data for classpath snapshot feature
to make it easier to add more tests in the next commits.

- Add unit tests for constants and inline functions

Also add tests for different kinds of Kotlin classes: CLASS,
FILE_FACADE, MULTIFILE_CLASS.

-Add unit test for nested classes

Also remove the existing integration test for nested classes to keep the
integration tests focused on the key scenarios while unit tests will
cover the corner cases.

Ignore inline functions that are private
2021-12-24 18:31:49 +03:00
Aleksei.Cherepanov 7b41d382b8 Replace deprecated hashing strategy for jvm caches
Deprecated FileUtil.PATH_HASHING_STRATEGY will be removed since Intellij 213, so replace it with another hashing strategy
2021-12-20 11:12:18 +00:00
Vyacheslav Gerasimov f7a9065b75 Build: Use intellij maven repo instead of downloaded IDEA
#KTI-82
2021-12-16 21:48:23 +03:00
Vyacheslav Gerasimov bc2f0936bd Build: Rename commonDep -> commonDependency 2021-12-16 21:48:19 +03:00
Hung Nguyen 586fa8af64 KT-45777: Shrink classpath snapshot incrementally
Currently, we shrink classpath snapshots at 2 steps:
  - Classpath diffing: Shrink the current classpath snapshot against
    the previous lookup symbols
  - Classpath snapshot saving: Shrink the current classpath snapshot
    against the current lookup symbols

With this commit, the shrinking at the second step is now incremental.
The shrinking at the first step is still non-incremental.
2021-12-14 13:10:08 +03:00
Anastasiya Shadrina d47cf315e7 [Metadata] Add context receivers to metadata.proto
[Tests] Add JvmVersionRequirementTest
2021-12-02 20:24:20 +03:00
Hung Nguyen 6ba1b2cc08 KT-45777: Don't include classpath snapshot dir in task output backup
for performance reasons: (1) the snapshots are too big, and (2) they are
usually updated only at the end of the task execution--in a failed task
run, they are usually unchanged and therefore don't need to be restored.
2021-11-30 13:59:19 +03:00
Hung Nguyen 6bee7948e7 KT-45777: Don't compute snapshots for inaccessible classes
Also visit a class file with ASM once to extract all information we need
in advance, instead of visiting the class file each time some piece of
info is needed.
2021-11-30 13:59:14 +03:00
Hung Nguyen f52be5f471 KT-45777: Move classpath diffing to incremental Kotlin compiler (2/2)
as we need access to the lookup tracker to compute classpath changes
more efficiently and reduce the size of the saved classpath snapshot.

The previous commit only changed the files' paths, this
commit actually updates the files' contents.

Note that classpath snapshotting still happens in Gradle artifact
transforms. (However, the previous commit also moved the code for
classpath snapshotting together with the code for classpath diffing as
they are closely related.)
2021-11-30 13:59:13 +03:00
Hung Nguyen bd7c2ae6d7 KT-45777: Snapshot Java classes using ASM analysis directly
This is faster than the current approach which creates
`JavaClassDescriptor`s, converts them to protos, and then snapshots
these protos.

- Refactor unit tests to faciliate further changes
- moves test data to a directory that matches the tests' package name
- moves expected snapshots to a separate directory
- adds public and private fields/properties to sample class
- Compute changes between ASM-based Java class snapshots
- Don't collect members of an added Java class as changes
as it's enough to report the name of the added Java class as changed (we
also do that for added Kotlin classes and Kotlin/Java removed classes).
- Add unit tests for impact analysis in advance
- Compute impacted symbols of changed symbols
Also do not collect added classes/class members as they don't impact
recompilation.
-Use ClassId when computing Java class changes
It is more precise than JvmClassName, which can be ambiguous around the
`$` character (e.g., ClassId "com/example/A$B.C" and "com/example/A.B$C"
both have the same JvmClassName "com/example/A$B$C").
- Compute impacted set of changed symbols across Kotlin and Java
- Add unit tests for impact analysis across Kotlin and Java
- Compute supertypes of Kotlin classes during snapshotting
- Handle inner classes when computing list of changed symbols.
For the reported symbols, always check all options:
class member, inner class, top level class, top level member.

Test: IncrementalJavaChangeClasspathSnapshotIT.testAddingInnerClass
2021-11-09 13:57:56 +03:00
Hung Nguyen e26dc4d574 KT-45777: Compute classpath changes based on changed snapshots only
to avoid unnecessarily loading unchanged ones.

Duplicate classes will make this a bit tricky. This commit outlines the
algorithm to handle them, the full implementation will follow later.

Also handle removed classes when computing classpath changes.

Test: New tests in ClasspathChangesComputerTest
2021-09-30 17:57:47 +03:00
Yahor Berdnikau 3dc69495f9 Restore tasks outputs to pre-execution state in worker.
Workers usually execute later than task action and does not raise
exception to the task. Such behaviour skips task outputs restoration to
the pre-execution state.

Kotlin compiler on incremental compilation error leaves 'dirty*' files
in the build output, forcing Gradle to run non-incrementally on the
next build. Fixed it by moving task outputs reset logic into worker as
well.

^KT-46406 In Progress
2021-09-28 11:41:09 +00:00
Vyacheslav Gerasimov ab146bd6d4 Build: Fix deprecated Gradle configurations usages
for migration to Gradle 7+ #KTI-559
2021-09-26 18:28:44 +03:00
Denis.Zharkov 38fa900e56 FIR: Optimize case with no annotations on package 2021-09-23 16:58:26 +03:00
Hung Nguyen f400305cc6 KT-45777: Handle problematic classes when taking snapshots
There are certain classes that we are not yet able to take snapshots of,
either because the class is faulty, or there is a bug in our code.

For these classes, we will use a special snapshot and fall back to the
existing approach to compute classpath changes.

In the short run, we will update this list of cases as they arise. In
the long run, we will:
  - Fix all cases that are caused by bugs in our code.
  - Decide what to with the faulty jars in general and remove the list.

Test: The following should pass
  - Step 1: ./gradlew publish
  - Step 2: ./gradlew publish -Pbootstrap.local=true
              -Pbootstrap.local.path=/path/to/kotlin/build/repo
              -Pkotlin.incremental.useClasspathSnapshot=true
2021-09-23 12:47:51 +03:00
Aleksei.Cherepanov 47a1dd27dd Fix after review KT-CR-4441 of cc5382b3
Simplify API of InlineConstTracker
In ConstLowering: Move transformer logic to another class to avoid mutable state. Avoid marking all files in module as module. Support of inner classes.

#KT-46506 Fixed
2021-09-22 01:55:18 +03:00
Andrey Uskov 8f963bed7c Optimized performance of recordPackageLookup
#KT-47909 Fixed
2021-09-16 12:07:55 +03:00
Hung Nguyen a48bf63630 KT-45777: Compute classpath changes for incremental Kotlin compile
Test: Updated unit tests + incremental compilation integration tests
2021-09-14 12:10:38 +03:00
Aleksei.Cherepanov cc5382b37e [JPS] Fix incremental build after changing Java constant
InlineConstantTracker implemented for tracking changed java static final constants, that used in kotlin.

#KT-46506 Fixed
2021-09-11 13:00:00 +03:00
Hung Nguyen a342c81a9f KT-45777: Take snapshots and compute changes for Java classes
Create `JavaClassDescriptor`s for Java classes
Ignore anonymous and synthetic classes
as they can't impact recompilation.
Clean up handling of local and anonymous classes

Bug: KT-45777
Test: New JavaClassDescriptorCreatorTest
2021-09-01 13:29:17 +03:00
Alexander Udalov 4f29c113b7 Remove KotlinCompilerVersion.IS_PRE_RELEASE
Now, milestones of major Kotlin releases (e.g. 1.6.0-M1) will NOT
generate prerelease binaries anymore.

The reason for that is it's proven to be quite a complicated process to
turn on IR_PRE_RELEASE after the release is branched, perform double
bootstrap and fix tests, and then do it again in reverse just before
release. With the new release cadence, we don't have that much time to
do it and verify that everything works as intended.

Note that this only removes the "global" prerelease flag. Compiler will
still generate prerelease binaries if a non-stable language version is
used. For example, Kotlin 1.6.0-M1 with `-language-version 1.7` will
generate prerelease binaries.
2021-08-24 16:23:42 +02:00
nataliya.valtman 260d301100 Report compiler performance data to ES 2021-08-24 16:33:13 +03:00
nataliya.valtman 7357aeb1c9 Add output size to ES metrics 2021-08-24 16:33:12 +03:00