Add IC metrics reporting
This commit is contained in:
committed by
Alexander Likhachev
parent
5bde6457b1
commit
36387d97ad
+1
@@ -29,6 +29,7 @@ enum class CompilationResultCategory(val code: Int) {
|
||||
IC_COMPILE_ITERATION(0),
|
||||
BUILD_REPORT_LINES(1),
|
||||
VERBOSE_BUILD_REPORT_LINES(2),
|
||||
BUILD_METRICS(3)
|
||||
}
|
||||
|
||||
interface CompilationResultsAsync {
|
||||
|
||||
@@ -21,6 +21,9 @@ import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.vfs.impl.ZipHandler
|
||||
import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem
|
||||
import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
|
||||
import org.jetbrains.kotlin.build.report.BuildReporter
|
||||
import org.jetbrains.kotlin.build.report.RemoteBuildReporter
|
||||
import org.jetbrains.kotlin.build.report.RemoteReporter
|
||||
import org.jetbrains.kotlin.cli.common.CLICompiler
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY
|
||||
@@ -286,7 +289,7 @@ abstract class CompileServiceImplBase(
|
||||
createMessageCollector: (ServicesFacadeT, CompilationOptions) -> MessageCollector,
|
||||
createReporter: (ServicesFacadeT, CompilationOptions) -> DaemonMessageReporter,
|
||||
createServices: (JpsServicesFacadeT, EventManager, Profiler) -> Services,
|
||||
getICReporter: (ServicesFacadeT, CompilationResultsT?, IncrementalCompilationOptions) -> RemoteICReporter
|
||||
getICReporter: (ServicesFacadeT, CompilationResultsT?, IncrementalCompilationOptions) -> RemoteBuildReporter
|
||||
) = kotlin.run {
|
||||
val messageCollector = createMessageCollector(servicesFacade, compilationOptions)
|
||||
val daemonReporter = createReporter(servicesFacade, compilationOptions)
|
||||
@@ -514,7 +517,7 @@ abstract class CompileServiceImplBase(
|
||||
args: K2JSCompilerArguments,
|
||||
incrementalCompilationOptions: IncrementalCompilationOptions,
|
||||
compilerMessageCollector: MessageCollector,
|
||||
reporter: RemoteICReporter
|
||||
reporter: RemoteBuildReporter
|
||||
): ExitCode {
|
||||
val allKotlinFiles = arrayListOf<File>()
|
||||
val freeArgsWithoutKotlinFiles = arrayListOf<String>()
|
||||
@@ -554,7 +557,7 @@ abstract class CompileServiceImplBase(
|
||||
k2jvmArgs: K2JVMCompilerArguments,
|
||||
incrementalCompilationOptions: IncrementalCompilationOptions,
|
||||
compilerMessageCollector: MessageCollector,
|
||||
reporter: RemoteICReporter
|
||||
reporter: RemoteBuildReporter
|
||||
): ExitCode {
|
||||
val allKotlinExtensions = (DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS +
|
||||
(incrementalCompilationOptions.kotlinScriptExtensions ?: emptyArray())).distinct()
|
||||
@@ -784,7 +787,7 @@ class CompileServiceImpl(
|
||||
createMessageCollector = ::CompileServicesFacadeMessageCollector,
|
||||
createReporter = ::DaemonMessageReporter,
|
||||
createServices = this::createCompileServices,
|
||||
getICReporter = { a, b, c -> getICReporter(a, b!!, c)}
|
||||
getICReporter = { a, b, c -> getBuildReporter(a, b!!, c)}
|
||||
)
|
||||
|
||||
override fun leaseReplSession(
|
||||
|
||||
@@ -8,23 +8,19 @@ package org.jetbrains.kotlin.daemon.report
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.daemon.common.CompilationResultCategory
|
||||
import org.jetbrains.kotlin.daemon.common.CompilationResults
|
||||
import org.jetbrains.kotlin.incremental.ICReporterBase
|
||||
import org.jetbrains.kotlin.build.report.ICReporterBase
|
||||
import org.jetbrains.kotlin.build.report.RemoteICReporter
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
// todo: sync BuildReportICReporterAsync
|
||||
internal class BuildReportICReporter(
|
||||
private val compilationResults: CompilationResults,
|
||||
rootDir: File,
|
||||
private val isVerbose: Boolean = false,
|
||||
// todo: default value
|
||||
// todo: sync BuildReportICReporterAsync
|
||||
private val reportMetrics: Boolean = true
|
||||
private val isVerbose: Boolean = false
|
||||
) : ICReporterBase(rootDir), RemoteICReporter {
|
||||
private val icLogLines = arrayListOf<String>()
|
||||
private val recompilationReason = HashMap<File, String>()
|
||||
private val rootMetric = Metric("<root>", 0)
|
||||
private val metrics = ArrayDeque<Metric>().apply { add(rootMetric) }
|
||||
|
||||
override fun report(message: () -> String) {
|
||||
icLogLines.add(message())
|
||||
@@ -36,30 +32,6 @@ internal class BuildReportICReporter(
|
||||
}
|
||||
}
|
||||
|
||||
override fun startMeasure(metric: String, startNs: Long) {
|
||||
if (!reportMetrics) return
|
||||
|
||||
val newMetric = Metric(metric, startNs)
|
||||
if (metrics.isNotEmpty()) {
|
||||
metrics.peekLast().children.add(newMetric)
|
||||
}
|
||||
metrics.addLast(newMetric)
|
||||
}
|
||||
|
||||
override fun endMeasure(metric: String, endNs: Long) {
|
||||
if (!reportMetrics) return
|
||||
|
||||
while (metrics.isNotEmpty()) {
|
||||
val lastMetric = metrics.peekLast()
|
||||
if (lastMetric.name == metric) {
|
||||
lastMetric.endNs = endNs
|
||||
break
|
||||
} else {
|
||||
metrics.removeLast()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun reportCompileIteration(incremental: Boolean, sourceFiles: Collection<File>, exitCode: ExitCode) {
|
||||
if (!incremental) return
|
||||
|
||||
@@ -76,25 +48,6 @@ internal class BuildReportICReporter(
|
||||
}
|
||||
|
||||
override fun flush() {
|
||||
if (reportMetrics) {
|
||||
icLogLines.add("Performance metrics:")
|
||||
reportMetric(rootMetric)
|
||||
}
|
||||
|
||||
compilationResults.add(CompilationResultCategory.BUILD_REPORT_LINES.code, icLogLines)
|
||||
}
|
||||
|
||||
private fun reportMetric(metric: Metric, level: Int = 0) {
|
||||
if (level > 0) {
|
||||
val timeMs = metric.endNs?.let { (it - metric.startNs) / 1_000_000L }
|
||||
icLogLines.add(" ".repeat(level) + "{perf_metric:${metric.name}} ${timeMs ?: "<unknown>"} ms")
|
||||
}
|
||||
|
||||
metric.children.forEach { reportMetric(it, level + 1) }
|
||||
}
|
||||
}
|
||||
|
||||
private class Metric(val name: String, val startNs: Long) {
|
||||
var endNs: Long? = null
|
||||
val children = ArrayList<Metric>()
|
||||
}
|
||||
+2
-1
@@ -9,7 +9,8 @@ import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.daemon.common.CompilationResultCategory
|
||||
import org.jetbrains.kotlin.daemon.common.CompilationResults
|
||||
import org.jetbrains.kotlin.daemon.common.CompileIterationResult
|
||||
import org.jetbrains.kotlin.incremental.ICReporterBase
|
||||
import org.jetbrains.kotlin.build.report.ICReporterBase
|
||||
import org.jetbrains.kotlin.build.report.RemoteICReporter
|
||||
import java.io.File
|
||||
|
||||
internal class CompileIterationICReporter(
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.daemon.report
|
||||
|
||||
import org.jetbrains.kotlin.build.report.RemoteICReporter
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import java.io.File
|
||||
|
||||
internal class CompositeICReporter(private val reporters: Iterable<RemoteICReporter>) :
|
||||
RemoteICReporter {
|
||||
internal class CompositeICReporter(private val reporters: Iterable<RemoteICReporter>) : RemoteICReporter {
|
||||
override fun report(message: () -> String) {
|
||||
reporters.forEach { it.report(message) }
|
||||
}
|
||||
@@ -34,14 +34,6 @@ internal class CompositeICReporter(private val reporters: Iterable<RemoteICRepor
|
||||
reporters.forEach { it.reportMarkDirty(affectedFiles, reason) }
|
||||
}
|
||||
|
||||
override fun startMeasure(metric: String, startNs: Long) {
|
||||
reporters.forEach { it.startMeasure(metric, startNs) }
|
||||
}
|
||||
|
||||
override fun endMeasure(metric: String, endNs: Long) {
|
||||
reporters.forEach { it.endMeasure(metric, endNs) }
|
||||
}
|
||||
|
||||
override fun flush() {
|
||||
reporters.forEach { it.flush() }
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ package org.jetbrains.kotlin.daemon.report
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.daemon.common.*
|
||||
import org.jetbrains.kotlin.incremental.ICReporterBase
|
||||
import org.jetbrains.kotlin.build.report.ICReporterBase
|
||||
import org.jetbrains.kotlin.build.report.RemoteICReporter
|
||||
import java.io.File
|
||||
|
||||
internal class DebugMessagesICReporter(
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.daemon.report
|
||||
|
||||
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
|
||||
import org.jetbrains.kotlin.build.report.metrics.RemoteBuildMetricsReporter
|
||||
import org.jetbrains.kotlin.daemon.common.CompilationResultCategory
|
||||
import org.jetbrains.kotlin.daemon.common.CompilationResults
|
||||
|
||||
class RemoteBuildMetricsReporterAdapter(
|
||||
private val delegate: BuildMetricsReporter,
|
||||
private val shouldReport: Boolean,
|
||||
private val compilationResults: CompilationResults
|
||||
) :
|
||||
BuildMetricsReporter by delegate,
|
||||
RemoteBuildMetricsReporter {
|
||||
|
||||
override fun flush() {
|
||||
if (shouldReport) {
|
||||
val metrics = delegate.getMetrics()
|
||||
compilationResults.add(CompilationResultCategory.BUILD_METRICS.code, metrics)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.daemon.report
|
||||
|
||||
import org.jetbrains.kotlin.incremental.ICReporter
|
||||
|
||||
interface RemoteICReporter : ICReporter {
|
||||
fun flush()
|
||||
}
|
||||
+21
-8
@@ -9,8 +9,14 @@ import kotlinx.coroutines.*
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.daemon.common.*
|
||||
import org.jetbrains.kotlin.daemon.report.CompositeICReporter
|
||||
import org.jetbrains.kotlin.daemon.report.RemoteICReporter
|
||||
import org.jetbrains.kotlin.incremental.ICReporterBase
|
||||
import org.jetbrains.kotlin.build.report.ICReporterBase
|
||||
import org.jetbrains.kotlin.build.report.RemoteBuildReporter
|
||||
import org.jetbrains.kotlin.build.report.RemoteICReporter
|
||||
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
|
||||
import org.jetbrains.kotlin.build.report.metrics.DoNothingBuildMetricsReporter
|
||||
import org.jetbrains.kotlin.build.report.metrics.RemoteBuildMetricsReporter
|
||||
import org.jetbrains.kotlin.daemon.report.BuildReportICReporter
|
||||
import org.jetbrains.kotlin.daemon.report.CompileIterationICReporter
|
||||
import java.io.File
|
||||
|
||||
internal class DebugMessagesICReporterAsync(
|
||||
@@ -106,7 +112,7 @@ fun getICReporterAsync(
|
||||
servicesFacade: CompilerServicesFacadeBaseAsync,
|
||||
compilationResults: CompilationResultsAsync?,
|
||||
compilationOptions: IncrementalCompilationOptions
|
||||
): RemoteICReporter {
|
||||
): RemoteBuildReporter {
|
||||
val root = compilationOptions.modulesInfo.projectRoot
|
||||
val reporters = ArrayList<RemoteICReporter>()
|
||||
|
||||
@@ -120,19 +126,26 @@ fun getICReporterAsync(
|
||||
.mapNotNullTo(HashSet()) { resultCode ->
|
||||
CompilationResultCategory.values().getOrNull(resultCode)
|
||||
}
|
||||
requestedResults.mapTo(reporters) { requestedResult ->
|
||||
for (requestedResult in requestedResults) {
|
||||
when (requestedResult) {
|
||||
CompilationResultCategory.IC_COMPILE_ITERATION -> {
|
||||
CompileIterationICReporterAsync(compilationResults)
|
||||
reporters.add(CompileIterationICReporterAsync(compilationResults))
|
||||
}
|
||||
CompilationResultCategory.BUILD_REPORT_LINES -> {
|
||||
BuildReportICReporterAsync(compilationResults, root)
|
||||
reporters.add(BuildReportICReporterAsync(compilationResults, root))
|
||||
}
|
||||
CompilationResultCategory.VERBOSE_BUILD_REPORT_LINES -> {
|
||||
BuildReportICReporterAsync(compilationResults, root, isVerbose = true)
|
||||
reporters.add(BuildReportICReporterAsync(compilationResults, root, isVerbose = true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CompositeICReporter(reporters)
|
||||
val icReporter = CompositeICReporter(reporters)
|
||||
val metricsReporter = DoNothingRemoteBuildMetricsReporter
|
||||
return RemoteBuildReporter(icReporter, metricsReporter)
|
||||
}
|
||||
|
||||
object DoNothingRemoteBuildMetricsReporter : BuildMetricsReporter by DoNothingBuildMetricsReporter, RemoteBuildMetricsReporter {
|
||||
override fun flush() {
|
||||
}
|
||||
}
|
||||
@@ -16,15 +16,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.daemon.report
|
||||
|
||||
import org.jetbrains.kotlin.build.report.RemoteBuildReporter
|
||||
import org.jetbrains.kotlin.build.report.RemoteICReporter
|
||||
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporterImpl
|
||||
import org.jetbrains.kotlin.build.report.metrics.DoNothingBuildMetricsReporter
|
||||
import org.jetbrains.kotlin.daemon.common.*
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
fun getICReporter(
|
||||
fun getBuildReporter(
|
||||
servicesFacade: CompilerServicesFacadeBase,
|
||||
compilationResults: CompilationResults,
|
||||
compilationOptions: IncrementalCompilationOptions
|
||||
): RemoteICReporter {
|
||||
): RemoteBuildReporter {
|
||||
val root = compilationOptions.modulesInfo.projectRoot
|
||||
val reporters = ArrayList<RemoteICReporter>()
|
||||
|
||||
@@ -38,21 +41,25 @@ fun getICReporter(
|
||||
.mapNotNullTo(HashSet()) { resultCode ->
|
||||
CompilationResultCategory.values().getOrNull(resultCode)
|
||||
}
|
||||
requestedResults.mapTo(reporters) { requestedResult ->
|
||||
for (requestedResult in requestedResults) {
|
||||
when (requestedResult) {
|
||||
CompilationResultCategory.IC_COMPILE_ITERATION -> {
|
||||
CompileIterationICReporter(compilationResults)
|
||||
reporters.add(CompileIterationICReporter(compilationResults))
|
||||
}
|
||||
CompilationResultCategory.BUILD_REPORT_LINES -> {
|
||||
BuildReportICReporter(compilationResults, root)
|
||||
reporters.add(BuildReportICReporter(compilationResults, root))
|
||||
}
|
||||
CompilationResultCategory.VERBOSE_BUILD_REPORT_LINES -> {
|
||||
BuildReportICReporter(compilationResults, root, isVerbose = true)
|
||||
reporters.add(BuildReportICReporter(compilationResults, root, isVerbose = true))
|
||||
}
|
||||
}
|
||||
}
|
||||
val areBuildMetricsNeeded = CompilationResultCategory.BUILD_METRICS in requestedResults
|
||||
val metricsReporter =
|
||||
(if (areBuildMetricsNeeded) BuildMetricsReporterImpl() else DoNothingBuildMetricsReporter)
|
||||
.let { RemoteBuildMetricsReporterAdapter(it, areBuildMetricsNeeded, compilationResults) }
|
||||
|
||||
return CompositeICReporter(reporters)
|
||||
return RemoteBuildReporter(CompositeICReporter(reporters), metricsReporter)
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user