Kotlin Gradle plugin - use build service to share incremental compilation info

For large projects, incremental comilation mapping information may be quite
large. With configuration caching enabled, each task gets its own copy of that
state, and for a project with 1400 subprojects, this resulted in 3.6GB of additional
state stored (once task graph is cached).

This change introduces IncrementalModuleInfoProvider which allows build service
to be used if configuration caching is enabled, and it falls back to static
constant otherwise.
This commit is contained in:
Ivan Gavrilovic
2020-08-13 20:44:25 +01:00
committed by nataliya.valtman
parent 16d51eb510
commit 7c360c0068
3 changed files with 57 additions and 6 deletions
@@ -141,7 +141,7 @@ internal open class GradleCompilerRunner(protected val taskProvider: GradleCompi
}
val incrementalCompilationEnvironment = environment.incrementalCompilationEnvironment
val modulesInfo = incrementalCompilationEnvironment?.let { incrementalModuleInfoProvider }
val modulesInfo = incrementalCompilationEnvironment?.let { incrementalModuleInfoProvider.get().info }
val workArgs = GradleKotlinCompilerWorkArguments(
projectFiles = ProjectFilesForCompilation(
loggerProvider,
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.incremental
import org.gradle.api.provider.Property
import org.gradle.api.services.BuildService
import org.gradle.api.services.BuildServiceParameters
import org.jetbrains.kotlin.incremental.IncrementalModuleInfo
/**
* Provider of [IncrementalModuleInfo] that allows concrete implementation to e.g use Gradle build services
* or rely on some static stats.
*/
interface IncrementalModuleInfoProvider {
val info: IncrementalModuleInfo
}
/** A build service used to provide [IncrementalModuleInfo] instance for all tasks. */
abstract class IncrementalModuleInfoBuildService : BuildService<IncrementalModuleInfoBuildService.Parameters>,
IncrementalModuleInfoProvider {
abstract class Parameters : BuildServiceParameters {
abstract val info: Property<IncrementalModuleInfo>
}
override val info: IncrementalModuleInfo
get() = parameters.info.get()
companion object {
// Use class name + class loader in case there are multiple class loaders in the same build
fun getServiceName(): String {
val clazz = IncrementalModuleInfoBuildService::class.java
return clazz.canonicalName + "_" + clazz.classLoader.hashCode()
}
}
}
@@ -25,6 +25,8 @@ import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner.Companion.normal
import org.jetbrains.kotlin.daemon.common.MultiModuleICSettings
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.incremental.ChangedFiles
import org.jetbrains.kotlin.gradle.incremental.IncrementalModuleInfoBuildService
import org.jetbrains.kotlin.gradle.incremental.IncrementalModuleInfoProvider
import org.jetbrains.kotlin.gradle.internal.*
import org.jetbrains.kotlin.gradle.internal.tasks.TaskWithLocalState
import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles
@@ -37,12 +39,11 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithTransitiveClosure
import org.jetbrains.kotlin.gradle.plugin.mpp.ownModuleName
import org.jetbrains.kotlin.gradle.report.BuildReportMode
import org.jetbrains.kotlin.gradle.utils.getValue
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.gradle.utils.isParentOf
import org.jetbrains.kotlin.gradle.utils.pathsAsStringRelativeTo
import org.jetbrains.kotlin.gradle.utils.toSortedPathsArray
import org.jetbrains.kotlin.incremental.ChangedFiles
import org.jetbrains.kotlin.incremental.IncrementalModuleInfo
import org.jetbrains.kotlin.library.impl.isKotlinLibrary
import org.jetbrains.kotlin.utils.JsLibraryUtils
import java.io.File
@@ -127,10 +128,22 @@ public class GradleCompileTaskProvider {
rootDir = task.project.rootProject.rootDir
sessionsDir = GradleCompilerRunner.sessionsDir(task.project)
projectName = task.project.rootProject.name.normalizeForFlagFile()
buildModulesInfo = GradleCompilerRunner.buildModulesInfo(task.project.gradle)
val modulesInfo = GradleCompilerRunner.buildModulesInfo(task.project.gradle)
buildModulesInfo = if (!isConfigurationCacheAvailable(task.project.gradle)) {
task.project.provider {
object : IncrementalModuleInfoProvider {
override val info = modulesInfo
}
}
} else {
task.project.gradle.sharedServices.registerIfAbsent(
IncrementalModuleInfoBuildService.getServiceName(), IncrementalModuleInfoBuildService::class.java
) {
it.parameters.info.set(modulesInfo)
}
}
path = task.path
logger = task.logger
}
val path: String
@@ -140,7 +153,7 @@ public class GradleCompileTaskProvider {
val rootDir: File /*= project.rootProject.rootDir*/
val sessionsDir: File/* = GradleCompilerRunner.sessionsDir(project)*/
val projectName: String /*= project.rootProject.name.normalizeForFlagFile()*/
val buildModulesInfo: IncrementalModuleInfo /*= GradleCompilerRunner.buildModulesInfo(project.gradle)*/
val buildModulesInfo: Provider<out IncrementalModuleInfoProvider> /*= GradleCompilerRunner.buildModulesInfo(project.gradle)*/
}
abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKotlinCompileTool<T>() {