Skip to content

Commit 0012580

Browse files
wojtek-kalicinskiSpace Team
authored andcommitted
[KGP] Introduce BuildSessionService for caching BTA sessions
^KT-78199
1 parent a32009f commit 0012580

File tree

9 files changed

+110
-20
lines changed

9 files changed

+110
-20
lines changed

libraries/tools/kotlin-gradle-plugin/api/all/kotlin-gradle-plugin.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5820,7 +5820,7 @@ public abstract class org/jetbrains/kotlin/gradle/targets/web/yarn/BaseYarnRootE
58205820
public abstract interface class org/jetbrains/kotlin/gradle/targets/web/yarn/CommonYarnPlugin : org/gradle/api/Plugin {
58215821
}
58225822

5823-
public abstract class org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile : org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompileTool, org/jetbrains/kotlin/compilerRunner/UsesCompilerSystemPropertiesService, org/jetbrains/kotlin/gradle/incremental/UsesIncrementalModuleInfoBuildService, org/jetbrains/kotlin/gradle/internal/UsesClassLoadersCachingBuildService, org/jetbrains/kotlin/gradle/plugin/UsesBuildFinishedListenerService, org/jetbrains/kotlin/gradle/plugin/UsesKotlinGradleBuildServices, org/jetbrains/kotlin/gradle/plugin/UsesVariantImplementationFactories, org/jetbrains/kotlin/gradle/plugin/diagnostics/UsesKotlinToolingDiagnostics, org/jetbrains/kotlin/gradle/plugin/internal/UsesBuildIdProviderService, org/jetbrains/kotlin/gradle/plugin/statistics/UsesBuildFusService, org/jetbrains/kotlin/gradle/report/UsesBuildMetricsService, org/jetbrains/kotlin/gradle/tasks/BaseKotlinCompile, org/jetbrains/kotlin/gradle/tasks/CompileUsingKotlinDaemonWithNormalization {
5823+
public abstract class org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile : org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompileTool, org/jetbrains/kotlin/compilerRunner/UsesCompilerSystemPropertiesService, org/jetbrains/kotlin/compilerRunner/btapi/UsesBuildSessionService, org/jetbrains/kotlin/gradle/incremental/UsesIncrementalModuleInfoBuildService, org/jetbrains/kotlin/gradle/internal/UsesClassLoadersCachingBuildService, org/jetbrains/kotlin/gradle/plugin/UsesBuildFinishedListenerService, org/jetbrains/kotlin/gradle/plugin/UsesKotlinGradleBuildServices, org/jetbrains/kotlin/gradle/plugin/UsesVariantImplementationFactories, org/jetbrains/kotlin/gradle/plugin/diagnostics/UsesKotlinToolingDiagnostics, org/jetbrains/kotlin/gradle/plugin/internal/UsesBuildIdProviderService, org/jetbrains/kotlin/gradle/plugin/statistics/UsesBuildFusService, org/jetbrains/kotlin/gradle/report/UsesBuildMetricsService, org/jetbrains/kotlin/gradle/tasks/BaseKotlinCompile, org/jetbrains/kotlin/gradle/tasks/CompileUsingKotlinDaemonWithNormalization {
58245824
public fun <init> (Lorg/gradle/api/model/ObjectFactory;Lorg/gradle/workers/WorkerExecutor;)V
58255825
protected fun cleanOutputsAndLocalState (Ljava/lang/String;)V
58265826
public final fun execute (Lorg/gradle/work/InputChanges;)V

libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import org.gradle.workers.WorkerExecutor
1818
import org.jetbrains.kotlin.build.report.metrics.*
1919
import org.jetbrains.kotlin.cli.common.arguments.*
2020
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
21+
import org.jetbrains.kotlin.compilerRunner.btapi.BuildSessionService
2122
import org.jetbrains.kotlin.compilerRunner.btapi.GradleBuildToolsApiCompilerRunner
2223
import org.jetbrains.kotlin.daemon.client.CompileServiceSession
2324
import org.jetbrains.kotlin.daemon.common.CompilerId
@@ -68,6 +69,7 @@ internal fun createGradleCompilerRunner(
6869
cachedClassLoadersService: Property<ClassLoadersCachingBuildService>,
6970
buildFinishedListenerService: Provider<BuildFinishedListenerService>,
7071
buildIdService: Provider<BuildIdService>,
72+
buildSessionService: Provider<BuildSessionService>,
7173
fusMetricsConsumer: StatisticsValuesConsumer?,
7274
diagnosticsReporter: UsesKotlinToolingDiagnostics,
7375
): GradleCompilerRunner {
@@ -82,6 +84,7 @@ internal fun createGradleCompilerRunner(
8284
cachedClassLoadersService,
8385
buildFinishedListenerService,
8486
buildIdService,
87+
buildSessionService,
8588
fusMetricsConsumer
8689
)
8790
} else {
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
3+
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
4+
*/
5+
6+
package org.jetbrains.kotlin.compilerRunner.btapi
7+
8+
import org.gradle.api.Project
9+
import org.gradle.api.Task
10+
import org.gradle.api.provider.Property
11+
import org.gradle.api.provider.Provider
12+
import org.gradle.api.services.BuildService
13+
import org.gradle.api.services.BuildServiceParameters
14+
import org.gradle.api.tasks.Internal
15+
import org.jetbrains.kotlin.buildtools.api.KotlinToolchains
16+
import org.jetbrains.kotlin.gradle.internal.ClassLoadersCachingBuildService
17+
import org.jetbrains.kotlin.gradle.tasks.withType
18+
import org.jetbrains.kotlin.gradle.utils.SingleActionPerProject
19+
import org.jetbrains.kotlin.gradle.utils.registerClassLoaderScopedBuildService
20+
import java.io.File
21+
import java.util.concurrent.ConcurrentHashMap
22+
import java.util.concurrent.locks.ReentrantReadWriteLock
23+
import kotlin.concurrent.read
24+
import kotlin.concurrent.write
25+
26+
internal interface UsesBuildSessionService : Task {
27+
@get:Internal
28+
val buildSessionService: Property<BuildSessionService>
29+
}
30+
31+
/**
32+
* A Gradle [BuildService] to share the same [KotlinToolchain.BuildSession] instance between multiple tasks.
33+
*/
34+
internal abstract class BuildSessionService : BuildService<BuildServiceParameters.None>, AutoCloseable {
35+
private val lock = ReentrantReadWriteLock()
36+
private var closed = false
37+
private val buildSessions = ConcurrentHashMap<List<File>, KotlinToolchains.BuildSession>()
38+
39+
fun getOrCreateBuildSession(
40+
classloaderService: ClassLoadersCachingBuildService,
41+
compilerClasspath: List<File>,
42+
): KotlinToolchains.BuildSession {
43+
lock.read {
44+
check(!closed) { "${BuildSessionService::class.java.simpleName} is already closed, cannot create new build sessions" }
45+
return buildSessions.computeIfAbsent(compilerClasspath) {
46+
val classLoader = classloaderService.getClassLoader(compilerClasspath, SharedApiClassesClassLoaderProvider)
47+
val compilationService = KotlinToolchains.loadImplementation(classLoader)
48+
compilationService.createBuildSession()
49+
}
50+
}
51+
}
52+
53+
override fun close() {
54+
lock.write {
55+
check(!closed) { "${BuildSessionService::class.java.simpleName} is already closed" }
56+
closed = true
57+
buildSessions.values.forEach { it.close() }
58+
buildSessions.clear()
59+
}
60+
}
61+
62+
companion object {
63+
fun registerIfAbsent(project: Project): Provider<BuildSessionService> =
64+
project.gradle.registerClassLoaderScopedBuildService(BuildSessionService::class).also { serviceProvider ->
65+
SingleActionPerProject.run(project, UsesBuildSessionService::class.java.name) {
66+
project.tasks.withType<UsesBuildSessionService>().configureEach { task ->
67+
task.usesService(serviceProvider)
68+
task.buildSessionService.set(serviceProvider)
69+
}
70+
}
71+
}
72+
73+
fun getInstance(project: Project): BuildSessionService = registerIfAbsent(project).get()
74+
}
75+
}

libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/BuildToolsApiCompilationWork.kt

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ import org.jetbrains.kotlin.gradle.internal.ParentClassLoaderProvider
4242
import org.jetbrains.kotlin.gradle.logging.CompositeKotlinLogger
4343
import org.jetbrains.kotlin.gradle.logging.ExceptionReportingKotlinLogger
4444
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
45-
import org.jetbrains.kotlin.gradle.logging.logCompilerArgumentsMessage
4645
import org.jetbrains.kotlin.gradle.logging.reportToIde
4746
import org.jetbrains.kotlin.gradle.plugin.BuildFinishedListenerService
4847
import org.jetbrains.kotlin.gradle.plugin.internal.BuildIdService
@@ -70,6 +69,7 @@ internal abstract class BuildToolsApiCompilationWork @Inject constructor(
7069
) :
7170
WorkAction<BuildToolsApiCompilationWork.BuildToolsApiCompilationParameters> {
7271
internal interface BuildToolsApiCompilationParameters : WorkParameters {
72+
val buildSessionService: Property<BuildSessionService>
7373
val buildIdService: Property<BuildIdService>
7474
val buildFinishedListenerService: Property<BuildFinishedListenerService>
7575
val classLoadersCachingService: Property<ClassLoadersCachingBuildService>
@@ -94,14 +94,11 @@ internal abstract class BuildToolsApiCompilationWork @Inject constructor(
9494
@OptIn(ExperimentalCompilerArgument::class)
9595
private fun performCompilation(executionStrategy: KotlinCompilerExecutionStrategy, log: KotlinLogger): CompilationResult {
9696
try {
97-
val classLoader = parameters.classLoadersCachingService.get()
98-
.getClassLoader(workArguments.compilerFullClasspath, SharedApiClassesClassLoaderProvider)
99-
val compilationService = KotlinToolchains.loadImplementation(classLoader)
100-
val buildId = ProjectId.ProjectUUID(parameters.buildIdService.get().buildId)
101-
val build = compilationService.createBuildSession()
102-
parameters.buildFinishedListenerService.get().onCloseOnceByKey(buildId.toString()) {
103-
build.close()
104-
}
97+
val buildSession = parameters.buildSessionService.get().getOrCreateBuildSession(
98+
parameters.classLoadersCachingService.get(),
99+
workArguments.compilerFullClasspath
100+
)
101+
val compilationService = buildSession.kotlinToolchains
105102

106103
val args = parseCommandLineArguments<K2JVMCompilerArguments>(workArguments.compilerArgs.toList())
107104
val jvmCompilationOperation = compilationService.jvm.createJvmCompilationOperation(
@@ -169,7 +166,7 @@ internal abstract class BuildToolsApiCompilationWork @Inject constructor(
169166
}
170167

171168
return metrics.measure(GradleBuildTime.RUN_COMPILATION) {
172-
build.executeOperation(jvmCompilationOperation, executionConfig, log)
169+
buildSession.executeOperation(jvmCompilationOperation, executionConfig, log)
173170
}.also { extractMetrics(jvmCompilationOperation) }
174171
} catch (e: Throwable) {
175172
wrapAndRethrowCompilationException(executionStrategy, e)

libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/GradleBuildToolsApiCompilerRunner.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ internal class GradleBuildToolsApiCompilerRunner(
3131
private val cachedClassLoadersService: Provider<ClassLoadersCachingBuildService>,
3232
private val buildFinishedListenerService: Provider<BuildFinishedListenerService>,
3333
private val buildIdService: Provider<BuildIdService>,
34+
private val buildSessionService: Provider<BuildSessionService>,
3435
fusMetricsConsumer: StatisticsValuesConsumer?,
3536
) : GradleCompilerRunner(taskProvider, jdkToolsJar, compilerExecutionSettings, buildMetrics, fusMetricsConsumer) {
3637

@@ -46,6 +47,7 @@ internal class GradleBuildToolsApiCompilerRunner(
4647
params.classLoadersCachingService.set(cachedClassLoadersService)
4748
params.buildFinishedListenerService.set(buildFinishedListenerService)
4849
params.buildIdService.set(buildIdService)
50+
params.buildSessionService.set(buildSessionService)
4951
if (taskOutputsBackup != null) {
5052
params.taskOutputsToRestore.set(taskOutputsBackup.outputsToRestore)
5153
params.snapshotsDir.set(taskOutputsBackup.snapshotsDir)

libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/transforms/ClasspathEntrySnapshotTransform.kt

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,16 @@ import org.gradle.api.provider.Provider
1414
import org.gradle.api.tasks.Classpath
1515
import org.gradle.api.tasks.Input
1616
import org.gradle.api.tasks.Internal
17-
import org.jetbrains.kotlin.buildtools.api.KotlinToolchains
1817
import org.jetbrains.kotlin.buildtools.api.jvm.ClassSnapshotGranularity
1918
import org.jetbrains.kotlin.buildtools.api.jvm.ClassSnapshotGranularity.CLASS_LEVEL
2019
import org.jetbrains.kotlin.buildtools.api.jvm.ClassSnapshotGranularity.CLASS_MEMBER_LEVEL
2120
import org.jetbrains.kotlin.buildtools.api.jvm.JvmPlatformToolchain.Companion.jvm
2221
import org.jetbrains.kotlin.buildtools.api.jvm.operations.JvmClasspathSnapshottingOperation.Companion.GRANULARITY
2322
import org.jetbrains.kotlin.buildtools.api.jvm.operations.JvmClasspathSnapshottingOperation.Companion.PARSE_INLINED_LOCAL_CLASSES
24-
import org.jetbrains.kotlin.compilerRunner.btapi.SharedApiClassesClassLoaderProvider
23+
import org.jetbrains.kotlin.compilerRunner.btapi.BuildSessionService
2524
import org.jetbrains.kotlin.gradle.internal.ClassLoadersCachingBuildService
2625
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
2726
import org.jetbrains.kotlin.gradle.plugin.diagnostics.TransformActionUsingKotlinToolingDiagnostics
28-
import org.jetbrains.kotlin.gradle.utils.use
2927
import java.io.File
3028

3129
/** Transform to create a snapshot of a classpath entry (directory or jar). */
@@ -60,6 +58,9 @@ internal abstract class ClasspathEntrySnapshotTransform : TransformAction<Classp
6058

6159
@get:Input
6260
abstract val parseInlinedLocalClasses: Property<Boolean>
61+
62+
@get:Internal
63+
abstract val buildSessionService: Property<BuildSessionService>
6364
}
6465

6566
@get:Classpath
@@ -95,17 +96,18 @@ internal abstract class ClasspathEntrySnapshotTransform : TransformAction<Classp
9596
)
9697
val parseInlinedLocalClasses = parameters.parseInlinedLocalClasses.get()
9798

98-
val classLoader = parameters.classLoadersCachingService.get()
99-
.getClassLoader(parameters.classpath.toList(), SharedApiClassesClassLoaderProvider)
100-
val kotlinToolchains = KotlinToolchains.loadImplementation(classLoader)
99+
val buildSession = parameters.buildSessionService.get().getOrCreateBuildSession(
100+
parameters.classLoadersCachingService.get(),
101+
parameters.classpath.toList()
102+
)
103+
val kotlinToolchains = buildSession.kotlinToolchains
104+
101105
val snapshotOperation = kotlinToolchains.jvm.createClasspathSnapshottingOperation(classpathEntryInputDirOrJar.toPath())
102106
.apply {
103107
this[GRANULARITY] = granularity
104108
this[PARSE_INLINED_LOCAL_CLASSES] = parseInlinedLocalClasses
105109
}
106-
val snapshot = kotlinToolchains.createBuildSession().use {
107-
it.executeOperation(snapshotOperation)
108-
}
110+
val snapshot = buildSession.executeOperation(snapshotOperation)
109111
snapshot.saveSnapshot(snapshotOutputFile)
110112
}
111113

libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import org.gradle.api.Project
2222
import org.gradle.api.artifacts.ExternalDependency
2323
import org.gradle.api.logging.Logger
2424
import org.gradle.api.logging.Logging
25+
import org.jetbrains.kotlin.compilerRunner.btapi.BuildSessionService
2526
import org.jetbrains.kotlin.compilerRunner.maybeCreateCommonizerClasspathConfiguration
2627
import org.jetbrains.kotlin.gradle.dsl.*
2728
import org.jetbrains.kotlin.gradle.fus.BuildUidService
@@ -77,6 +78,7 @@ abstract class DefaultKotlinBasePlugin : KotlinBasePlugin {
7778
project.runGradleCompatibilityCheck()
7879
project.runAgpCompatibilityCheckIfAgpIsApplied()
7980
BuildFinishedListenerService.registerIfAbsent(project)
81+
BuildSessionService.registerIfAbsent(project)
8082

8183
val buildUidService = BuildUidService.registerIfAbsent(project.gradle)
8284
BuildFusService.registerIfAbsent(project, pluginVersion, buildUidService)

libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.compilerRunner.*
2121
import org.jetbrains.kotlin.compilerRunner.CompilerExecutionSettings
2222
import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner
2323
import org.jetbrains.kotlin.compilerRunner.UsesCompilerSystemPropertiesService
24+
import org.jetbrains.kotlin.compilerRunner.btapi.UsesBuildSessionService
2425
import org.jetbrains.kotlin.compilerRunner.createGradleCompilerRunner
2526
import org.jetbrains.kotlin.daemon.common.MultiModuleICSettings
2627
import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
@@ -61,6 +62,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
6162
UsesClassLoadersCachingBuildService,
6263
UsesKotlinToolingDiagnostics,
6364
UsesBuildIdProviderService,
65+
UsesBuildSessionService,
6466
UsesBuildFusService,
6567
BaseKotlinCompile {
6668

@@ -201,6 +203,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
201203
classLoadersCachingService,
202204
buildFinishedListenerService,
203205
buildIdService,
206+
buildSessionService,
204207
buildFusService.orNull?.getFusMetricsConsumer(),
205208
this
206209
)

libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import org.gradle.api.artifacts.result.ResolvedDependencyResult
1212
import org.gradle.api.artifacts.transform.TransformSpec
1313
import org.gradle.api.artifacts.type.ArtifactTypeDefinition
1414
import org.gradle.api.provider.Provider
15+
import org.jetbrains.kotlin.compilerRunner.btapi.BuildSessionService
1516
import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
1617
import org.jetbrains.kotlin.gradle.internal.ClassLoadersCachingBuildService
1718
import org.jetbrains.kotlin.gradle.internal.KOTLIN_BUILD_TOOLS_API_IMPL
@@ -152,6 +153,7 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
152153
classpath: Provider<out Configuration>,
153154
jvmToolchain: Provider<DefaultKotlinJavaToolchain>,
154155
runKotlinCompilerViaBuildToolsApi: Provider<Boolean>,
156+
buildSessionService: Provider<BuildSessionService>,
155157
) {
156158
parameters.gradleUserHomeDir.set(project.gradle.gradleUserHomeDir)
157159
val roDepCachePath = System.getenv(READONLY_CACHE_ENV_VAR)
@@ -177,6 +179,7 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
177179
parameters.buildToolsImplVersion.set(classpath.map { configuration -> configuration.findBuildToolsApiImplVersion() })
178180
}
179181
parameters.suppressVersionInconsistencyChecks.set(suppressVersionInconsistencyChecks)
182+
parameters.buildSessionService.set(buildSessionService)
180183
}
181184

182185
private fun Configuration.findBuildToolsApiImplVersion() = incoming.resolutionResult.allDependencies
@@ -194,6 +197,7 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
194197
val classLoadersCachingService = ClassLoadersCachingBuildService.registerIfAbsent(project)
195198
val classpath = project.configurations.named(BUILD_TOOLS_API_CLASSPATH_CONFIGURATION_NAME)
196199
val kgpVersion = project.getKotlinPluginVersion()
200+
val buildSessionService = BuildSessionService.registerIfAbsent(project)
197201
project.dependencies.registerTransformForArtifactType(
198202
ClasspathEntrySnapshotTransform::class.java,
199203
fromArtifactType = ArtifactTypeDefinition.JAR_TYPE,
@@ -205,6 +209,7 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
205209
classpath,
206210
jvmToolchain,
207211
runKotlinCompilerViaBuildToolsApi,
212+
buildSessionService,
208213
)
209214
it.parameters.setupKotlinToolingDiagnosticsParameters(project)
210215
}
@@ -219,6 +224,7 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
219224
classpath,
220225
jvmToolchain,
221226
runKotlinCompilerViaBuildToolsApi,
227+
buildSessionService,
222228
)
223229
it.parameters.setupKotlinToolingDiagnosticsParameters(project)
224230
}

0 commit comments

Comments
 (0)