Add compiler performance metrics
WIP
This commit is contained in:
committed by
nataliya.valtman
parent
64da19cb2d
commit
9becb2c468
@@ -99,7 +99,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
|||||||
doMain(new K2JSCompiler(), args);
|
doMain(new K2JSCompiler(), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final K2JSCompilerPerformanceManager performanceManager = new K2JSCompilerPerformanceManager();
|
final K2JSCompilerPerformanceManager performanceManager = new K2JSCompilerPerformanceManager();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
@@ -564,7 +564,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
protected CommonCompilerPerformanceManager getPerformanceManager() {
|
public CommonCompilerPerformanceManager getDefaultPerformanceManager() {
|
||||||
return performanceManager;
|
return performanceManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ enum class ProduceKind {
|
|||||||
|
|
||||||
class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||||
|
|
||||||
override val performanceManager: CommonCompilerPerformanceManager =
|
override val defaultPerformanceManager: CommonCompilerPerformanceManager =
|
||||||
object : CommonCompilerPerformanceManager("Kotlin to JS (IR) Compiler") {}
|
object : CommonCompilerPerformanceManager("Kotlin to JS (IR) Compiler") {}
|
||||||
|
|
||||||
override fun createArguments(): K2JSCompilerArguments {
|
override fun createArguments(): K2JSCompilerArguments {
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ import java.io.PrintStream
|
|||||||
|
|
||||||
abstract class CLICompiler<A : CommonCompilerArguments> : CLITool<A>() {
|
abstract class CLICompiler<A : CommonCompilerArguments> : CLITool<A>() {
|
||||||
|
|
||||||
protected abstract val performanceManager: CommonCompilerPerformanceManager
|
abstract val defaultPerformanceManager: CommonCompilerPerformanceManager
|
||||||
|
|
||||||
protected open fun createPerformanceManager(arguments: A, services: Services): CommonCompilerPerformanceManager = performanceManager
|
protected open fun createPerformanceManager(arguments: A, services: Services): CommonCompilerPerformanceManager = defaultPerformanceManager
|
||||||
|
|
||||||
// Used in CompilerRunnerUtil#invokeExecMethod, in Eclipse plugin (KotlinCLICompiler) and in kotlin-gradle-plugin (GradleCompilerRunner)
|
// Used in CompilerRunnerUtil#invokeExecMethod, in Eclipse plugin (KotlinCLICompiler) and in kotlin-gradle-plugin (GradleCompilerRunner)
|
||||||
fun execAndOutputXml(errStream: PrintStream, services: Services, vararg args: String): ExitCode {
|
fun execAndOutputXml(errStream: PrintStream, services: Services, vararg args: String): ExitCode {
|
||||||
|
|||||||
+21
-3
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.cli.common
|
package org.jetbrains.kotlin.cli.common
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.util.PerformanceCounter
|
import org.jetbrains.kotlin.util.PerformanceCounter
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.management.GarbageCollectorMXBean
|
import java.lang.management.GarbageCollectorMXBean
|
||||||
@@ -26,6 +28,7 @@ abstract class CommonCompilerPerformanceManager(private val presentableName: Str
|
|||||||
private var irGenerationStart: Long = 0
|
private var irGenerationStart: Long = 0
|
||||||
|
|
||||||
private var targetDescription: String? = null
|
private var targetDescription: String? = null
|
||||||
|
private var sourceFiles: List<KtFile>? = null
|
||||||
protected var files: Int? = null
|
protected var files: Int? = null
|
||||||
protected var lines: Int? = null
|
protected var lines: Int? = null
|
||||||
|
|
||||||
@@ -42,12 +45,19 @@ abstract class CommonCompilerPerformanceManager(private val presentableName: Str
|
|||||||
|
|
||||||
private fun deltaTime(start: Long): Long = PerformanceCounter.currentTime() - start
|
private fun deltaTime(start: Long): Long = PerformanceCounter.currentTime() - start
|
||||||
|
|
||||||
open fun notifyCompilerInitialized(files: Int, lines: Int, targetDescription: String) {
|
private fun countLinesOfCode(sourceFiles: List<KtFile>): Int =
|
||||||
|
sourceFiles.sumBy { sourceFile ->
|
||||||
|
val text = sourceFile.text
|
||||||
|
StringUtil.getLineBreakCount(text) + (if (StringUtil.endsWithLineBreak(text)) 0 else 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun notifyCompilerInitialized(sourceFiles: List<KtFile>, targetDescription: String) {
|
||||||
if (!isEnabled) return
|
if (!isEnabled) return
|
||||||
recordInitializationTime()
|
recordInitializationTime()
|
||||||
|
|
||||||
this.files = files
|
this.sourceFiles = sourceFiles
|
||||||
this.lines = lines
|
this.files = sourceFiles.size
|
||||||
|
this.lines = countLinesOfCode(sourceFiles)
|
||||||
this.targetDescription = targetDescription
|
this.targetDescription = targetDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,4 +170,12 @@ abstract class CommonCompilerPerformanceManager(private val presentableName: Str
|
|||||||
private data class GCData(val name: String, val collectionTime: Long, val collectionCount: Long) {
|
private data class GCData(val name: String, val collectionTime: Long, val collectionCount: Long) {
|
||||||
constructor(bean: GarbageCollectorMXBean) : this(bean.name, bean.collectionTime, bean.collectionCount)
|
constructor(bean: GarbageCollectorMXBean) : this(bean.name, bean.collectionTime, bean.collectionCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun renderCompilerPerformance(): String {
|
||||||
|
val relevantMeasurements = getMeasurementResults().filter {
|
||||||
|
it is CompilerInitializationMeasurement || it is CodeAnalysisMeasurement || it is CodeGenerationMeasurement || it is PerformanceCounterMeasurement
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Compiler perf stats:\n" + relevantMeasurements.joinToString(separator = "\n") { " ${it.render()}" }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
|
|
||||||
val sourceFiles = environment.getSourceFiles()
|
val sourceFiles = environment.getSourceFiles()
|
||||||
configuration[CLIConfigurationKeys.PERF_MANAGER]?.notifyCompilerInitialized(
|
configuration[CLIConfigurationKeys.PERF_MANAGER]?.notifyCompilerInitialized(
|
||||||
sourceFiles.size, environment.countLinesOfCode(sourceFiles), targetDescription
|
sourceFiles, targetDescription
|
||||||
)
|
)
|
||||||
|
|
||||||
return if (messageCollector.hasErrors()) null else environment
|
return if (messageCollector.hasErrors()) null else environment
|
||||||
@@ -274,8 +274,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override val performanceManager: CommonCompilerPerformanceManager
|
override val defaultPerformanceManager: CommonCompilerPerformanceManager = K2JVMCompilerPerformanceManager()
|
||||||
get() = error("Unsupported")
|
|
||||||
|
|
||||||
override fun createPerformanceManager(arguments: K2JVMCompilerArguments, services: Services): CommonCompilerPerformanceManager {
|
override fun createPerformanceManager(arguments: K2JVMCompilerArguments, services: Services): CommonCompilerPerformanceManager {
|
||||||
val externalManager = services[CommonCompilerPerformanceManager::class.java]
|
val externalManager = services[CommonCompilerPerformanceManager::class.java]
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import java.io.File
|
|||||||
|
|
||||||
class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
|
class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
|
||||||
|
|
||||||
override val performanceManager = K2MetadataCompilerPerformanceManager()
|
override val defaultPerformanceManager: CommonCompilerPerformanceManager = K2MetadataCompilerPerformanceManager()
|
||||||
|
|
||||||
override fun createArguments() = K2MetadataCompilerArguments()
|
override fun createArguments() = K2MetadataCompilerArguments()
|
||||||
|
|
||||||
@@ -58,6 +58,7 @@ class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
|
|||||||
paths: KotlinPaths?
|
paths: KotlinPaths?
|
||||||
): ExitCode {
|
): ExitCode {
|
||||||
val collector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
val collector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||||
|
val performanceManager = configuration.getNotNull(CLIConfigurationKeys.PERF_MANAGER)
|
||||||
|
|
||||||
val pluginLoadResult = loadPlugins(paths, arguments, configuration)
|
val pluginLoadResult = loadPlugins(paths, arguments, configuration)
|
||||||
if (pluginLoadResult != ExitCode.OK) return pluginLoadResult
|
if (pluginLoadResult != ExitCode.OK) return pluginLoadResult
|
||||||
@@ -70,7 +71,8 @@ class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
|
|||||||
configuration.addJvmClasspathRoots(arguments.classpath!!.split(File.pathSeparatorChar).map(::File))
|
configuration.addJvmClasspathRoots(arguments.classpath!!.split(File.pathSeparatorChar).map(::File))
|
||||||
}
|
}
|
||||||
|
|
||||||
configuration.put(CommonConfigurationKeys.MODULE_NAME, arguments.moduleName ?: JvmProtoBufUtil.DEFAULT_MODULE_NAME)
|
val moduleName = arguments.moduleName ?: JvmProtoBufUtil.DEFAULT_MODULE_NAME
|
||||||
|
configuration.put(CommonConfigurationKeys.MODULE_NAME, moduleName)
|
||||||
|
|
||||||
configuration.put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, arguments.allowKotlinPackage)
|
configuration.put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, arguments.allowKotlinPackage)
|
||||||
|
|
||||||
@@ -93,6 +95,9 @@ class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
|
|||||||
val environment =
|
val environment =
|
||||||
KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.METADATA_CONFIG_FILES)
|
KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.METADATA_CONFIG_FILES)
|
||||||
|
|
||||||
|
val mode = if(arguments.expectActualLinker) "KLib" else "metadata"
|
||||||
|
performanceManager.notifyCompilerInitialized(environment.getSourceFiles(), "$mode mode for $moduleName module")
|
||||||
|
|
||||||
if (environment.getSourceFiles().isEmpty()) {
|
if (environment.getSourceFiles().isEmpty()) {
|
||||||
if (arguments.version) {
|
if (arguments.version) {
|
||||||
return ExitCode.OK
|
return ExitCode.OK
|
||||||
|
|||||||
@@ -48,20 +48,25 @@ import java.io.File
|
|||||||
internal class K2MetadataKlibSerializer(private val metadataVersion: BuiltInsBinaryVersion) {
|
internal class K2MetadataKlibSerializer(private val metadataVersion: BuiltInsBinaryVersion) {
|
||||||
fun serialize(environment: KotlinCoreEnvironment) {
|
fun serialize(environment: KotlinCoreEnvironment) {
|
||||||
val configuration = environment.configuration
|
val configuration = environment.configuration
|
||||||
|
val performanceManager = configuration.getNotNull(CLIConfigurationKeys.PERF_MANAGER)
|
||||||
|
|
||||||
val dependencyContainer = KlibMetadataDependencyContainer(
|
val dependencyContainer = KlibMetadataDependencyContainer(
|
||||||
configuration,
|
configuration,
|
||||||
LockBasedStorageManager("K2MetadataKlibSerializer")
|
LockBasedStorageManager("K2MetadataKlibSerializer")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
performanceManager.notifyAnalysisStarted()
|
||||||
val analyzer = runCommonAnalysisForSerialization(environment, true, dependencyContainer)
|
val analyzer = runCommonAnalysisForSerialization(environment, true, dependencyContainer)
|
||||||
|
performanceManager.notifyAnalysisFinished()
|
||||||
|
|
||||||
if (analyzer == null || analyzer.hasErrors()) return
|
if (analyzer == null || analyzer.hasErrors()) return
|
||||||
|
|
||||||
val (_, moduleDescriptor) = analyzer.analysisResult
|
val (_, moduleDescriptor) = analyzer.analysisResult
|
||||||
|
|
||||||
|
performanceManager.notifyGenerationStarted()
|
||||||
val destDir = checkNotNull(environment.destDir)
|
val destDir = checkNotNull(environment.destDir)
|
||||||
performSerialization(configuration, moduleDescriptor, destDir, environment.project)
|
performSerialization(configuration, moduleDescriptor, destDir, environment.project)
|
||||||
|
performanceManager.notifyGenerationFinished()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun performSerialization(
|
private fun performSerialization(
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.cli.metadata
|
package org.jetbrains.kotlin.cli.metadata
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
@@ -39,14 +40,20 @@ open class MetadataSerializer(
|
|||||||
protected var totalFiles = 0
|
protected var totalFiles = 0
|
||||||
|
|
||||||
fun serialize(environment: KotlinCoreEnvironment) {
|
fun serialize(environment: KotlinCoreEnvironment) {
|
||||||
|
val performanceManager = environment.configuration.getNotNull(CLIConfigurationKeys.PERF_MANAGER)
|
||||||
|
|
||||||
|
performanceManager.notifyAnalysisStarted()
|
||||||
val analyzer = runCommonAnalysisForSerialization(environment, dependOnOldBuiltIns, dependencyContainer = null)
|
val analyzer = runCommonAnalysisForSerialization(environment, dependOnOldBuiltIns, dependencyContainer = null)
|
||||||
|
performanceManager.notifyAnalysisFinished()
|
||||||
|
|
||||||
if (analyzer == null || analyzer.hasErrors()) return
|
if (analyzer == null || analyzer.hasErrors()) return
|
||||||
|
|
||||||
val (bindingContext, moduleDescriptor) = analyzer.analysisResult
|
val (bindingContext, moduleDescriptor) = analyzer.analysisResult
|
||||||
|
|
||||||
|
performanceManager.notifyGenerationStarted()
|
||||||
val destDir = checkNotNull(environment.destDir)
|
val destDir = checkNotNull(environment.destDir)
|
||||||
performSerialization(environment.getSourceFiles(), bindingContext, moduleDescriptor, destDir, environment.project)
|
performSerialization(environment.getSourceFiles(), bindingContext, moduleDescriptor, destDir, environment.project)
|
||||||
|
performanceManager.notifyGenerationFinished()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun performSerialization(
|
protected open fun performSerialization(
|
||||||
|
|||||||
@@ -326,7 +326,12 @@ abstract class CompileServiceImplBase(
|
|||||||
}
|
}
|
||||||
CompilerMode.NON_INCREMENTAL_COMPILER -> {
|
CompilerMode.NON_INCREMENTAL_COMPILER -> {
|
||||||
doCompile(sessionId, daemonReporter, tracer = null) { _, _ ->
|
doCompile(sessionId, daemonReporter, tracer = null) { _, _ ->
|
||||||
compiler.exec(messageCollector, Services.EMPTY, k2PlatformArgs)
|
val exitCode = compiler.exec(messageCollector, Services.EMPTY, k2PlatformArgs)
|
||||||
|
|
||||||
|
val perfString = compiler.defaultPerformanceManager.renderCompilerPerformance()
|
||||||
|
(compilationResults as CompilationResults).add(CompilationResultCategory.BUILD_REPORT_LINES.code, arrayListOf(perfString))
|
||||||
|
|
||||||
|
exitCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CompilerMode.INCREMENTAL_COMPILER -> {
|
CompilerMode.INCREMENTAL_COMPILER -> {
|
||||||
|
|||||||
+3
-1
@@ -186,11 +186,13 @@ class IncrementalJsCompilerRunner(
|
|||||||
): ExitCode {
|
): ExitCode {
|
||||||
val freeArgsBackup = args.freeArgs
|
val freeArgsBackup = args.freeArgs
|
||||||
|
|
||||||
|
val compiler = K2JSCompiler()
|
||||||
return try {
|
return try {
|
||||||
args.freeArgs += sourcesToCompile.map { it.absolutePath }
|
args.freeArgs += sourcesToCompile.map { it.absolutePath }
|
||||||
K2JSCompiler().exec(messageCollector, services, args)
|
compiler.exec(messageCollector, services, args)
|
||||||
} finally {
|
} finally {
|
||||||
args.freeArgs = freeArgsBackup
|
args.freeArgs = freeArgsBackup
|
||||||
|
reporter.report { compiler.defaultPerformanceManager.renderCompilerPerformance() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
@@ -433,6 +433,7 @@ class IncrementalJvmCompilerRunner(
|
|||||||
args.allowNoSourceFiles = true
|
args.allowNoSourceFiles = true
|
||||||
val exitCode = compiler.exec(messageCollector, services, args)
|
val exitCode = compiler.exec(messageCollector, services, args)
|
||||||
args.freeArgs = freeArgsBackup
|
args.freeArgs = freeArgsBackup
|
||||||
|
reporter.report { compiler.defaultPerformanceManager.renderCompilerPerformance() }
|
||||||
return exitCode
|
return exitCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
|
|||||||
|
|
||||||
override fun createMetadataVersion(versionArray: IntArray): BinaryVersion = KlibMetadataVersion(*versionArray)
|
override fun createMetadataVersion(versionArray: IntArray): BinaryVersion = KlibMetadataVersion(*versionArray)
|
||||||
|
|
||||||
override val performanceManager:CommonCompilerPerformanceManager by lazy {
|
override val defaultPerformanceManager: CommonCompilerPerformanceManager by lazy {
|
||||||
K2NativeCompilerPerformanceManager()
|
K2NativeCompilerPerformanceManager()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -270,8 +270,12 @@ internal class GradleKotlinCompilerWork @Inject constructor(
|
|||||||
kotlinScriptExtensions = kotlinScriptExtensions
|
kotlinScriptExtensions = kotlinScriptExtensions
|
||||||
)
|
)
|
||||||
val servicesFacade = GradleCompilerServicesFacadeImpl(log, bufferingMessageCollector)
|
val servicesFacade = GradleCompilerServicesFacadeImpl(log, bufferingMessageCollector)
|
||||||
|
val compilationResults = GradleCompilationResults(log, projectRootFile)
|
||||||
return metrics.measure(BuildTime.NON_INCREMENTAL_COMPILATION_DAEMON) {
|
return metrics.measure(BuildTime.NON_INCREMENTAL_COMPILATION_DAEMON) {
|
||||||
daemon.compile(sessionId, compilerArgs, compilationOptions, servicesFacade, compilationResults = null)
|
daemon.compile(sessionId, compilerArgs, compilationOptions, servicesFacade, compilationResults)
|
||||||
|
}.also {
|
||||||
|
metrics.addMetrics(compilationResults.buildMetrics)
|
||||||
|
icLogLines = compilationResults.icLogLines
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user