From 8065e490e89ff34a6250527526386f882c03920c Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Thu, 18 Feb 2016 13:02:31 +0100 Subject: [PATCH] performing cleanup (and memory usage reporting) only if kotlin compiler was actually called, should fix e.g. KT-10127 --- .../jetbrains/kotlin/gradle/tasks/Tasks.kt | 2 + .../gradle/plugin/CleanUpBuildListener.kt | 38 +++++++++++++------ .../gradle/plugin/KotlinPluginWrapper.kt | 7 ++-- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index 8b4eb50c6a5..2bb96efa4f5 100644 --- a/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -42,6 +42,7 @@ abstract class AbstractKotlinCompile() : AbstractCo public var kotlinOptions: T = createBlankArgs() public var kotlinDestinationDir: File? = destinationDir + var compilerCalled: Boolean = false private val loggerInstance = Logging.getLogger(this.javaClass) override fun getLogger() = loggerInstance @@ -56,6 +57,7 @@ abstract class AbstractKotlinCompile() : AbstractCo return } + compilerCalled = true populateCommonArgs(args, sources) populateTargetSpecificArgs(args) callCompiler(args) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/CleanUpBuildListener.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/CleanUpBuildListener.kt index 840726d1eb5..23ffc0fe62c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/CleanUpBuildListener.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/CleanUpBuildListener.kt @@ -19,7 +19,9 @@ package org.jetbrains.kotlin.gradle.plugin import org.apache.commons.lang.SystemUtils import org.gradle.BuildAdapter import org.gradle.BuildResult +import org.gradle.api.Project import org.gradle.api.logging.Logging +import org.gradle.api.tasks.compile.AbstractCompile import java.util.concurrent.ScheduledExecutorService import kotlin.properties.Delegates @@ -34,7 +36,7 @@ private fun comparableVersionStr(version: String) = ?.let { if (it.all { (it?.value?.length ?: 0).let { it > 0 && it < 4 }}) it else null } ?.joinToString(".", transform = { it!!.value.padStart(3, '0') }) -class CleanUpBuildListener(pluginClassLoader: ClassLoader) : BuildAdapter() { +class CleanUpBuildListener(pluginClassLoader: ClassLoader, private val project: Project) : BuildAdapter() { companion object { const val FORCE_SYSTEM_GC_MESSAGE = "Forcing System.gc()" } @@ -53,23 +55,35 @@ class CleanUpBuildListener(pluginClassLoader: ClassLoader) : BuildAdapter() { } override fun buildFinished(result: BuildResult?) { - log.kotlinDebug("Build finished listener") - val gradle = result?.gradle if (gradle != null) { - cleanup(gradle.gradleVersion) - // checking thread leaks only then cleaning up - threadTracker?.checkThreadLeak(gradle) + + val kotlinCompilerCalled = project.tasks.filter { it.name.contains("kotlin", ignoreCase = true) } + .any { task -> task.hasProperty("compilerCalled") && task.property("compilerCalled") as? Boolean ?: false } + + if (kotlinCompilerCalled) { + log.kotlinDebug("Cleanup after kotlin") + + cleanup(gradle.gradleVersion) + + // checking thread leaks only then cleaning up + threadTracker?.checkThreadLeak(gradle) + } + else { + log.kotlinDebug("Skipping kotlin cleanup since compiler wasn't called") + } threadTracker = null gradle.removeListener(this) - } - startMemory?.let { startMemoryCopy -> - getUsedMemoryKb()?.let { endMemory -> - // the value reported here is not necessarily a leak, since it is calculated before collecting the plugin classes - // but on subsequent runs in the daemon it should be rather small, then the classes are actually reused by the daemon (see above) - log.kotlinDebug("[PERF] Used memory after build: $endMemory kb (difference since build start: ${"%+d".format(endMemory - startMemoryCopy)} kb)") + if (kotlinCompilerCalled) { + startMemory?.let { startMemoryCopy -> + getUsedMemoryKb()?.let { endMemory -> + // the value reported here is not necessarily a leak, since it is calculated before collecting the plugin classes + // but on subsequent runs in the daemon it should be rather small, then the classes are actually reused by the daemon (see above) + log.kotlinDebug("[PERF] Used memory after build: $endMemory kb (difference since build start: ${"%+d".format(endMemory - startMemoryCopy)} kb)") + } + } } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt index b169d559e67..b87f3fde877 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt @@ -14,10 +14,6 @@ abstract class KotlinBasePluginWrapper: Plugin { val log = Logging.getLogger(this.javaClass) override fun apply(project: Project) { - val cleanUpBuildListener = CleanUpBuildListener(this.javaClass.classLoader) - cleanUpBuildListener.buildStarted() - project.gradle.addBuildListener(cleanUpBuildListener) - val sourceBuildScript = findSourceBuildScript(project) if (sourceBuildScript == null) { log.error("Failed to determine source cofiguration of kotlin plugin. Can not download core. Please verify that this or any parent project " + @@ -31,6 +27,9 @@ abstract class KotlinBasePluginWrapper: Plugin { val plugin = getPlugin(this.javaClass.classLoader, sourceBuildScript) plugin.apply(project) + val cleanUpBuildListener = CleanUpBuildListener(this.javaClass.classLoader, project) + cleanUpBuildListener.buildStarted() + project.gradle.addBuildListener(cleanUpBuildListener) } protected abstract fun getPlugin(pluginClassLoader: ClassLoader, scriptHandler: ScriptHandler): Plugin