Rewrite performance statistics collection

This commit introduces notion of 'PerformanceManager' in CLI, suitable
for collecting performance metrics of the compiler. It:

- provides `notifyX{Started/Finished}` API, where 'X' is some
measurable event (previously there were just ad hoc manual time
measurements using System.nanoTime() and stuff)

- collects measurements, so that later they can be reported in an
appropriate way (previously measurements were reported immediately to
MessageCollector as plain strings)

- allows overriding to collect metrics, specific for just one target
platform compilation

Also, common logic of compiler performance statistics collection was
extracted from platform-compilers (K2JVMCompiler) to common classes
(CLICompiler), to allow other platform-compilers (e.g. K2JSCompiler)
re-use it.
This commit is contained in:
Dmitry Savvinov
2018-03-29 11:37:00 +03:00
parent c3745c9040
commit 9996a1bc7e
14 changed files with 231 additions and 120 deletions
@@ -150,6 +150,9 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
)
var properIeee754Comparisons by FreezableVar(false)
@Argument(value = "-Xreport-perf", description = "Report detailed performance statistics")
var reportPerf: Boolean by FreezableVar(false)
open fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
return HashMap<AnalysisFlag<*>, Any>().apply {
put(AnalysisFlag.skipMetadataVersionCheck, skipMetadataVersionCheck)
@@ -124,9 +124,6 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
)
var constructorCallNormalizationMode: String? by FreezableVar(JVMConstructorCallNormalizationMode.DEFAULT.description)
@Argument(value = "-Xreport-perf", description = "Report detailed performance statistics")
var reportPerf: Boolean by FreezableVar(false)
@Argument(
value = "-Xbuild-file",
deprecatedName = "-module",
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.cli.common;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
import kotlin.collections.ArraysKt;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -28,23 +27,23 @@ import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector;
import org.jetbrains.kotlin.cli.common.messages.MessageCollector;
import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil;
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer;
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler;
import org.jetbrains.kotlin.cli.jvm.compiler.CompilerJarLocator;
import org.jetbrains.kotlin.config.*;
import org.jetbrains.kotlin.config.CommonConfigurationKeys;
import org.jetbrains.kotlin.config.CommonConfigurationKeysKt;
import org.jetbrains.kotlin.config.CompilerConfiguration;
import org.jetbrains.kotlin.config.Services;
import org.jetbrains.kotlin.progress.CompilationCanceledException;
import org.jetbrains.kotlin.progress.CompilationCanceledStatus;
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
import org.jetbrains.kotlin.utils.KotlinPaths;
import org.jetbrains.kotlin.utils.KotlinPathsFromHomeDir;
import org.jetbrains.kotlin.utils.PathUtil;
import org.jetbrains.kotlin.utils.StringsKt;
import java.io.File;
import java.io.PrintStream;
import java.util.List;
import java.util.Map;
import static org.jetbrains.kotlin.cli.common.ExitCode.*;
import static org.jetbrains.kotlin.cli.common.ExitCode.COMPILATION_ERROR;
import static org.jetbrains.kotlin.cli.common.ExitCode.INTERNAL_ERROR;
import static org.jetbrains.kotlin.cli.common.environment.UtilKt.setIdeaIoUseFallback;
import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*;
@@ -69,11 +68,16 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
@NotNull
@Override
public ExitCode execImpl(@NotNull MessageCollector messageCollector, @NotNull Services services, @NotNull A arguments) {
CommonCompilerPerformanceManager performanceManager = getPerformanceManager();
if (arguments.getReportPerf()) {
performanceManager.enableCollectingPerformanceStatistics();
}
GroupingMessageCollector groupingCollector = new GroupingMessageCollector(messageCollector, arguments.getAllWarningsAsErrors());
CompilerConfiguration configuration = new CompilerConfiguration();
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, groupingCollector);
configuration.put(CLIConfigurationKeys.PERF_MANAGER, performanceManager);
try {
setupCommonArgumentsAndServices(configuration, arguments, services);
setupPlatformSpecificArgumentsAndServices(configuration, arguments, services);
@@ -89,6 +93,14 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
try {
setIdeaIoUseFallback();
ExitCode code = doExecute(arguments, configuration, rootDisposable, paths);
performanceManager.notifyCompilationFinished();
if (arguments.getReportPerf()) {
performanceManager.getMeasurementResults().forEach(
it -> configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(INFO, "PERF: " + it.render(), null)
);
}
return groupingCollector.hasErrors() ? COMPILATION_ERROR : code;
}
catch (CompilationCanceledException e) {
@@ -212,4 +224,7 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
@NotNull Disposable rootDisposable,
@Nullable KotlinPaths paths
);
@NotNull
protected abstract CommonCompilerPerformanceManager getPerformanceManager();
}
@@ -27,8 +27,8 @@ public class CLIConfigurationKeys {
CompilerConfigurationKey.create("message collector");
public static final CompilerConfigurationKey<Boolean> ALLOW_KOTLIN_PACKAGE =
CompilerConfigurationKey.create("allow kotlin package");
public static final CompilerConfigurationKey<Boolean> REPORT_PERF =
CompilerConfigurationKey.create("report performance information");
public static final CompilerConfigurationKey<CommonCompilerPerformanceManager> PERF_MANAGER =
CompilerConfigurationKey.create("performance manager");
// Used in Eclipse plugin (see KotlinCLICompiler)
public static final CompilerConfigurationKey<String> INTELLIJ_PLUGIN_ROOT =
@@ -0,0 +1,79 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. 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.cli.common
import org.jetbrains.kotlin.util.PerformanceCounter
import java.lang.management.ManagementFactory
import java.util.concurrent.TimeUnit
abstract class CommonCompilerPerformanceManager(private val presentableName: String) {
protected val measurements: MutableList<PerformanceMeasurement> = mutableListOf()
protected var isEnabled: Boolean = false
private var initStartNanos = PerformanceCounter.currentTime()
private var analysisStart: Long = 0
private var generationStart: Long = 0
fun getMeasurementResults(): List<PerformanceMeasurement> = measurements
fun enableCollectingPerformanceStatistics() {
isEnabled = true
PerformanceCounter.setTimeCounterEnabled(true)
}
open fun notifyCompilerInitialized() {
if (!isEnabled) return
recordInitializationTime()
}
open fun notifyCompilationFinished() {
if (!isEnabled) return
recordGcTime()
recordJitCompilationTime()
recordPerfCountersMeasurements()
}
open fun notifyAnalysisStarted() {
analysisStart = PerformanceCounter.currentTime()
}
open fun notifyAnalysisFinished(files: Int, lines: Int, additionalDescription: String?) {
val time = PerformanceCounter.currentTime() - analysisStart
measurements += CodeAnalysisMeasurement(files, lines, TimeUnit.NANOSECONDS.toMillis(time), additionalDescription)
}
open fun notifyGenerationStarted() {
generationStart = PerformanceCounter.currentTime()
}
open fun notifyGenerationFinished(lines: Int, files: Int, additionalDescription: String) {
val time = PerformanceCounter.currentTime() - generationStart
measurements += CodeGenerationMeasurement(lines, files, TimeUnit.NANOSECONDS.toMillis(time), additionalDescription)
}
private fun recordGcTime() {
if (!isEnabled) return
ManagementFactory.getGarbageCollectorMXBeans().forEach {
measurements += GarbageCollectionMeasurement(it.name, it.collectionTime)
}
}
private fun recordJitCompilationTime() {
if (!isEnabled) return
val bean = ManagementFactory.getCompilationMXBean() ?: return
measurements += JitCompilationMeasurement(bean.totalCompilationTime)
}
private fun recordInitializationTime() {
val time = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - initStartNanos)
measurements += CompilerInitializationMeasurement(time)
}
private fun recordPerfCountersMeasurements() {
PerformanceCounter.report { s -> measurements += PerformanceCounterMeasurement(s) }
}
}
@@ -0,0 +1,50 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. 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.cli.common
interface PerformanceMeasurement {
fun render(): String
}
class JitCompilationMeasurement(private val milliseconds: Long) : PerformanceMeasurement {
override fun render(): String = "JIT time is $milliseconds ms"
}
class CompilerInitializationMeasurement(private val milliseconds: Long) : PerformanceMeasurement {
override fun render(): String = "INIT: Compiler initialized in $milliseconds ms"
}
class CodeAnalysisMeasurement(private val files: Int, val lines: Int, private val milliseconds: Long, private val description: String?) :
PerformanceMeasurement {
private val speed: Double = lines.toDouble() * 1000 / milliseconds
override fun render(): String =
"ANALYZE: $files files ($lines lines) ${description ?: ""}in $milliseconds ms - ${"%.3f".format(speed)} loc/s"
}
class CodeGenerationMeasurement(private val files: Int, val lines: Int, private val milliseconds: Long, private val description: String?) :
PerformanceMeasurement {
private val speed: Double = lines.toDouble() * 1000 / milliseconds
override fun render(): String =
"GENERATE: $files files ($lines lines) ${description}in $milliseconds ms - ${"%.3f".format(speed)} loc/s"
}
class GarbageCollectionMeasurement(private val garbageCollectionKind: String, private val milliseconds: Long) : PerformanceMeasurement {
override fun render(): String = "GC time for $garbageCollectionKind is $milliseconds ms"
}
class PerformanceCounterMeasurement(private val counterReport: String) : PerformanceMeasurement {
override fun render(): String = counterReport
}
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.analyzer.AnalysisResult;
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
import org.jetbrains.kotlin.cli.common.CLICompiler;
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys;
import org.jetbrains.kotlin.cli.common.CommonCompilerPerformanceManager;
import org.jetbrains.kotlin.cli.common.ExitCode;
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments;
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants;
@@ -95,6 +96,8 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
doMain(new K2JSCompiler(), args);
}
private final K2JSCompilerPerformanceManager performanceManager = new K2JSCompilerPerformanceManager();
@NotNull
@Override
public K2JSCompilerArguments createArguments() {
@@ -513,6 +516,11 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
return commonPath != null ? commonPath.getPath() : ".";
}
@NotNull
@Override
protected CommonCompilerPerformanceManager getPerformanceManager() {
return performanceManager;
}
private static MainCallParameters createMainCallParameters(String main) {
if (K2JsArgumentConstants.NO_CALL.equals(main)) {
@@ -528,4 +536,12 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
public String executableScriptFileName() {
return "kotlinc-js";
}
private static final class K2JSCompilerPerformanceManager extends CommonCompilerPerformanceManager {
public K2JSCompilerPerformanceManager() {
super("Kotlin to JS Compiler");
}
}
}
@@ -18,11 +18,7 @@ package org.jetbrains.kotlin.cli.jvm
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.cli.common.CLICompiler
import org.jetbrains.kotlin.cli.common.CLICompiler.getLibraryFromHome
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.CLITool
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.*
import org.jetbrains.kotlin.cli.common.ExitCode.*
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.*
@@ -47,22 +43,21 @@ import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
import org.jetbrains.kotlin.script.ScriptDefinitionProvider
import org.jetbrains.kotlin.script.StandardScriptDefinition
import org.jetbrains.kotlin.util.PerformanceCounter
import org.jetbrains.kotlin.utils.KotlinPaths
import org.jetbrains.kotlin.utils.PathUtil
import java.io.File
import java.lang.management.ManagementFactory
import java.util.concurrent.TimeUnit
import java.util.*
class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
private val performanceManager: K2JVMCompilerPerformanceManager = K2JVMCompilerPerformanceManager()
override fun doExecute(
arguments: K2JVMCompilerArguments,
configuration: CompilerConfiguration,
rootDisposable: Disposable,
paths: KotlinPaths?
): ExitCode {
PerformanceCounter.setTimeCounterEnabled(arguments.reportPerf)
val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
configureJdkHome(arguments, configuration, messageCollector).let {
@@ -208,12 +203,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
if (!it) return COMPILATION_ERROR
}
}
if (arguments.reportPerf) {
reportGCTime(configuration)
reportCompilationTime(configuration)
PerformanceCounter.report { s -> reportPerf(configuration, s) }
}
return OK
} catch (e: CompilationException) {
messageCollector.report(
@@ -225,6 +215,8 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
}
}
override fun getPerformanceManager(): CommonCompilerPerformanceManager = performanceManager
private fun loadPlugins(paths: KotlinPaths?, arguments: K2JVMCompilerArguments, configuration: CompilerConfiguration): ExitCode {
val pluginClasspaths = arguments.pluginClasspaths?.toMutableList() ?: ArrayList()
val pluginOptions = arguments.pluginOptions?.toMutableList() ?: ArrayList()
@@ -300,11 +292,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
if (initStartNanos != 0L) {
val initNanos = System.nanoTime() - initStartNanos
reportPerf(configuration, "INIT: Compiler initialized in " + TimeUnit.NANOSECONDS.toMillis(initNanos) + " ms")
initStartNanos = 0L
}
performanceManager.notifyCompilerInitialized()
return if (messageCollector.hasErrors()) null else environment
}
@@ -343,31 +331,14 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
override fun executableScriptFileName(): String = "kotlinc-jvm"
companion object {
private var initStartNanos = System.nanoTime()
private class K2JVMCompilerPerformanceManager : CommonCompilerPerformanceManager("Kotlin to JVM Compiler")
companion object {
@JvmStatic
fun main(args: Array<String>) {
CLITool.doMain(K2JVMCompiler(), args)
}
fun reportPerf(configuration: CompilerConfiguration, message: String) {
if (!configuration.getBoolean(CLIConfigurationKeys.REPORT_PERF)) return
configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(INFO, "PERF: $message")
}
fun reportGCTime(configuration: CompilerConfiguration) {
ManagementFactory.getGarbageCollectorMXBeans().forEach {
reportPerf(configuration, "GC time for ${it.name} is ${it.collectionTime} ms")
}
}
fun reportCompilationTime(configuration: CompilerConfiguration) {
val bean = ManagementFactory.getCompilationMXBean() ?: return
reportPerf(configuration, "JIT time is ${bean.totalCompilationTime} ms")
}
private fun putAdvancedOptions(configuration: CompilerConfiguration, arguments: K2JVMCompilerArguments) {
configuration.put(JVMConfigurationKeys.DISABLE_CALL_ASSERTIONS, arguments.noCallAssertions)
configuration.put(JVMConfigurationKeys.DISABLE_RECEIVER_ASSERTIONS, arguments.noReceiverAssertions)
@@ -403,7 +374,6 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
}
configuration.put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, arguments.allowKotlinPackage)
configuration.put(CLIConfigurationKeys.REPORT_PERF, arguments.reportPerf)
configuration.put(JVMConfigurationKeys.USE_SINGLE_MODULE, arguments.singleModule)
configuration.put(JVMConfigurationKeys.ADD_BUILT_INS_FROM_COMPILER_TO_DEPENDENCIES, arguments.addCompilerBuiltIns)
configuration.put(JVMConfigurationKeys.CREATE_BUILT_INS_FROM_MODULE_DEPENDENCIES, arguments.loadBuiltInsFromDependencies)
@@ -29,16 +29,13 @@ import org.jetbrains.kotlin.asJava.FilteredJvmDiagnostics
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection
import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage
import org.jetbrains.kotlin.cli.common.*
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.OUTPUT
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.WARNING
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAll
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.cli.jvm.config.*
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.state.GenerationState
@@ -356,7 +353,10 @@ object KotlinToJVMBytecodeCompiler {
val sourceFiles = environment.getSourceFiles()
val collector = environment.messageCollector
val analysisStart = PerformanceCounter.currentTime()
// Can be null for Scripts/REPL
val performanceManager = environment.configuration.get(CLIConfigurationKeys.PERF_MANAGER)
performanceManager?.notifyAnalysisStarted()
val analyzerWithCompilerReport = AnalyzerWithCompilerReport(collector, environment.configuration.languageVersionSettings)
analyzerWithCompilerReport.analyzeAndReport(sourceFiles) {
val project = environment.project
@@ -377,16 +377,7 @@ object KotlinToJVMBytecodeCompiler {
)
}
val analysisNanos = PerformanceCounter.currentTime() - analysisStart
val sourceLinesOfCode = environment.countLinesOfCode(sourceFiles)
val time = TimeUnit.NANOSECONDS.toMillis(analysisNanos)
val speed = sourceLinesOfCode.toFloat() * 1000 / time
val message = "ANALYZE: ${sourceFiles.size} files ($sourceLinesOfCode lines) ${targetDescription ?: ""}" +
"in $time ms - ${"%.3f".format(speed)} loc/s"
K2JVMCompiler.reportPerf(environment.configuration, message)
performanceManager?.notifyAnalysisFinished(sourceFiles.size, environment.countLinesOfCode(sourceFiles), targetDescription)
val analysisResult = analyzerWithCompilerReport.analysisResult
@@ -445,19 +436,17 @@ object KotlinToJVMBytecodeCompiler {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
val generationStart = PerformanceCounter.currentTime()
val performanceManager = environment.configuration.get(CLIConfigurationKeys.PERF_MANAGER)
performanceManager?.notifyGenerationStarted()
KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION)
val generationNanos = PerformanceCounter.currentTime() - generationStart
val desc = if (module != null) "target " + module.getModuleName() + "-" + module.getModuleType() + " " else ""
val numberOfSourceFiles = sourceFiles.size
val numberOfLines = environment.countLinesOfCode(sourceFiles)
val time = TimeUnit.NANOSECONDS.toMillis(generationNanos)
val speed = numberOfLines.toFloat() * 1000 / time
val message = "GENERATE: $numberOfSourceFiles files ($numberOfLines lines) ${desc}in $time ms - ${"%.3f".format(speed)} loc/s"
performanceManager?.notifyGenerationFinished(
sourceFiles.size,
environment.countLinesOfCode(sourceFiles),
additionalDescription = if (module != null) "target " + module.getModuleName() + "-" + module.getModuleType() + " " else ""
)
K2JVMCompiler.reportPerf(environment.configuration, message)
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
AnalyzerWithCompilerReport.reportDiagnostics(
@@ -355,7 +355,10 @@ object KotlinToJVMBytecodeCompiler {
val sourceFiles = environment.getSourceFiles()
val collector = environment.messageCollector
val analysisStart = PerformanceCounter.currentTime()
// Can be null for Scripts/REPL
val performanceManager = environment.configuration.get(CLIConfigurationKeys.PERF_MANAGER)
performanceManager?.notifyAnalysisStarted()
val analyzerWithCompilerReport = AnalyzerWithCompilerReport(collector, environment.configuration.languageVersionSettings)
analyzerWithCompilerReport.analyzeAndReport(sourceFiles) {
val project = environment.project
@@ -376,16 +379,7 @@ object KotlinToJVMBytecodeCompiler {
)
}
val analysisNanos = PerformanceCounter.currentTime() - analysisStart
val sourceLinesOfCode = environment.countLinesOfCode(sourceFiles)
val time = TimeUnit.NANOSECONDS.toMillis(analysisNanos)
val speed = sourceLinesOfCode.toFloat() * 1000 / time
val message = "ANALYZE: ${sourceFiles.size} files ($sourceLinesOfCode lines) ${targetDescription ?: ""}" +
"in $time ms - ${"%.3f".format(speed)} loc/s"
K2JVMCompiler.reportPerf(environment.configuration, message)
performanceManager?.notifyAnalysisFinished(sourceFiles.size, environment.countLinesOfCode(sourceFiles), targetDescription)
val analysisResult = analyzerWithCompilerReport.analysisResult
@@ -444,19 +438,17 @@ object KotlinToJVMBytecodeCompiler {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
val generationStart = PerformanceCounter.currentTime()
val performanceManager = environment.configuration.get(CLIConfigurationKeys.PERF_MANAGER)
performanceManager?.notifyGenerationStarted()
KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION)
val generationNanos = PerformanceCounter.currentTime() - generationStart
val desc = if (module != null) "target " + module.getModuleName() + "-" + module.getModuleType() + " " else ""
val numberOfSourceFiles = sourceFiles.size
val numberOfLines = environment.countLinesOfCode(sourceFiles)
val time = TimeUnit.NANOSECONDS.toMillis(generationNanos)
val speed = numberOfLines.toFloat() * 1000 / time
val message = "GENERATE: $numberOfSourceFiles files ($numberOfLines lines) ${desc}in $time ms - ${"%.3f".format(speed)} loc/s"
performanceManager?.notifyGenerationFinished(
sourceFiles.size,
environment.countLinesOfCode(sourceFiles),
additionalDescription = if (module != null) "target " + module.getModuleName() + "-" + module.getModuleType() + " " else ""
)
K2JVMCompiler.reportPerf(environment.configuration, message)
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
AnalyzerWithCompilerReport.reportDiagnostics(
@@ -355,7 +355,10 @@ object KotlinToJVMBytecodeCompiler {
val sourceFiles = environment.getSourceFiles()
val collector = environment.messageCollector
val analysisStart = PerformanceCounter.currentTime()
// Can be null for Scripts/REPL
val performanceManager = environment.configuration.get(CLIConfigurationKeys.PERF_MANAGER)
performanceManager?.notifyAnalysisStarted()
val analyzerWithCompilerReport = AnalyzerWithCompilerReport(collector, environment.configuration.languageVersionSettings)
analyzerWithCompilerReport.analyzeAndReport(sourceFiles) {
val project = environment.project
@@ -376,16 +379,7 @@ object KotlinToJVMBytecodeCompiler {
)
}
val analysisNanos = PerformanceCounter.currentTime() - analysisStart
val sourceLinesOfCode = environment.countLinesOfCode(sourceFiles)
val time = TimeUnit.NANOSECONDS.toMillis(analysisNanos)
val speed = sourceLinesOfCode.toFloat() * 1000 / time
val message = "ANALYZE: ${sourceFiles.size} files ($sourceLinesOfCode lines) ${targetDescription ?: ""}" +
"in $time ms - ${"%.3f".format(speed)} loc/s"
K2JVMCompiler.reportPerf(environment.configuration, message)
performanceManager?.notifyAnalysisFinished(sourceFiles.size, environment.countLinesOfCode(sourceFiles), targetDescription)
val analysisResult = analyzerWithCompilerReport.analysisResult
@@ -444,19 +438,17 @@ object KotlinToJVMBytecodeCompiler {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
val generationStart = PerformanceCounter.currentTime()
val performanceManager = environment.configuration.get(CLIConfigurationKeys.PERF_MANAGER)
performanceManager?.notifyGenerationStarted()
KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION)
val generationNanos = PerformanceCounter.currentTime() - generationStart
val desc = if (module != null) "target " + module.getModuleName() + "-" + module.getModuleType() + " " else ""
val numberOfSourceFiles = sourceFiles.size
val numberOfLines = environment.countLinesOfCode(sourceFiles)
val time = TimeUnit.NANOSECONDS.toMillis(generationNanos)
val speed = numberOfLines.toFloat() * 1000 / time
val message = "GENERATE: $numberOfSourceFiles files ($numberOfLines lines) ${desc}in $time ms - ${"%.3f".format(speed)} loc/s"
performanceManager?.notifyGenerationFinished(
sourceFiles.size,
environment.countLinesOfCode(sourceFiles),
additionalDescription = if (module != null) "target " + module.getModuleName() + "-" + module.getModuleType() + " " else ""
)
K2JVMCompiler.reportPerf(environment.configuration, message)
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
AnalyzerWithCompilerReport.reportDiagnostics(
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.cli.metadata
import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.cli.common.CLICompiler
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.CommonCompilerPerformanceManager
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
@@ -38,6 +39,8 @@ import org.jetbrains.kotlin.utils.KotlinPaths
import java.io.File
class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
private val performanceManager: K2MetadataCompilerPerformanceManager = K2MetadataCompilerPerformanceManager()
override fun createArguments() = K2MetadataCompilerArguments()
override fun setupPlatformSpecificArgumentsAndServices(
@@ -99,10 +102,14 @@ class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
// TODO: update this once a launcher script for K2MetadataCompiler is available
override fun executableScriptFileName(): String = "kotlinc"
override fun getPerformanceManager(): CommonCompilerPerformanceManager = performanceManager
companion object {
@JvmStatic
fun main(args: Array<String>) {
doMain(K2MetadataCompiler(), args)
}
}
}
private class K2MetadataCompilerPerformanceManager : CommonCompilerPerformanceManager("Kotlin to Metadata compiler")
}