Preview of Kotlin 1.6.20 With Prototype of Context Receivers, Parallel Compilation on JVM, Incremental Compilation in JS, and More
The first preview of the 1.6.20 release is out! Introducing Kotlin 1.6.20-M1! This preview includes:
- Defining context-dependent declarations in Kotlin/JVM with the prototype of context receivers.
- Faster builds with parallel compilation of a single module in the JVM IR backend.
- Faster development with incremental compilation in Kotlin/JS IR.
- Easier code sharing with hierarchical structure of multiplatform projects.
- Kotlin/Native performance improvements.
Prototype of context receivers for Kotlin/JVM
The YouTrack issue about supporting multiple receivers has received a lot of upvotes and positive feedback, so prototyping it became a part of our roadmap. Recently we published the initial design proposal of the feature under the name context receivers. We are now sharing the prototype for Kotlin/JVM.
With Kotlin 1.6.20-M1, you are no longer limited to having one receiver. If you need more, you can make functions, properties, and classes context-dependent (or contextual) by adding context receivers to their declaration. A contextual declaration:
- Requires all declared context receivers to be present in a caller’s scope as implicit receivers.
- Brings declared context receivers into its body scope as implicit receivers.
To enable context receivers in your project, use the
-Xcontext-receivers compiler option. You can find a detailed description of the feature and its syntax in the KEEP.
Please note that the implementation is a prototype:
-Xcontext-receiversenabled, the compiler will produce pre-release binaries that cannot be used in production code.
- The IDE support for context receivers is now minimal.
Support for parallel compilation of a single module in the JVM backend
We are continuing our work on the roadmap item Improve the new JVM IR backend compilation time. In Kotlin 1.6.20-M1, we added the experimental JVM IR backend mode to compile all the files in a module in parallel. Parallel compilation can reduce the total compilation time by up to 15%.
Enable the experimental parallel backend mode with the compiler option
-Xbackend-threads. Use the following arguments for this option:
Nis equal to the number of threads you want to use. It should not be greater than your number of CPU cores; otherwise, parallelization stops being effective because of switching context between threads.
0to use one thread for each CPU core.
This parallelization helps only when the project build is not parallelized enough by a build tool such as Gradle. For example, if you have a very big monolithic module, adding the compiler option
-Xbackend-threads to this module may help. But if a project consists of lots of small modules and has a parallelized build, adding another layer of parallelization may hurt performance because of context switching.
Note that experimental parallel compilation doesn’t work with kapt because kapt disables the IR backend. Also note that parallel compilation requires more JVM heap by design. The amount of heap is proportional to the number of threads.
We’d be grateful for your feedback in this YouTrack issue.
Incremental compilation for development binaries with Kotlin/JS IR compiler
To make Kotlin/JS development with the IR compiler more efficient, we’re introducing the new incremental compilation mode.
When building development binaries with the
compileDevelopmentExecutableKotlinJs Gradle task in this mode, the compiler caches the results of previous compilations on the module level. It uses the cached compilation results for unchanged source files during subsequent compilations, making them complete faster, especially with small changes. Note that this improvement exclusively targets the development process (shortening the edit-build-debug cycle) and doesn’t affect the building of production artifacts.
To enable incremental compilation for development binaries, add the following line to the project’s
Please tell us what you think of using the incremental compilation with your Kotlin/JS projects: share your results and impressions with us in this YouTrack issue. If you experience problems, file a new issue in YouTrack.
Hierarchical structure support
for multiplatform projects
Kotlin 1.6.20 comes with hierarchical structure support enabled by default. Since introducing it in Kotlin 1.4.0, we’ve significantly improved the frontend and IDE import stability.
Now you can share source code among several similar native targets. The technology will provide correct default dependencies and find the exact API available in the shared code. This eliminates a complex build setup and workarounds to get IDE support for sharing source sets among native targets. It also helps to prevent unsafe API usages meant for a different target.
The technology will come in handy for library authors too. A hierarchical project structure allows you to publish and consume libraries with common APIs for a subset of targets.
Better code-sharing in your project
Without hierarchical structure support, there is no straightforward way to share code across some but not all Kotlin targets. One particular example that is popular: sharing code across all iOS targets and having access to iOS-specific dependencies, like
Thanks to the hierarchical project structure support, you can now achieve this out of the box. The Kotlin toolchain will provide the correct default dependencies, like Kotlin/Native stdlib or native libraries.
Moreover, this technology will try its best to find exactly the API surface area available in the shared code. This prevents such cases as, for example, the use of a macOS-specific function in the code shared for Windows.
More opportunities for the library ecosystem
When a multiplatform library is published, the API of its intermediate source sets is now properly published alongside it, making it available for consumers. Again, the Kotlin toolchain will automatically figure out the API available in the consumer source set while watching carefully over unsafe usages, like using an API meant for the JVM in JS code. Learn more about sharing code in libraries.
By default, libraries published with the hierarchical project structure are compatible only with hierarchical structure projects. Learn more about project-library compatibility.
Configuration and setup
Starting with Kotlin 1.6.20-M1, all your new multiplatform projects will have a hierarchical project structure. No additional setup is required.
- If you’ve already turned it on manually, you can remove the corresponding option from
- For Kotlin 1.6.20, we recommend using Android Studio 2021.1.1 (Bumblebee) or later to get the best experience.
Leave your feedback
This is a significant change for the whole ecosystem. We appreciate your feedback to help make it even better.
Try it now and report any difficulties you encounter to our issue tracker, YouTrack.
Kotlin/Native performance improvements
We are working hard on Kotlin/Native to speed up the compilation process and improve your developing experience.
This 1.6.20 Kotlin release brings some performance updates and bug fixes that affect the LLVM IR that Kotlin generates. According to the benchmarks on our internal projects, we achieved the following performance boosts on average:
- 15% reduction in execution time
- 20% reduction in the code size of both release and debug binaries
- 26% reduction in the compilation time of release binaries
These changes also provide a 10% reduction in compilation time for a debug binary on a large internal project.
To achieve this, we’ve implemented static initialization for some of the compiler-generated synthetic objects, improved the way we structure LLVM IR for every function, and optimized the compiler caches.
If you have already switched to our new memory manager, which was announced in Kotlin 1.6, you might notice a huge execution time improvement: our benchmarks show 35% improvement on average. Since this EAP release, there is also a concurrent implementation for the sweep phase available for the new memory manager. This should also improve the performance and decrease the duration of garbage collector pauses. Use the
-Xgc=cms flag to enable it for the new Kotlin/Native memory manager.
Feel free to share your feedback on the new memory manager performance in this YouTrack issue.
Stay up to date with information about the latest Kotlin features! Enter your email address and subscribe to Kotlin updates using the form to the right of the post.
Try new features and provide feedback
- If you use the Early Access Preview update channel, the IDE will suggest updating to 1.6.20-M1 automatically as soon as it becomes available.
- If you use the Stable update channel, you can change the channel to Early Access Preview at any time by selecting Tools | Kotlin | Configure Kotlin Plugin Updates in your IDE. You’ll then be able to install the latest preview release. Check out these instructions for details. Note that starting from Kotlin 1.6.20-M1, there is only one Early Access Preview channel.
You can always download the latest versions of these IDEs to get extensive support for Kotlin:
- IntelliJ IDEA for developing Kotlin applications for a variety of platforms.
- Android Studio for developing Android and cross-platform mobile applications.
Once you’ve installed 1.6.20-M1, change the Kotlin version to
1.6.20-M1 in your build scripts.
If you run into any problems:
- Report issues to our issue tracker, YouTrack.
- Find help in the #eap channel in Kotlin Slack (get an invite).
- Rollback to the latest stable version. Learn how.