Add compiler metrics to JPS build report
#KT-63549: Fixed
This commit is contained in:
committed by
Space Team
parent
6cff71e7d1
commit
6bbf5b83c8
+1
@@ -26,6 +26,7 @@ enum class JpsBuildPerformanceMetric(
|
|||||||
DAEMON_GC_COUNT(readableString = "Count of GC", type = ValueType.NUMBER),
|
DAEMON_GC_COUNT(readableString = "Count of GC", type = ValueType.NUMBER),
|
||||||
|
|
||||||
COMPILE_ITERATION(parent = null, "Total compiler iteration", type = ValueType.NUMBER),
|
COMPILE_ITERATION(parent = null, "Total compiler iteration", type = ValueType.NUMBER),
|
||||||
|
IC_COMPILE_ITERATION(parent = COMPILE_ITERATION, "Total kotlin compiler iteration", type = ValueType.NUMBER),
|
||||||
ANALYZED_LINES_NUMBER(parent = COMPILE_ITERATION, "Number of lines analyzed", type = ValueType.NUMBER),
|
ANALYZED_LINES_NUMBER(parent = COMPILE_ITERATION, "Number of lines analyzed", type = ValueType.NUMBER),
|
||||||
CODE_GENERATED_LINES_NUMBER(parent = COMPILE_ITERATION, "Number of lines for code generation", type = ValueType.NUMBER),
|
CODE_GENERATED_LINES_NUMBER(parent = COMPILE_ITERATION, "Number of lines for code generation", type = ValueType.NUMBER),
|
||||||
ANALYSIS_LPS(parent = COMPILE_ITERATION, "Analysis lines per second", type = ValueType.NUMBER),
|
ANALYSIS_LPS(parent = COMPILE_ITERATION, "Analysis lines per second", type = ValueType.NUMBER),
|
||||||
|
|||||||
+7
-1
@@ -20,9 +20,15 @@ interface BuildTime : Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Suppress("Reformat")
|
||||||
enum class JpsBuildTime(private val parent: JpsBuildTime? = null, private val readableString: String) : BuildTime {
|
enum class JpsBuildTime(private val parent: JpsBuildTime? = null, private val readableString: String) : BuildTime {
|
||||||
|
|
||||||
JPS_ITERATION(readableString = "Jps iteration")
|
JPS_ITERATION(readableString = "Jps iteration"),
|
||||||
|
COMPILATION_ROUND(JPS_ITERATION, "Sources compilation round"),
|
||||||
|
COMPILER_PERFORMANCE(COMPILATION_ROUND, readableString = "Compiler time"),
|
||||||
|
COMPILER_INITIALIZATION(COMPILER_PERFORMANCE, "Compiler initialization time"),
|
||||||
|
CODE_ANALYSIS(COMPILER_PERFORMANCE, "Compiler code analysis"),
|
||||||
|
CODE_GENERATION(COMPILER_PERFORMANCE, "Compiler code generation"),
|
||||||
;
|
;
|
||||||
|
|
||||||
override fun getReadableString(): String = readableString
|
override fun getReadableString(): String = readableString
|
||||||
|
|||||||
+15
-23
@@ -15,34 +15,21 @@ import java.io.Serializable
|
|||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class FileReportService<B : BuildTime, P : BuildPerformanceMetric>(
|
open class FileReportService<B : BuildTime, P : BuildPerformanceMetric>(
|
||||||
private val outputFile: File,
|
buildReportDir: File,
|
||||||
|
projectName: String,
|
||||||
private val printMetrics: Boolean,
|
private val printMetrics: Boolean,
|
||||||
private val logger: KotlinLogger,
|
private val logger: KotlinLogger,
|
||||||
) : Serializable {
|
) : Serializable {
|
||||||
companion object {
|
companion object {
|
||||||
private val formatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").also { it.timeZone = TimeZone.getTimeZone("UTC") }
|
private val formatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").also { it.timeZone = TimeZone.getTimeZone("UTC") }
|
||||||
fun <B : BuildTime, P : BuildPerformanceMetric> reportBuildStatInFile(
|
|
||||||
buildReportDir: File,
|
|
||||||
projectName: String,
|
|
||||||
includeMetricsInReport: Boolean,
|
|
||||||
buildData: List<CompileStatisticsData<B, P>>,
|
|
||||||
startParameters: BuildStartParameters,
|
|
||||||
failureMessages: List<String>,
|
|
||||||
logger: KotlinLogger,
|
|
||||||
) {
|
|
||||||
val ts = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(Calendar.getInstance().time)
|
|
||||||
val reportFile = buildReportDir.resolve("$projectName-build-$ts.txt")
|
|
||||||
|
|
||||||
FileReportService<B, P>(
|
|
||||||
outputFile = reportFile,
|
|
||||||
printMetrics = includeMetricsInReport,
|
|
||||||
logger = logger
|
|
||||||
).process(buildData, startParameters, failureMessages)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
private val ts = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(Calendar.getInstance().time)
|
||||||
|
private val outputFile = buildReportDir.resolve("$projectName-build-$ts.txt")
|
||||||
|
|
||||||
private lateinit var p: Printer
|
protected lateinit var p: Printer
|
||||||
|
|
||||||
|
open fun printCustomTaskMetrics(statisticsData: CompileStatisticsData<B, P>) {}
|
||||||
|
|
||||||
fun process(
|
fun process(
|
||||||
statisticsData: List<CompileStatisticsData<B, P>>,
|
statisticsData: List<CompileStatisticsData<B, P>>,
|
||||||
@@ -263,14 +250,18 @@ class FileReportService<B : BuildTime, P : BuildPerformanceMetric>(
|
|||||||
p.println()
|
p.println()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun printTasksLog(statisticsData: List<CompileStatisticsData<B, P>>) {
|
private fun printTasksLog(
|
||||||
|
statisticsData: List<CompileStatisticsData<B, P>>,
|
||||||
|
) {
|
||||||
for (task in statisticsData.sortedWith(compareBy({ -it.getDurationMs() }, { it.getStartTimeMs() }))) {
|
for (task in statisticsData.sortedWith(compareBy({ -it.getDurationMs() }, { it.getStartTimeMs() }))) {
|
||||||
printTaskLog(task)
|
printTaskLog(task)
|
||||||
p.println()
|
p.println()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <B : BuildTime, P : BuildPerformanceMetric> printTaskLog(statisticsData: CompileStatisticsData<B, P>) {
|
private fun printTaskLog(
|
||||||
|
statisticsData: CompileStatisticsData<B, P>,
|
||||||
|
) {
|
||||||
val skipMessage = statisticsData.getSkipMessage()
|
val skipMessage = statisticsData.getSkipMessage()
|
||||||
if (skipMessage != null) {
|
if (skipMessage != null) {
|
||||||
p.println("Task '${statisticsData.getTaskName()}' was skipped: $skipMessage")
|
p.println("Task '${statisticsData.getTaskName()}' was skipped: $skipMessage")
|
||||||
@@ -295,6 +286,7 @@ class FileReportService<B : BuildTime, P : BuildPerformanceMetric>(
|
|||||||
statisticsData.getBuildTimesMetrics(), statisticsData.getPerformanceMetrics(), statisticsData.getNonIncrementalAttributes(),
|
statisticsData.getBuildTimesMetrics(), statisticsData.getPerformanceMetrics(), statisticsData.getNonIncrementalAttributes(),
|
||||||
statisticsData.getGcTimeMetrics(), statisticsData.getGcCountMetrics()
|
statisticsData.getGcTimeMetrics(), statisticsData.getGcCountMetrics()
|
||||||
)
|
)
|
||||||
|
printCustomTaskMetrics(statisticsData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -9,7 +9,7 @@ import java.io.IOException
|
|||||||
|
|
||||||
private val LINE_SEPARATOR = System.getProperty("line.separator")
|
private val LINE_SEPARATOR = System.getProperty("line.separator")
|
||||||
|
|
||||||
internal class Printer(
|
class Printer(
|
||||||
private val out: Appendable,
|
private val out: Appendable,
|
||||||
private val indentUnit: String = " ",
|
private val indentUnit: String = " ",
|
||||||
private var indent: String = ""
|
private var indent: String = ""
|
||||||
|
|||||||
+17
@@ -31,3 +31,20 @@ enum class CompilationResultCategory(val code: Int) {
|
|||||||
VERBOSE_BUILD_REPORT_LINES(2),
|
VERBOSE_BUILD_REPORT_LINES(2),
|
||||||
BUILD_METRICS(3)
|
BUILD_METRICS(3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class BuildMetricsValue(
|
||||||
|
val key: CompilationPerformanceMetrics,
|
||||||
|
val value: Long
|
||||||
|
): Serializable
|
||||||
|
|
||||||
|
enum class CompilationPerformanceMetrics {
|
||||||
|
COMPILER_INITIALIZATION,
|
||||||
|
CODE_ANALYSIS,
|
||||||
|
ANALYZED_LINES_NUMBER,
|
||||||
|
ANALYSIS_LPS,
|
||||||
|
CODE_GENERATION,
|
||||||
|
CODE_GENERATED_LINES_NUMBER,
|
||||||
|
CODE_GENERATION_LPS,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,9 +27,7 @@ import org.jetbrains.kotlin.build.report.metrics.GradleBuildPerformanceMetric
|
|||||||
import org.jetbrains.kotlin.build.report.metrics.GradleBuildTime
|
import org.jetbrains.kotlin.build.report.metrics.GradleBuildTime
|
||||||
import org.jetbrains.kotlin.build.report.metrics.endMeasureGc
|
import org.jetbrains.kotlin.build.report.metrics.endMeasureGc
|
||||||
import org.jetbrains.kotlin.build.report.metrics.startMeasureGc
|
import org.jetbrains.kotlin.build.report.metrics.startMeasureGc
|
||||||
import org.jetbrains.kotlin.cli.common.CLICompiler
|
import org.jetbrains.kotlin.cli.common.*
|
||||||
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties
|
|
||||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.*
|
import org.jetbrains.kotlin.cli.common.arguments.*
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||||
@@ -106,7 +104,7 @@ abstract class CompileServiceImplBase(
|
|||||||
val daemonOptions: DaemonOptions,
|
val daemonOptions: DaemonOptions,
|
||||||
val compilerId: CompilerId,
|
val compilerId: CompilerId,
|
||||||
val port: Int,
|
val port: Int,
|
||||||
val timer: Timer
|
val timer: Timer,
|
||||||
) {
|
) {
|
||||||
protected val log by lazy { Logger.getLogger("compiler") }
|
protected val log by lazy { Logger.getLogger("compiler") }
|
||||||
|
|
||||||
@@ -118,7 +116,7 @@ abstract class CompileServiceImplBase(
|
|||||||
protected class ClientOrSessionProxy<out T : Any>(
|
protected class ClientOrSessionProxy<out T : Any>(
|
||||||
val aliveFlagPath: String?,
|
val aliveFlagPath: String?,
|
||||||
val data: T? = null,
|
val data: T? = null,
|
||||||
private var disposable: Disposable? = null
|
private var disposable: Disposable? = null,
|
||||||
) {
|
) {
|
||||||
val isAlive: Boolean
|
val isAlive: Boolean
|
||||||
get() = aliveFlagPath?.let { File(it).exists() } ?: true // assuming that if no file was given, the client is alive
|
get() = aliveFlagPath?.let { File(it).exists() } ?: true // assuming that if no file was given, the client is alive
|
||||||
@@ -211,7 +209,7 @@ abstract class CompileServiceImplBase(
|
|||||||
private inline fun <T> Iterable<T>.cleanMatching(
|
private inline fun <T> Iterable<T>.cleanMatching(
|
||||||
lock: ReentrantReadWriteLock,
|
lock: ReentrantReadWriteLock,
|
||||||
crossinline pred: (T) -> Boolean,
|
crossinline pred: (T) -> Boolean,
|
||||||
crossinline clean: (T) -> Unit
|
crossinline clean: (T) -> Unit,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
var anyDead = false
|
var anyDead = false
|
||||||
lock.read {
|
lock.read {
|
||||||
@@ -288,6 +286,48 @@ abstract class CompileServiceImplBase(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected fun getPerformanceMetrics(compiler: CLICompiler<CommonCompilerArguments>): List<BuildMetricsValue> {
|
||||||
|
val performanceMetrics = ArrayList<BuildMetricsValue>()
|
||||||
|
compiler.defaultPerformanceManager.getMeasurementResults().forEach {
|
||||||
|
when (it) {
|
||||||
|
is CompilerInitializationMeasurement -> {
|
||||||
|
performanceMetrics.add(BuildMetricsValue(CompilationPerformanceMetrics.COMPILER_INITIALIZATION, it.milliseconds))
|
||||||
|
}
|
||||||
|
is CodeAnalysisMeasurement -> {
|
||||||
|
performanceMetrics.add(BuildMetricsValue(CompilationPerformanceMetrics.CODE_ANALYSIS, it.milliseconds))
|
||||||
|
it.lines?.apply {
|
||||||
|
performanceMetrics.add(BuildMetricsValue(CompilationPerformanceMetrics.ANALYZED_LINES_NUMBER, this.toLong()))
|
||||||
|
if (it.milliseconds > 0) {
|
||||||
|
performanceMetrics.add(
|
||||||
|
BuildMetricsValue(
|
||||||
|
CompilationPerformanceMetrics.ANALYSIS_LPS,
|
||||||
|
this * 1000 / it.milliseconds
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is CodeGenerationMeasurement -> {
|
||||||
|
performanceMetrics.add(
|
||||||
|
BuildMetricsValue(CompilationPerformanceMetrics.CODE_GENERATION, it.milliseconds)
|
||||||
|
)
|
||||||
|
it.lines?.apply {
|
||||||
|
performanceMetrics.add(BuildMetricsValue(CompilationPerformanceMetrics.CODE_GENERATED_LINES_NUMBER, this.toLong()))
|
||||||
|
if (it.milliseconds > 0) {
|
||||||
|
performanceMetrics.add(
|
||||||
|
BuildMetricsValue(
|
||||||
|
CompilationPerformanceMetrics.CODE_GENERATION_LPS,
|
||||||
|
this * 1000 / it.milliseconds
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return performanceMetrics
|
||||||
|
}
|
||||||
|
|
||||||
protected inline fun <ServicesFacadeT, JpsServicesFacadeT, CompilationResultsT> compileImpl(
|
protected inline fun <ServicesFacadeT, JpsServicesFacadeT, CompilationResultsT> compileImpl(
|
||||||
sessionId: Int,
|
sessionId: Int,
|
||||||
compilerArguments: Array<out String>,
|
compilerArguments: Array<out String>,
|
||||||
@@ -298,7 +338,7 @@ abstract class CompileServiceImplBase(
|
|||||||
createMessageCollector: (ServicesFacadeT, CompilationOptions) -> MessageCollector,
|
createMessageCollector: (ServicesFacadeT, CompilationOptions) -> MessageCollector,
|
||||||
createReporter: (ServicesFacadeT, CompilationOptions) -> DaemonMessageReporter,
|
createReporter: (ServicesFacadeT, CompilationOptions) -> DaemonMessageReporter,
|
||||||
createServices: (JpsServicesFacadeT, EventManager, Profiler) -> Services,
|
createServices: (JpsServicesFacadeT, EventManager, Profiler) -> Services,
|
||||||
getICReporter: (ServicesFacadeT, CompilationResultsT?, IncrementalCompilationOptions) -> RemoteBuildReporter<GradleBuildTime, GradleBuildPerformanceMetric>
|
getICReporter: (ServicesFacadeT, CompilationResultsT?, IncrementalCompilationOptions) -> RemoteBuildReporter<GradleBuildTime, GradleBuildPerformanceMetric>,
|
||||||
) = kotlin.run {
|
) = kotlin.run {
|
||||||
val messageCollector = createMessageCollector(servicesFacade, compilationOptions)
|
val messageCollector = createMessageCollector(servicesFacade, compilationOptions)
|
||||||
val daemonReporter = createReporter(servicesFacade, compilationOptions)
|
val daemonReporter = createReporter(servicesFacade, compilationOptions)
|
||||||
@@ -326,7 +366,16 @@ abstract class CompileServiceImplBase(
|
|||||||
withIncrementalCompilation(k2PlatformArgs, enabled = servicesFacade.hasIncrementalCaches()) {
|
withIncrementalCompilation(k2PlatformArgs, enabled = servicesFacade.hasIncrementalCaches()) {
|
||||||
doCompile(sessionId, daemonReporter, tracer = null) { eventManger, profiler ->
|
doCompile(sessionId, daemonReporter, tracer = null) { eventManger, profiler ->
|
||||||
val services = createServices(servicesFacade, eventManger, profiler)
|
val services = createServices(servicesFacade, eventManger, profiler)
|
||||||
compiler.exec(messageCollector, services, k2PlatformArgs)
|
val exitCode = compiler.exec(messageCollector, services, k2PlatformArgs)
|
||||||
|
|
||||||
|
compilationResults.also {
|
||||||
|
val compilationResult = it as CompilationResults
|
||||||
|
getPerformanceMetrics(compiler).forEach {
|
||||||
|
compilationResult.add(CompilationResultCategory.BUILD_METRICS.code, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exitCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -391,7 +440,7 @@ abstract class CompileServiceImplBase(
|
|||||||
sessionId: Int,
|
sessionId: Int,
|
||||||
daemonMessageReporter: DaemonMessageReporter,
|
daemonMessageReporter: DaemonMessageReporter,
|
||||||
tracer: RemoteOperationsTracer?,
|
tracer: RemoteOperationsTracer?,
|
||||||
body: (EventManager, Profiler) -> ExitCode
|
body: (EventManager, Profiler) -> ExitCode,
|
||||||
): CompileService.CallResult<Int> = run {
|
): CompileService.CallResult<Int> = run {
|
||||||
log.fine("alive!")
|
log.fine("alive!")
|
||||||
withValidClientOrSessionProxy(sessionId) {
|
withValidClientOrSessionProxy(sessionId) {
|
||||||
@@ -417,7 +466,7 @@ abstract class CompileServiceImplBase(
|
|||||||
protected inline fun <R> checkedCompile(
|
protected inline fun <R> checkedCompile(
|
||||||
daemonMessageReporter: DaemonMessageReporter,
|
daemonMessageReporter: DaemonMessageReporter,
|
||||||
rpcProfiler: Profiler,
|
rpcProfiler: Profiler,
|
||||||
body: () -> R
|
body: () -> R,
|
||||||
): R {
|
): R {
|
||||||
try {
|
try {
|
||||||
val profiler = if (daemonOptions.reportPerf) WallAndThreadAndMemoryTotalProfiler(withGC = false) else DummyProfiler()
|
val profiler = if (daemonOptions.reportPerf) WallAndThreadAndMemoryTotalProfiler(withGC = false) else DummyProfiler()
|
||||||
@@ -432,9 +481,11 @@ abstract class CompileServiceImplBase(
|
|||||||
val pc = profiler.getTotalCounters()
|
val pc = profiler.getTotalCounters()
|
||||||
val rpc = rpcProfiler.getTotalCounters()
|
val rpc = rpcProfiler.getTotalCounters()
|
||||||
|
|
||||||
"PERF: Compile on daemon: ${pc.time.ms()} ms; thread: user ${pc.threadUserTime.ms()} ms, sys ${(pc.threadTime - pc.threadUserTime).ms()} ms; rpc: ${rpc.count} calls, ${rpc.time.ms()} ms, thread ${rpc.threadTime.ms()} ms; memory: ${endMem.kb()} kb (${"%+d".format(
|
"PERF: Compile on daemon: ${pc.time.ms()} ms; thread: user ${pc.threadUserTime.ms()} ms, sys ${(pc.threadTime - pc.threadUserTime).ms()} ms; rpc: ${rpc.count} calls, ${rpc.time.ms()} ms, thread ${rpc.threadTime.ms()} ms; memory: ${endMem.kb()} kb (${
|
||||||
pc.memory.kb()
|
"%+d".format(
|
||||||
)} kb)".let {
|
pc.memory.kb()
|
||||||
|
)
|
||||||
|
} kb)".let {
|
||||||
daemonMessageReporter.report(ReportSeverity.INFO, it)
|
daemonMessageReporter.report(ReportSeverity.INFO, it)
|
||||||
log.info(it)
|
log.info(it)
|
||||||
}
|
}
|
||||||
@@ -454,9 +505,9 @@ abstract class CompileServiceImplBase(
|
|||||||
log.log(
|
log.log(
|
||||||
Level.SEVERE,
|
Level.SEVERE,
|
||||||
"Exception: $e\n ${e.stackTrace.joinToString("\n ")}${
|
"Exception: $e\n ${e.stackTrace.joinToString("\n ")}${
|
||||||
if (e.cause != null && e.cause != e) {
|
if (e.cause != null && e.cause != e) {
|
||||||
"\nCaused by: ${e.cause}\n ${e.cause!!.stackTrace.joinToString("\n ")}"
|
"\nCaused by: ${e.cause}\n ${e.cause!!.stackTrace.joinToString("\n ")}"
|
||||||
} else ""
|
} else ""
|
||||||
}"
|
}"
|
||||||
)
|
)
|
||||||
throw e
|
throw e
|
||||||
@@ -498,7 +549,7 @@ abstract class CompileServiceImplBase(
|
|||||||
|
|
||||||
protected inline fun <R> ifAliveChecksImpl(
|
protected inline fun <R> ifAliveChecksImpl(
|
||||||
minAliveness: Aliveness = Aliveness.LastSession,
|
minAliveness: Aliveness = Aliveness.LastSession,
|
||||||
body: () -> CompileService.CallResult<R>
|
body: () -> CompileService.CallResult<R>,
|
||||||
): CompileService.CallResult<R> {
|
): CompileService.CallResult<R> {
|
||||||
val curState = state.alive.get()
|
val curState = state.alive.get()
|
||||||
return when {
|
return when {
|
||||||
@@ -519,7 +570,7 @@ abstract class CompileServiceImplBase(
|
|||||||
|
|
||||||
protected inline fun <R> withValidClientOrSessionProxy(
|
protected inline fun <R> withValidClientOrSessionProxy(
|
||||||
sessionId: Int,
|
sessionId: Int,
|
||||||
body: (ClientOrSessionProxy<Any>?) -> CompileService.CallResult<R>
|
body: (ClientOrSessionProxy<Any>?) -> CompileService.CallResult<R>,
|
||||||
): CompileService.CallResult<R> {
|
): CompileService.CallResult<R> {
|
||||||
val session: ClientOrSessionProxy<Any>? =
|
val session: ClientOrSessionProxy<Any>? =
|
||||||
if (sessionId == CompileService.NO_SESSION) null
|
if (sessionId == CompileService.NO_SESSION) null
|
||||||
@@ -536,7 +587,7 @@ abstract class CompileServiceImplBase(
|
|||||||
args: K2JSCompilerArguments,
|
args: K2JSCompilerArguments,
|
||||||
incrementalCompilationOptions: IncrementalCompilationOptions,
|
incrementalCompilationOptions: IncrementalCompilationOptions,
|
||||||
compilerMessageCollector: MessageCollector,
|
compilerMessageCollector: MessageCollector,
|
||||||
reporter: RemoteBuildReporter<GradleBuildTime, GradleBuildPerformanceMetric>
|
reporter: RemoteBuildReporter<GradleBuildTime, GradleBuildPerformanceMetric>,
|
||||||
): ExitCode {
|
): ExitCode {
|
||||||
reporter.startMeasureGc()
|
reporter.startMeasureGc()
|
||||||
@Suppress("DEPRECATION") // TODO: get rid of that parsing KT-62759
|
@Suppress("DEPRECATION") // TODO: get rid of that parsing KT-62759
|
||||||
@@ -579,7 +630,7 @@ abstract class CompileServiceImplBase(
|
|||||||
k2jvmArgs: K2JVMCompilerArguments,
|
k2jvmArgs: K2JVMCompilerArguments,
|
||||||
incrementalCompilationOptions: IncrementalCompilationOptions,
|
incrementalCompilationOptions: IncrementalCompilationOptions,
|
||||||
compilerMessageCollector: MessageCollector,
|
compilerMessageCollector: MessageCollector,
|
||||||
reporter: RemoteBuildReporter<GradleBuildTime, GradleBuildPerformanceMetric>
|
reporter: RemoteBuildReporter<GradleBuildTime, GradleBuildPerformanceMetric>,
|
||||||
): ExitCode {
|
): ExitCode {
|
||||||
reporter.startMeasureGc()
|
reporter.startMeasureGc()
|
||||||
val allKotlinExtensions = (DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS +
|
val allKotlinExtensions = (DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS +
|
||||||
@@ -651,7 +702,7 @@ abstract class CompileServiceImplBase(
|
|||||||
|
|
||||||
protected inline fun <R, KotlinJvmReplServiceT> withValidReplImpl(
|
protected inline fun <R, KotlinJvmReplServiceT> withValidReplImpl(
|
||||||
sessionId: Int,
|
sessionId: Int,
|
||||||
body: KotlinJvmReplServiceT.() -> CompileService.CallResult<R>
|
body: KotlinJvmReplServiceT.() -> CompileService.CallResult<R>,
|
||||||
): CompileService.CallResult<R> =
|
): CompileService.CallResult<R> =
|
||||||
withValidClientOrSessionProxy(sessionId) { session ->
|
withValidClientOrSessionProxy(sessionId) { session ->
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
@@ -668,16 +719,17 @@ class CompileServiceImpl(
|
|||||||
val daemonJVMOptions: DaemonJVMOptions,
|
val daemonJVMOptions: DaemonJVMOptions,
|
||||||
port: Int,
|
port: Int,
|
||||||
timer: Timer,
|
timer: Timer,
|
||||||
val onShutdown: () -> Unit
|
val onShutdown: () -> Unit,
|
||||||
) : CompileService, CompileServiceImplBase(daemonOptions, compilerId, port, timer) {
|
) : CompileService, CompileServiceImplBase(daemonOptions, compilerId, port, timer) {
|
||||||
|
|
||||||
private inline fun <R> withValidRepl(
|
private inline fun <R> withValidRepl(
|
||||||
sessionId: Int,
|
sessionId: Int,
|
||||||
body: KotlinJvmReplService.() -> CompileService.CallResult<R>
|
body: KotlinJvmReplService.() -> CompileService.CallResult<R>,
|
||||||
) = withValidReplImpl(sessionId, body)
|
) = withValidReplImpl(sessionId, body)
|
||||||
|
|
||||||
override val lastUsedSeconds: Long get() =
|
override val lastUsedSeconds: Long
|
||||||
if (rwlock.isWriteLocked || rwlock.readLockCount - rwlock.readHoldCount > 0) nowSeconds() else _lastUsedSeconds
|
get() =
|
||||||
|
if (rwlock.isWriteLocked || rwlock.readLockCount - rwlock.readHoldCount > 0) nowSeconds() else _lastUsedSeconds
|
||||||
|
|
||||||
private val rwlock = ReentrantReadWriteLock()
|
private val rwlock = ReentrantReadWriteLock()
|
||||||
|
|
||||||
@@ -758,7 +810,7 @@ class CompileServiceImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun classesFqNamesByFiles(
|
override fun classesFqNamesByFiles(
|
||||||
sessionId: Int, sourceFiles: Set<File>
|
sessionId: Int, sourceFiles: Set<File>,
|
||||||
): CompileService.CallResult<Set<String>> =
|
): CompileService.CallResult<Set<String>> =
|
||||||
ifAlive {
|
ifAlive {
|
||||||
withValidClientOrSessionProxy(sessionId) {
|
withValidClientOrSessionProxy(sessionId) {
|
||||||
@@ -771,7 +823,7 @@ class CompileServiceImpl(
|
|||||||
compilerArguments: Array<out String>,
|
compilerArguments: Array<out String>,
|
||||||
compilationOptions: CompilationOptions,
|
compilationOptions: CompilationOptions,
|
||||||
servicesFacade: CompilerServicesFacadeBase,
|
servicesFacade: CompilerServicesFacadeBase,
|
||||||
compilationResults: CompilationResults?
|
compilationResults: CompilationResults?,
|
||||||
) = ifAlive {
|
) = ifAlive {
|
||||||
compileImpl(
|
compileImpl(
|
||||||
sessionId,
|
sessionId,
|
||||||
@@ -783,7 +835,7 @@ class CompileServiceImpl(
|
|||||||
createMessageCollector = ::CompileServicesFacadeMessageCollector,
|
createMessageCollector = ::CompileServicesFacadeMessageCollector,
|
||||||
createReporter = ::DaemonMessageReporter,
|
createReporter = ::DaemonMessageReporter,
|
||||||
createServices = this::createCompileServices,
|
createServices = this::createCompileServices,
|
||||||
getICReporter = { a, b, c -> getBuildReporter(a, b!!, c)}
|
getICReporter = { a, b, c -> getBuildReporter(a, b!!, c) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -794,7 +846,7 @@ class CompileServiceImpl(
|
|||||||
private fun createCompileServices(
|
private fun createCompileServices(
|
||||||
@Suppress("DEPRECATION") facade: CompilerCallbackServicesFacade,
|
@Suppress("DEPRECATION") facade: CompilerCallbackServicesFacade,
|
||||||
eventManager: EventManager,
|
eventManager: EventManager,
|
||||||
rpcProfiler: Profiler
|
rpcProfiler: Profiler,
|
||||||
): Services {
|
): Services {
|
||||||
val builder = Services.Builder()
|
val builder = Services.Builder()
|
||||||
if (facade.hasIncrementalCaches()) {
|
if (facade.hasIncrementalCaches()) {
|
||||||
@@ -834,7 +886,7 @@ class CompileServiceImpl(
|
|||||||
compilationOptions: CompilationOptions,
|
compilationOptions: CompilationOptions,
|
||||||
servicesFacade: CompilerServicesFacadeBase,
|
servicesFacade: CompilerServicesFacadeBase,
|
||||||
templateClasspath: List<File>,
|
templateClasspath: List<File>,
|
||||||
templateClassName: String
|
templateClassName: String,
|
||||||
): CompileService.CallResult<Int> = ifAlive(minAliveness = Aliveness.Alive) {
|
): CompileService.CallResult<Int> = ifAlive(minAliveness = Aliveness.Alive) {
|
||||||
if (compilationOptions.targetPlatform != CompileService.TargetPlatform.JVM)
|
if (compilationOptions.targetPlatform != CompileService.TargetPlatform.JVM)
|
||||||
CompileService.CallResult.Error("Sorry, only JVM target platform is supported now")
|
CompileService.CallResult.Error("Sorry, only JVM target platform is supported now")
|
||||||
@@ -1047,7 +1099,7 @@ class CompileServiceImpl(
|
|||||||
state.sessions.isEmpty() -> shutdownWithDelay()
|
state.sessions.isEmpty() -> shutdownWithDelay()
|
||||||
else -> {
|
else -> {
|
||||||
daemonOptions.autoshutdownIdleSeconds =
|
daemonOptions.autoshutdownIdleSeconds =
|
||||||
TimeUnit.MILLISECONDS.toSeconds(daemonOptions.forceShutdownTimeoutMilliseconds).toInt()
|
TimeUnit.MILLISECONDS.toSeconds(daemonOptions.forceShutdownTimeoutMilliseconds).toInt()
|
||||||
daemonOptions.autoshutdownUnusedSeconds = daemonOptions.autoshutdownIdleSeconds
|
daemonOptions.autoshutdownUnusedSeconds = daemonOptions.autoshutdownIdleSeconds
|
||||||
log.info("Some sessions are active, waiting for them to finish")
|
log.info("Some sessions are active, waiting for them to finish")
|
||||||
log.info("Unused/idle timeouts are set to ${daemonOptions.autoshutdownUnusedSeconds}/${daemonOptions.autoshutdownIdleSeconds}s")
|
log.info("Unused/idle timeouts are set to ${daemonOptions.autoshutdownUnusedSeconds}/${daemonOptions.autoshutdownIdleSeconds}s")
|
||||||
@@ -1101,7 +1153,7 @@ class CompileServiceImpl(
|
|||||||
|
|
||||||
private inline fun <R> ifAlive(
|
private inline fun <R> ifAlive(
|
||||||
minAliveness: Aliveness = Aliveness.LastSession,
|
minAliveness: Aliveness = Aliveness.LastSession,
|
||||||
body: () -> CompileService.CallResult<R>
|
body: () -> CompileService.CallResult<R>,
|
||||||
): CompileService.CallResult<R> = rwlock.read {
|
): CompileService.CallResult<R> = rwlock.read {
|
||||||
ifAliveChecksImpl(minAliveness, body)
|
ifAliveChecksImpl(minAliveness, body)
|
||||||
}
|
}
|
||||||
@@ -1115,7 +1167,7 @@ class CompileServiceImpl(
|
|||||||
|
|
||||||
private inline fun <R> ifAliveExclusive(
|
private inline fun <R> ifAliveExclusive(
|
||||||
minAliveness: Aliveness = Aliveness.LastSession,
|
minAliveness: Aliveness = Aliveness.LastSession,
|
||||||
body: () -> CompileService.CallResult<R>
|
body: () -> CompileService.CallResult<R>,
|
||||||
): CompileService.CallResult<R> = rwlock.write {
|
): CompileService.CallResult<R> = rwlock.write {
|
||||||
ifAliveChecksImpl(minAliveness, body)
|
ifAliveChecksImpl(minAliveness, body)
|
||||||
}
|
}
|
||||||
|
|||||||
+80
@@ -26,6 +26,8 @@ import org.jetbrains.kotlin.jps.build.fixtures.EnableICFixture
|
|||||||
import org.jetbrains.kotlin.jps.model.kotlinCommonCompilerArguments
|
import org.jetbrains.kotlin.jps.model.kotlinCommonCompilerArguments
|
||||||
import org.jetbrains.kotlin.jps.model.kotlinCompilerArguments
|
import org.jetbrains.kotlin.jps.model.kotlinCompilerArguments
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.Path
|
||||||
import kotlin.reflect.KMutableProperty1
|
import kotlin.reflect.KMutableProperty1
|
||||||
|
|
||||||
class KotlinJpsBuildTestIncremental : KotlinJpsBuildTest() {
|
class KotlinJpsBuildTestIncremental : KotlinJpsBuildTest() {
|
||||||
@@ -43,6 +45,84 @@ class KotlinJpsBuildTestIncremental : KotlinJpsBuildTest() {
|
|||||||
).run()
|
).run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testJpsBuildReportIC() {
|
||||||
|
|
||||||
|
val reportDir = workDir.resolve("buildReport")
|
||||||
|
|
||||||
|
@Suppress("UNREACHABLE_CODE")
|
||||||
|
fun getReportFile(): File {
|
||||||
|
return Files.list(reportDir.toPath()).let {
|
||||||
|
val files = it.toArray()
|
||||||
|
val singleFile = (files.singleOrNull() as Path?).also {
|
||||||
|
it ?: fail("The directory must contain a single file, but got: $files")
|
||||||
|
}
|
||||||
|
|
||||||
|
return singleFile?.toFile()!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun assertFileContains(
|
||||||
|
file: File,
|
||||||
|
vararg expectedText: String,
|
||||||
|
) {
|
||||||
|
val text = file.readText()
|
||||||
|
val textNotInTheFile = expectedText.filterNot { text.contains(it) }
|
||||||
|
assert(textNotInTheFile.isEmpty()) {
|
||||||
|
"""
|
||||||
|
|$file does not contain:
|
||||||
|
|${textNotInTheFile.joinToString(separator = "\n")}
|
||||||
|
|
|
||||||
|
|actual file content:
|
||||||
|
|"$text"
|
||||||
|
|
|
||||||
|
""".trimMargin()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun validateAndDeleteReportFile(vararg expectedText: String) {
|
||||||
|
assertTrue(reportDir.exists())
|
||||||
|
val reportFile = getReportFile()
|
||||||
|
assertFileContains(reportFile, *expectedText)
|
||||||
|
reportFile.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
val reportMetricsList = arrayOf(
|
||||||
|
"Task 'kotlinProject' finished in",
|
||||||
|
"Task info:",
|
||||||
|
"Kotlin language version: 2.0",
|
||||||
|
"Time metrics:",
|
||||||
|
"Jps iteration:",
|
||||||
|
"Compiler code analysis:",
|
||||||
|
"Compiler code generation:"
|
||||||
|
)
|
||||||
|
|
||||||
|
fun testImpl() {
|
||||||
|
assertTrue("Daemon was not enabled!", isDaemonEnabled())
|
||||||
|
doTest()
|
||||||
|
|
||||||
|
validateAndDeleteReportFile(
|
||||||
|
*reportMetricsList,
|
||||||
|
"Changed files: [${workDir.resolve("src/Foo.kt").path}, ${workDir.resolve("src/main.kt").path}]"
|
||||||
|
)
|
||||||
|
|
||||||
|
val mainKt = File(workDir, "src/main.kt")
|
||||||
|
change(mainKt.path, "fun main() {}")
|
||||||
|
|
||||||
|
buildAllModules().assertSuccessful()
|
||||||
|
|
||||||
|
validateAndDeleteReportFile(
|
||||||
|
*reportMetricsList,
|
||||||
|
"Changed files: [${workDir.resolve("src/main.kt").path}]"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
withDaemon {
|
||||||
|
withSystemProperty("kotlin.build.report.file.output_dir", reportDir.path) {
|
||||||
|
testImpl()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun testJpsDaemonIC() {
|
fun testJpsDaemonIC() {
|
||||||
fun testImpl() {
|
fun testImpl() {
|
||||||
assertTrue("Daemon was not enabled!", isDaemonEnabled())
|
assertTrue("Daemon was not enabled!", isDaemonEnabled())
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.compilerRunner
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.*
|
||||||
|
import org.jetbrains.kotlin.daemon.common.*
|
||||||
|
import org.jetbrains.kotlin.jps.build.KotlinBuilder
|
||||||
|
import java.io.Serializable
|
||||||
|
import java.rmi.RemoteException
|
||||||
|
import java.rmi.server.UnicastRemoteObject
|
||||||
|
|
||||||
|
class JpsCompilationResult : CompilationResults,
|
||||||
|
UnicastRemoteObject(
|
||||||
|
SOCKET_ANY_FREE_PORT,
|
||||||
|
LoopbackNetworkInterface.clientLoopbackSocketFactory,
|
||||||
|
LoopbackNetworkInterface.serverLoopbackSocketFactory
|
||||||
|
) {
|
||||||
|
|
||||||
|
var icLogLines: List<String> = emptyList()
|
||||||
|
val compiledFiles = ArrayList<String>()
|
||||||
|
|
||||||
|
private val buildMetricsReporter = BuildMetricsReporterImpl<JpsBuildTime, JpsBuildPerformanceMetric>()
|
||||||
|
val buildMetrics: BuildMetrics<JpsBuildTime, JpsBuildPerformanceMetric>
|
||||||
|
get() = buildMetricsReporter.getMetrics()
|
||||||
|
private val log = JpsKotlinLogger(KotlinBuilder.LOG)
|
||||||
|
@Throws(RemoteException::class)
|
||||||
|
override fun add(compilationResultCategory: Int, value: Serializable) {
|
||||||
|
when (compilationResultCategory) {
|
||||||
|
CompilationResultCategory.IC_COMPILE_ITERATION.code -> {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val compileIterationResult = value as? CompileIterationResult
|
||||||
|
if (compileIterationResult != null) {
|
||||||
|
val sourceFiles = compileIterationResult.sourceFiles
|
||||||
|
buildMetrics.buildPerformanceMetrics.add(JpsBuildPerformanceMetric.IC_COMPILE_ITERATION)
|
||||||
|
compiledFiles.addAll(sourceFiles.map { it.path })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CompilationResultCategory.BUILD_REPORT_LINES.code,
|
||||||
|
CompilationResultCategory.VERBOSE_BUILD_REPORT_LINES.code -> {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
(value as? List<String>)?.let { icLogLines = it }
|
||||||
|
}
|
||||||
|
CompilationResultCategory.BUILD_METRICS.code -> {
|
||||||
|
(value as BuildMetricsValue).let {
|
||||||
|
when (it.key) {
|
||||||
|
CompilationPerformanceMetrics.CODE_GENERATION -> buildMetrics.buildTimes.addTimeMs(JpsBuildTime.CODE_GENERATION, it.value)
|
||||||
|
CompilationPerformanceMetrics.CODE_ANALYSIS -> buildMetrics.buildTimes.addTimeMs(JpsBuildTime.CODE_ANALYSIS, it.value)
|
||||||
|
CompilationPerformanceMetrics.COMPILER_INITIALIZATION -> buildMetrics.buildTimes.addTimeMs(JpsBuildTime.COMPILER_INITIALIZATION, it.value)
|
||||||
|
|
||||||
|
CompilationPerformanceMetrics.ANALYZED_LINES_NUMBER -> buildMetrics.buildPerformanceMetrics.add(JpsBuildPerformanceMetric.ANALYZED_LINES_NUMBER, it.value)
|
||||||
|
CompilationPerformanceMetrics.ANALYSIS_LPS -> buildMetrics.buildPerformanceMetrics.add(JpsBuildPerformanceMetric.ANALYSIS_LPS, it.value)
|
||||||
|
CompilationPerformanceMetrics.CODE_GENERATED_LINES_NUMBER -> buildMetrics.buildPerformanceMetrics.add(JpsBuildPerformanceMetric.CODE_GENERATED_LINES_NUMBER, it.value)
|
||||||
|
CompilationPerformanceMetrics.CODE_GENERATION_LPS -> buildMetrics.buildPerformanceMetrics.add(JpsBuildPerformanceMetric.CODE_GENERATION_LPS, it.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.daemon.client.CompileServiceSession
|
|||||||
import org.jetbrains.kotlin.daemon.client.KotlinCompilerClient
|
import org.jetbrains.kotlin.daemon.client.KotlinCompilerClient
|
||||||
import org.jetbrains.kotlin.daemon.common.*
|
import org.jetbrains.kotlin.daemon.common.*
|
||||||
import org.jetbrains.kotlin.jps.build.KotlinBuilder
|
import org.jetbrains.kotlin.jps.build.KotlinBuilder
|
||||||
|
import org.jetbrains.kotlin.jps.statistic.JpsBuilderMetricReporter
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
@@ -91,7 +92,7 @@ class JpsKotlinCompilerRunner {
|
|||||||
|
|
||||||
fun classesFqNamesByFiles(
|
fun classesFqNamesByFiles(
|
||||||
environment: JpsCompilerEnvironment,
|
environment: JpsCompilerEnvironment,
|
||||||
files: Set<File>
|
files: Set<File>,
|
||||||
): Set<String> = withDaemonOrFallback(
|
): Set<String> = withDaemonOrFallback(
|
||||||
withDaemon = {
|
withDaemon = {
|
||||||
doWithDaemon(environment) { sessionId, daemon ->
|
doWithDaemon(environment) { sessionId, daemon ->
|
||||||
@@ -113,7 +114,8 @@ class JpsKotlinCompilerRunner {
|
|||||||
environment: JpsCompilerEnvironment,
|
environment: JpsCompilerEnvironment,
|
||||||
destination: String,
|
destination: String,
|
||||||
classpath: Collection<String>,
|
classpath: Collection<String>,
|
||||||
sourceFiles: Collection<File>
|
sourceFiles: Collection<File>,
|
||||||
|
buildMetricReporter: JpsBuilderMetricReporter?,
|
||||||
) {
|
) {
|
||||||
val arguments = mergeBeans(commonArguments, XmlSerializerUtil.createCopy(k2MetadataArguments))
|
val arguments = mergeBeans(commonArguments, XmlSerializerUtil.createCopy(k2MetadataArguments))
|
||||||
|
|
||||||
@@ -124,7 +126,7 @@ class JpsKotlinCompilerRunner {
|
|||||||
arguments.destination = arguments.destination ?: destination
|
arguments.destination = arguments.destination ?: destination
|
||||||
|
|
||||||
withCompilerSettings(compilerSettings) {
|
withCompilerSettings(compilerSettings) {
|
||||||
runCompiler(KotlinCompilerClass.METADATA, arguments, environment)
|
runCompiler(KotlinCompilerClass.METADATA, arguments, environment, buildMetricReporter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,12 +135,13 @@ class JpsKotlinCompilerRunner {
|
|||||||
k2jvmArguments: K2JVMCompilerArguments,
|
k2jvmArguments: K2JVMCompilerArguments,
|
||||||
compilerSettings: CompilerSettings,
|
compilerSettings: CompilerSettings,
|
||||||
environment: JpsCompilerEnvironment,
|
environment: JpsCompilerEnvironment,
|
||||||
moduleFile: File
|
moduleFile: File,
|
||||||
|
buildMetricReporter: JpsBuilderMetricReporter?,
|
||||||
) {
|
) {
|
||||||
val arguments = mergeBeans(commonArguments, XmlSerializerUtil.createCopy(k2jvmArguments))
|
val arguments = mergeBeans(commonArguments, XmlSerializerUtil.createCopy(k2jvmArguments))
|
||||||
setupK2JvmArguments(moduleFile, arguments)
|
setupK2JvmArguments(moduleFile, arguments)
|
||||||
withCompilerSettings(compilerSettings) {
|
withCompilerSettings(compilerSettings) {
|
||||||
runCompiler(KotlinCompilerClass.JVM, arguments, environment)
|
runCompiler(KotlinCompilerClass.JVM, arguments, environment, buildMetricReporter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +155,8 @@ class JpsKotlinCompilerRunner {
|
|||||||
sourceMapRoots: Collection<File>,
|
sourceMapRoots: Collection<File>,
|
||||||
libraries: List<String>,
|
libraries: List<String>,
|
||||||
friendModules: List<String>,
|
friendModules: List<String>,
|
||||||
outputFile: File
|
outputFile: File,
|
||||||
|
buildMetricReporter: JpsBuilderMetricReporter?,
|
||||||
) {
|
) {
|
||||||
log.debug("K2JS: common arguments: " + ArgumentUtils.convertArgumentsToStringList(commonArguments))
|
log.debug("K2JS: common arguments: " + ArgumentUtils.convertArgumentsToStringList(commonArguments))
|
||||||
log.debug("K2JS: JS arguments: " + ArgumentUtils.convertArgumentsToStringList(k2jsArguments))
|
log.debug("K2JS: JS arguments: " + ArgumentUtils.convertArgumentsToStringList(k2jsArguments))
|
||||||
@@ -168,26 +172,32 @@ class JpsKotlinCompilerRunner {
|
|||||||
log.debug("K2JS: arguments after setup" + ArgumentUtils.convertArgumentsToStringList(arguments))
|
log.debug("K2JS: arguments after setup" + ArgumentUtils.convertArgumentsToStringList(arguments))
|
||||||
|
|
||||||
withCompilerSettings(compilerSettings) {
|
withCompilerSettings(compilerSettings) {
|
||||||
runCompiler(KotlinCompilerClass.JS, arguments, environment)
|
runCompiler(KotlinCompilerClass.JS, arguments, environment, buildMetricReporter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun compileWithDaemonOrFallback(
|
private fun compileWithDaemonOrFallback(
|
||||||
compilerClassName: String,
|
compilerClassName: String,
|
||||||
compilerArgs: CommonCompilerArguments,
|
compilerArgs: CommonCompilerArguments,
|
||||||
environment: JpsCompilerEnvironment
|
environment: JpsCompilerEnvironment,
|
||||||
|
buildMetricReporter: JpsBuilderMetricReporter?,
|
||||||
) {
|
) {
|
||||||
log.debug("Using kotlin-home = " + environment.kotlinPaths.homePath)
|
log.debug("Using kotlin-home = " + environment.kotlinPaths.homePath)
|
||||||
|
|
||||||
withDaemonOrFallback(
|
withDaemonOrFallback(
|
||||||
withDaemon = { compileWithDaemon(compilerClassName, compilerArgs, environment) },
|
withDaemon = { compileWithDaemon(compilerClassName, compilerArgs, environment, buildMetricReporter) },
|
||||||
fallback = { fallbackCompileStrategy(compilerArgs, compilerClassName, environment) }
|
fallback = { fallbackCompileStrategy(compilerArgs, compilerClassName, environment) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun runCompiler(compilerClassName: String, compilerArgs: CommonCompilerArguments, environment: JpsCompilerEnvironment) {
|
private fun runCompiler(
|
||||||
|
compilerClassName: String,
|
||||||
|
compilerArgs: CommonCompilerArguments,
|
||||||
|
environment: JpsCompilerEnvironment,
|
||||||
|
buildMetricReporter: JpsBuilderMetricReporter?,
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
compileWithDaemonOrFallback(compilerClassName, compilerArgs, environment)
|
compileWithDaemonOrFallback(compilerClassName, compilerArgs, environment, buildMetricReporter)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
MessageCollectorUtil.reportException(environment.messageCollector, e)
|
MessageCollectorUtil.reportException(environment.messageCollector, e)
|
||||||
reportInternalCompilerError(environment.messageCollector)
|
reportInternalCompilerError(environment.messageCollector)
|
||||||
@@ -197,7 +207,8 @@ class JpsKotlinCompilerRunner {
|
|||||||
private fun compileWithDaemon(
|
private fun compileWithDaemon(
|
||||||
compilerClassName: String,
|
compilerClassName: String,
|
||||||
compilerArgs: CommonCompilerArguments,
|
compilerArgs: CommonCompilerArguments,
|
||||||
environment: JpsCompilerEnvironment
|
environment: JpsCompilerEnvironment,
|
||||||
|
buildMetricReporter: JpsBuilderMetricReporter?,
|
||||||
): Int? {
|
): Int? {
|
||||||
val targetPlatform = when (compilerClassName) {
|
val targetPlatform = when (compilerClassName) {
|
||||||
KotlinCompilerClass.JVM -> CompileService.TargetPlatform.JVM
|
KotlinCompilerClass.JVM -> CompileService.TargetPlatform.JVM
|
||||||
@@ -214,6 +225,8 @@ class JpsKotlinCompilerRunner {
|
|||||||
reportSeverity(verbose),
|
reportSeverity(verbose),
|
||||||
requestedCompilationResults = emptyArray()
|
requestedCompilationResults = emptyArray()
|
||||||
)
|
)
|
||||||
|
val compilationResult = JpsCompilationResult()
|
||||||
|
|
||||||
return doWithDaemon(environment) { sessionId, daemon ->
|
return doWithDaemon(environment) { sessionId, daemon ->
|
||||||
environment.withProgressReporter { progress ->
|
environment.withProgressReporter { progress ->
|
||||||
progress.compilationStarted()
|
progress.compilationStarted()
|
||||||
@@ -222,8 +235,10 @@ class JpsKotlinCompilerRunner {
|
|||||||
withAdditionalCompilerArgs(compilerArgs),
|
withAdditionalCompilerArgs(compilerArgs),
|
||||||
options,
|
options,
|
||||||
JpsCompilerServicesFacadeImpl(environment),
|
JpsCompilerServicesFacadeImpl(environment),
|
||||||
null
|
compilationResult
|
||||||
)
|
)
|
||||||
|
}.also {
|
||||||
|
buildMetricReporter?.addCompilerMetrics(compilationResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,7 +252,7 @@ class JpsKotlinCompilerRunner {
|
|||||||
|
|
||||||
private fun <T> doWithDaemon(
|
private fun <T> doWithDaemon(
|
||||||
environment: JpsCompilerEnvironment,
|
environment: JpsCompilerEnvironment,
|
||||||
fn: (sessionId: Int, daemon: CompileService) -> CompileService.CallResult<T>
|
fn: (sessionId: Int, daemon: CompileService) -> CompileService.CallResult<T>,
|
||||||
): T? {
|
): T? {
|
||||||
log.debug("Try to connect to daemon")
|
log.debug("Try to connect to daemon")
|
||||||
val connection = getDaemonConnection(environment)
|
val connection = getDaemonConnection(environment)
|
||||||
@@ -280,7 +295,7 @@ class JpsKotlinCompilerRunner {
|
|||||||
private fun fallbackCompileStrategy(
|
private fun fallbackCompileStrategy(
|
||||||
compilerArgs: CommonCompilerArguments,
|
compilerArgs: CommonCompilerArguments,
|
||||||
compilerClassName: String,
|
compilerClassName: String,
|
||||||
environment: JpsCompilerEnvironment
|
environment: JpsCompilerEnvironment,
|
||||||
) {
|
) {
|
||||||
if ("true" == System.getProperty("kotlin.jps.tests") && "true" == System.getProperty(FAIL_ON_FALLBACK_PROPERTY)) {
|
if ("true" == System.getProperty("kotlin.jps.tests") && "true" == System.getProperty(FAIL_ON_FALLBACK_PROPERTY)) {
|
||||||
error("Cannot compile with Daemon, see logs bellow. Fallback strategy is disabled in tests")
|
error("Cannot compile with Daemon, see logs bellow. Fallback strategy is disabled in tests")
|
||||||
@@ -325,7 +340,7 @@ class JpsKotlinCompilerRunner {
|
|||||||
_commonSources: Collection<File>,
|
_commonSources: Collection<File>,
|
||||||
_libraries: List<String>,
|
_libraries: List<String>,
|
||||||
_friendModules: List<String>,
|
_friendModules: List<String>,
|
||||||
settings: K2JSCompilerArguments
|
settings: K2JSCompilerArguments,
|
||||||
) {
|
) {
|
||||||
with(settings) {
|
with(settings) {
|
||||||
noStdlib = true
|
noStdlib = true
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.build.report.ICReporter.ReportSeverity
|
|||||||
import org.jetbrains.kotlin.build.report.ICReporterBase
|
import org.jetbrains.kotlin.build.report.ICReporterBase
|
||||||
import org.jetbrains.kotlin.build.report.debug
|
import org.jetbrains.kotlin.build.report.debug
|
||||||
import org.jetbrains.kotlin.build.report.metrics.JpsBuildTime
|
import org.jetbrains.kotlin.build.report.metrics.JpsBuildTime
|
||||||
|
import org.jetbrains.kotlin.build.report.statistics.StatTag
|
||||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
|
||||||
@@ -40,7 +41,9 @@ import org.jetbrains.kotlin.jps.KotlinJpsBundle
|
|||||||
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache
|
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache
|
||||||
import org.jetbrains.kotlin.jps.incremental.JpsLookupStorageManager
|
import org.jetbrains.kotlin.jps.incremental.JpsLookupStorageManager
|
||||||
import org.jetbrains.kotlin.jps.model.kotlinKind
|
import org.jetbrains.kotlin.jps.model.kotlinKind
|
||||||
|
import org.jetbrains.kotlin.jps.statistic.JpsBuilderMetricReporter
|
||||||
import org.jetbrains.kotlin.jps.statistic.JpsStatisticsReportService
|
import org.jetbrains.kotlin.jps.statistic.JpsStatisticsReportService
|
||||||
|
import org.jetbrains.kotlin.jps.statistic.statisticsReportServiceKey
|
||||||
import org.jetbrains.kotlin.jps.targets.KotlinJvmModuleBuildTarget
|
import org.jetbrains.kotlin.jps.targets.KotlinJvmModuleBuildTarget
|
||||||
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
|
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||||
@@ -66,7 +69,6 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
System.getProperty("kotlin.jps.classesToLoadByParent")?.split(',')?.map { it.trim() } ?: emptyList()
|
System.getProperty("kotlin.jps.classesToLoadByParent")?.split(',')?.map { it.trim() } ?: emptyList()
|
||||||
private val classPrefixesToLoadByParentFromRegistry =
|
private val classPrefixesToLoadByParentFromRegistry =
|
||||||
System.getProperty("kotlin.jps.classPrefixesToLoadByParent")?.split(',')?.map { it.trim() } ?: emptyList()
|
System.getProperty("kotlin.jps.classPrefixesToLoadByParent")?.split(',')?.map { it.trim() } ?: emptyList()
|
||||||
private val reportService = JpsStatisticsReportService.create()
|
|
||||||
|
|
||||||
val classesToLoadByParent: ClassCondition
|
val classesToLoadByParent: ClassCondition
|
||||||
get() = ClassCondition { className ->
|
get() = ClassCondition { className ->
|
||||||
@@ -100,6 +102,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
|
|
||||||
override fun buildStarted(context: CompileContext) {
|
override fun buildStarted(context: CompileContext) {
|
||||||
logSettings(context)
|
logSettings(context)
|
||||||
|
val reportService = JpsStatisticsReportService.create()
|
||||||
|
context.putUserData(statisticsReportServiceKey, reportService)
|
||||||
reportService.buildStarted(context)
|
reportService.buildStarted(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,6 +165,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
|
|
||||||
override fun buildFinished(context: CompileContext) {
|
override fun buildFinished(context: CompileContext) {
|
||||||
ensureKotlinContextDisposed(context)
|
ensureKotlinContextDisposed(context)
|
||||||
|
val reportService = JpsStatisticsReportService.getFromContext(context)
|
||||||
reportService.buildFinish(context)
|
reportService.buildFinish(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,7 +300,19 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
|
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
|
||||||
outputConsumer: OutputConsumer
|
outputConsumer: OutputConsumer
|
||||||
): ExitCode {
|
): ExitCode {
|
||||||
|
val reportService = JpsStatisticsReportService.getFromContext(context)
|
||||||
reportService.moduleBuildStarted(chunk)
|
reportService.moduleBuildStarted(chunk)
|
||||||
|
return doBuild(context, chunk, dirtyFilesHolder, outputConsumer).also { result ->
|
||||||
|
reportService.moduleBuildFinished(chunk, context, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doBuild(
|
||||||
|
context: CompileContext,
|
||||||
|
chunk: ModuleChunk,
|
||||||
|
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
|
||||||
|
outputConsumer: OutputConsumer
|
||||||
|
): ExitCode {
|
||||||
if (chunk.isDummy(context))
|
if (chunk.isDummy(context))
|
||||||
return NOTHING_DONE
|
return NOTHING_DONE
|
||||||
|
|
||||||
@@ -320,6 +337,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
val fsOperations = FSOperationsHelper(context, chunk, kotlinDirtyFilesHolder, LOG)
|
val fsOperations = FSOperationsHelper(context, chunk, kotlinDirtyFilesHolder, LOG)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
val reportService = JpsStatisticsReportService.getFromContext(context)
|
||||||
|
reportService.reportDirtyFiles(kotlinDirtyFilesHolder)
|
||||||
return reportService.reportMetrics(chunk, JpsBuildTime.JPS_ITERATION) {
|
return reportService.reportMetrics(chunk, JpsBuildTime.JPS_ITERATION) {
|
||||||
val proposedExitCode =
|
val proposedExitCode =
|
||||||
doBuild(chunk, kotlinTarget, context, kotlinDirtyFilesHolder, messageCollector, outputConsumer, fsOperations)
|
doBuild(chunk, kotlinTarget, context, kotlinDirtyFilesHolder, messageCollector, outputConsumer, fsOperations)
|
||||||
@@ -342,8 +361,6 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
LOG.info("Caught exception: $e")
|
LOG.info("Caught exception: $e")
|
||||||
MessageCollectorUtil.reportException(messageCollector, e)
|
MessageCollectorUtil.reportException(messageCollector, e)
|
||||||
return ABORT
|
return ABORT
|
||||||
} finally {
|
|
||||||
reportService.moduleBuildFinished(chunk, context)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,7 +371,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
kotlinDirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
kotlinDirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
||||||
messageCollector: MessageCollectorAdapter,
|
messageCollector: MessageCollectorAdapter,
|
||||||
outputConsumer: OutputConsumer,
|
outputConsumer: OutputConsumer,
|
||||||
fsOperations: FSOperationsHelper
|
fsOperations: FSOperationsHelper,
|
||||||
): ExitCode {
|
): ExitCode {
|
||||||
// Workaround for Android Studio
|
// Workaround for Android Studio
|
||||||
if (representativeTarget is KotlinJvmModuleBuildTarget && !JavaBuilder.IS_ENABLED[context, true]) {
|
if (representativeTarget is KotlinJvmModuleBuildTarget && !JavaBuilder.IS_ENABLED[context, true]) {
|
||||||
@@ -448,6 +465,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
LOG.debug("Compiling files: ${kotlinDirtyFilesHolder.allDirtyFiles}")
|
LOG.debug("Compiling files: ${kotlinDirtyFilesHolder.allDirtyFiles}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val reportService = JpsStatisticsReportService.getFromContext(context)
|
||||||
|
reportService.reportCompilerArguments(chunk, kotlinChunk)
|
||||||
val start = System.nanoTime()
|
val start = System.nanoTime()
|
||||||
val outputItemCollector = doCompileModuleChunk(
|
val outputItemCollector = doCompileModuleChunk(
|
||||||
kotlinChunk,
|
kotlinChunk,
|
||||||
@@ -457,7 +476,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
kotlinDirtyFilesHolder,
|
kotlinDirtyFilesHolder,
|
||||||
fsOperations,
|
fsOperations,
|
||||||
environment,
|
environment,
|
||||||
incrementalCaches
|
incrementalCaches,
|
||||||
|
reportService.getMetricReporter(chunk)
|
||||||
)
|
)
|
||||||
|
|
||||||
statisticsLogger.registerStatistic(chunk, System.nanoTime() - start)
|
statisticsLogger.registerStatistic(chunk, System.nanoTime() - start)
|
||||||
@@ -591,13 +611,15 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
||||||
fsOperations: FSOperationsHelper,
|
fsOperations: FSOperationsHelper,
|
||||||
environment: JpsCompilerEnvironment,
|
environment: JpsCompilerEnvironment,
|
||||||
incrementalCaches: Map<KotlinModuleBuildTarget<*>, JpsIncrementalCache>
|
incrementalCaches: Map<KotlinModuleBuildTarget<*>, JpsIncrementalCache>,
|
||||||
|
buildMetricReporter: JpsBuilderMetricReporter?,
|
||||||
): OutputItemsCollector? {
|
): OutputItemsCollector? {
|
||||||
kotlinChunk.targets.forEach {
|
kotlinChunk.targets.forEach {
|
||||||
it.nextRound(context)
|
it.nextRound(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (representativeTarget.isIncrementalCompilationEnabled) {
|
if (representativeTarget.isIncrementalCompilationEnabled) {
|
||||||
|
buildMetricReporter?.addTag(StatTag.INCREMENTAL)
|
||||||
for (target in kotlinChunk.targets) {
|
for (target in kotlinChunk.targets) {
|
||||||
val cache = incrementalCaches[target]
|
val cache = incrementalCaches[target]
|
||||||
val jpsTarget = target.jpsModuleBuildTarget
|
val jpsTarget = target.jpsModuleBuildTarget
|
||||||
@@ -613,7 +635,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val isDoneSomething = representativeTarget.compileModuleChunk(commonArguments, dirtyFilesHolder, environment)
|
val isDoneSomething = representativeTarget.compileModuleChunk(commonArguments, dirtyFilesHolder, environment, buildMetricReporter)
|
||||||
|
|
||||||
return if (isDoneSomething) environment.outputItemsCollector else null
|
return if (isDoneSomething) environment.outputItemsCollector else null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.jps.statistic
|
||||||
|
|
||||||
|
import org.jetbrains.jps.ModuleChunk
|
||||||
|
import org.jetbrains.jps.incremental.CompileContext
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.JpsBuildPerformanceMetric
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.JpsBuildTime
|
||||||
|
import org.jetbrains.kotlin.build.report.statistics.StatTag
|
||||||
|
import org.jetbrains.kotlin.compilerRunner.JpsCompilationResult
|
||||||
|
|
||||||
|
interface JpsBuilderMetricReporter : BuildMetricsReporter<JpsBuildTime, JpsBuildPerformanceMetric> {
|
||||||
|
fun flush(context: CompileContext): JpsCompileStatisticsData
|
||||||
|
|
||||||
|
fun buildFinish(moduleChunk: ModuleChunk, context: CompileContext, exitCode: String)
|
||||||
|
|
||||||
|
fun addChangedFiles(files: List<String>)
|
||||||
|
|
||||||
|
fun addCompilerArguments(arguments: List<String>)
|
||||||
|
|
||||||
|
fun setKotlinLanguageVersion(languageVersion: String?)
|
||||||
|
|
||||||
|
fun addTag(tag: StatTag)
|
||||||
|
|
||||||
|
fun addCompilerMetrics(jpsCompilationResult: JpsCompilationResult)
|
||||||
|
}
|
||||||
+104
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.jps.statistic
|
||||||
|
|
||||||
|
import org.jetbrains.jps.ModuleChunk
|
||||||
|
import org.jetbrains.jps.incremental.CompileContext
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporterImpl
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.JpsBuildPerformanceMetric
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.JpsBuildTime
|
||||||
|
import org.jetbrains.kotlin.build.report.statistics.BuildDataType
|
||||||
|
import org.jetbrains.kotlin.build.report.statistics.StatTag
|
||||||
|
import org.jetbrains.kotlin.compilerRunner.JpsCompilationResult
|
||||||
|
import java.net.InetAddress
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
class JpsBuilderMetricReporterImpl(
|
||||||
|
chunk: ModuleChunk,
|
||||||
|
private val reporter: BuildMetricsReporterImpl<JpsBuildTime, JpsBuildPerformanceMetric>,
|
||||||
|
private val label: String? = null,
|
||||||
|
private val kotlinVersion: String = "kotlin_version"
|
||||||
|
) :
|
||||||
|
JpsBuilderMetricReporter, BuildMetricsReporter<JpsBuildTime, JpsBuildPerformanceMetric> by reporter {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val hostName: String? = try {
|
||||||
|
InetAddress.getLocalHost().hostName
|
||||||
|
} catch (_: Exception) {
|
||||||
|
//do nothing
|
||||||
|
null
|
||||||
|
}
|
||||||
|
private val uuid = UUID.randomUUID()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private val startTime = System.currentTimeMillis()
|
||||||
|
private var finishTime: Long = 0L
|
||||||
|
private val tags = HashSet<StatTag>()
|
||||||
|
private val changedFiles = ArrayList<String>()
|
||||||
|
private val compilerArguments = ArrayList<String>()
|
||||||
|
private val moduleString = chunk.name
|
||||||
|
private var exitCode = "Unknown"
|
||||||
|
private var kotlinLanguageVersion: String? = null
|
||||||
|
|
||||||
|
override fun buildFinish(moduleChunk: ModuleChunk, context: CompileContext, exitCode: String) {
|
||||||
|
finishTime = System.currentTimeMillis()
|
||||||
|
this.exitCode = exitCode
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addChangedFiles(files: List<String>) {
|
||||||
|
changedFiles.addAll(files)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addCompilerArguments(arguments: List<String>) {
|
||||||
|
compilerArguments.addAll(arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setKotlinLanguageVersion(languageVersion: String?) {
|
||||||
|
kotlinLanguageVersion = languageVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addTag(tag: StatTag) {
|
||||||
|
tags.add(tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addCompilerMetrics(jpsCompilationResult: JpsCompilationResult) {
|
||||||
|
reporter.addMetrics(jpsCompilationResult.buildMetrics)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun flush(context: CompileContext): JpsCompileStatisticsData {
|
||||||
|
val buildMetrics = reporter.getMetrics()
|
||||||
|
return JpsCompileStatisticsData(
|
||||||
|
projectName = context.projectDescriptor.project.name,
|
||||||
|
label = label,
|
||||||
|
taskName = moduleString,
|
||||||
|
taskResult = exitCode,
|
||||||
|
startTimeMs = startTime,
|
||||||
|
durationMs = finishTime - startTime,
|
||||||
|
tags = tags,
|
||||||
|
buildUuid = uuid.toString(),
|
||||||
|
changes = changedFiles,
|
||||||
|
kotlinVersion = kotlinVersion,
|
||||||
|
hostName = hostName,
|
||||||
|
finishTime = finishTime,
|
||||||
|
buildTimesMetrics = buildMetrics.buildTimes.asMapMs(),
|
||||||
|
performanceMetrics = buildMetrics.buildPerformanceMetrics.asMap(),
|
||||||
|
compilerArguments = compilerArguments,
|
||||||
|
nonIncrementalAttributes = emptySet(),
|
||||||
|
type = BuildDataType.JPS_DATA.name,
|
||||||
|
fromKotlinPlugin = true,
|
||||||
|
compiledSources = emptyList(),
|
||||||
|
skipMessage = null,
|
||||||
|
icLogLines = emptyList(),
|
||||||
|
gcTimeMetrics = buildMetrics.gcMetrics.asGcTimeMap(),
|
||||||
|
gcCountMetrics = buildMetrics.gcMetrics.asGcCountMap(),
|
||||||
|
kotlinLanguageVersion = kotlinLanguageVersion
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.jps.statistic
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.JpsBuildPerformanceMetric
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.JpsBuildTime
|
||||||
|
import org.jetbrains.kotlin.build.report.statistics.CompileStatisticsData
|
||||||
|
import org.jetbrains.kotlin.build.report.statistics.file.FileReportService
|
||||||
|
import org.jetbrains.kotlin.compilerRunner.JpsKotlinLogger
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
internal class JpsFileReportService(
|
||||||
|
buildReportDir: File,
|
||||||
|
projectName: String,
|
||||||
|
printMetrics: Boolean,
|
||||||
|
logger: JpsKotlinLogger,
|
||||||
|
) : FileReportService<JpsBuildTime, JpsBuildPerformanceMetric>(buildReportDir, projectName, printMetrics, logger) {
|
||||||
|
override fun printCustomTaskMetrics(statisticsData: CompileStatisticsData<JpsBuildTime, JpsBuildPerformanceMetric>) {
|
||||||
|
p.print("Changed files: ${statisticsData.getChanges().sorted()}")
|
||||||
|
p.print("Execution result: ${statisticsData.getTaskResult()}")
|
||||||
|
}
|
||||||
|
}
|
||||||
+44
-81
@@ -8,92 +8,29 @@ package org.jetbrains.kotlin.jps.statistic
|
|||||||
import com.intellij.openapi.diagnostic.Logger
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import org.jetbrains.jps.ModuleChunk
|
import org.jetbrains.jps.ModuleChunk
|
||||||
import org.jetbrains.jps.incremental.CompileContext
|
import org.jetbrains.jps.incremental.CompileContext
|
||||||
|
import org.jetbrains.jps.incremental.GlobalContextKey
|
||||||
|
import org.jetbrains.jps.incremental.ModuleLevelBuilder
|
||||||
|
import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode
|
||||||
import org.jetbrains.kotlin.build.report.FileReportSettings
|
import org.jetbrains.kotlin.build.report.FileReportSettings
|
||||||
import org.jetbrains.kotlin.build.report.HttpReportSettings
|
import org.jetbrains.kotlin.build.report.HttpReportSettings
|
||||||
import org.jetbrains.kotlin.build.report.metrics.*
|
import org.jetbrains.kotlin.build.report.metrics.*
|
||||||
import org.jetbrains.kotlin.build.report.statistics.BuildDataType
|
import org.jetbrains.kotlin.build.report.statistics.*
|
||||||
import org.jetbrains.kotlin.build.report.statistics.BuildStartParameters
|
|
||||||
import org.jetbrains.kotlin.build.report.statistics.HttpReportService
|
|
||||||
import org.jetbrains.kotlin.build.report.statistics.StatTag
|
|
||||||
import org.jetbrains.kotlin.build.report.statistics.file.FileReportService
|
|
||||||
import org.jetbrains.kotlin.compilerRunner.JpsKotlinLogger
|
import org.jetbrains.kotlin.compilerRunner.JpsKotlinLogger
|
||||||
|
import org.jetbrains.kotlin.jps.build.KotlinChunk
|
||||||
|
import org.jetbrains.kotlin.jps.build.KotlinCompileContext
|
||||||
|
import org.jetbrains.kotlin.jps.build.KotlinDirtySourceFilesHolder
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.InetAddress
|
|
||||||
import java.util.*
|
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue
|
import java.util.concurrent.ConcurrentLinkedQueue
|
||||||
|
|
||||||
interface JpsBuilderMetricReporter : BuildMetricsReporter<JpsBuildTime, JpsBuildPerformanceMetric> {
|
|
||||||
fun flush(context: CompileContext): JpsCompileStatisticsData
|
|
||||||
|
|
||||||
fun buildFinish(moduleChunk: ModuleChunk, context: CompileContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
private const val jpsBuildTaskName = "JPS build"
|
private const val jpsBuildTaskName = "JPS build"
|
||||||
|
|
||||||
class JpsBuilderMetricReporterImpl(
|
|
||||||
chunk: ModuleChunk,
|
|
||||||
private val reporter: BuildMetricsReporterImpl<JpsBuildTime, JpsBuildPerformanceMetric>,
|
|
||||||
private val label: String? = null,
|
|
||||||
private val kotlinVersion: String = "kotlin_version",
|
|
||||||
) :
|
|
||||||
JpsBuilderMetricReporter, BuildMetricsReporter<JpsBuildTime, JpsBuildPerformanceMetric> by reporter {
|
|
||||||
|
|
||||||
companion object {
|
internal val statisticsReportServiceKey = GlobalContextKey<JpsStatisticsReportService>("jpsStatistics")
|
||||||
private val hostName: String? = try {
|
|
||||||
InetAddress.getLocalHost().hostName
|
|
||||||
} catch (_: Exception) {
|
|
||||||
//do nothing
|
|
||||||
null
|
|
||||||
}
|
|
||||||
private val uuid = UUID.randomUUID()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private val startTime = System.currentTimeMillis()
|
|
||||||
private var finishTime: Long = 0L
|
|
||||||
private val tags = HashSet<StatTag>()
|
|
||||||
private val moduleString = chunk.name
|
|
||||||
|
|
||||||
override fun buildFinish(moduleChunk: ModuleChunk, context: CompileContext) {
|
|
||||||
finishTime = System.currentTimeMillis()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun flush(context: CompileContext): JpsCompileStatisticsData {
|
|
||||||
val buildMetrics = reporter.getMetrics()
|
|
||||||
return JpsCompileStatisticsData(
|
|
||||||
projectName = context.projectDescriptor.project.name,
|
|
||||||
label = label,
|
|
||||||
taskName = moduleString,
|
|
||||||
taskResult = "Unknown",//TODO will be updated in KT-58026
|
|
||||||
startTimeMs = startTime,
|
|
||||||
durationMs = finishTime - startTime,
|
|
||||||
tags = tags,
|
|
||||||
buildUuid = uuid.toString(),
|
|
||||||
changes = emptyList(), //TODO will be updated in KT-58026
|
|
||||||
kotlinVersion = kotlinVersion,
|
|
||||||
hostName = hostName,
|
|
||||||
finishTime = finishTime,
|
|
||||||
buildTimesMetrics = buildMetrics.buildTimes.asMapMs(),
|
|
||||||
performanceMetrics = buildMetrics.buildPerformanceMetrics.asMap(),
|
|
||||||
compilerArguments = emptyList(), //TODO will be updated in KT-58026
|
|
||||||
nonIncrementalAttributes = emptySet(),
|
|
||||||
type = BuildDataType.JPS_DATA.name,
|
|
||||||
fromKotlinPlugin = true,
|
|
||||||
compiledSources = emptyList(),
|
|
||||||
skipMessage = null,
|
|
||||||
icLogLines = emptyList(),
|
|
||||||
gcTimeMetrics = buildMetrics.gcMetrics.asGcTimeMap(),
|
|
||||||
gcCountMetrics = buildMetrics.gcMetrics.asGcCountMap(),
|
|
||||||
kotlinLanguageVersion = null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class JpsStatisticsReportService {
|
sealed class JpsStatisticsReportService {
|
||||||
companion object {
|
companion object {
|
||||||
fun create(): JpsStatisticsReportService {
|
internal fun create(): JpsStatisticsReportService {
|
||||||
val fileReportSettings = initFileReportSettings()
|
val fileReportSettings = initFileReportSettings()
|
||||||
val httpReportSettings = initHttpReportSettings()
|
val httpReportSettings = initHttpReportSettings()
|
||||||
|
|
||||||
@@ -102,9 +39,11 @@ sealed class JpsStatisticsReportService {
|
|||||||
} else {
|
} else {
|
||||||
JpsStatisticsReportServiceImpl(fileReportSettings, httpReportSettings)
|
JpsStatisticsReportServiceImpl(fileReportSettings, httpReportSettings)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun getFromContext(context: CompileContext): JpsStatisticsReportService =
|
||||||
|
context.getUserData(statisticsReportServiceKey) ?: DummyJpsStatisticsReportService
|
||||||
|
|
||||||
private fun initFileReportSettings(): FileReportSettings? {
|
private fun initFileReportSettings(): FileReportSettings? {
|
||||||
return System.getProperty("kotlin.build.report.file.output_dir")?.let { FileReportSettings(File(it)) }
|
return System.getProperty("kotlin.build.report.file.output_dir")?.let { FileReportSettings(File(it)) }
|
||||||
}
|
}
|
||||||
@@ -123,8 +62,12 @@ sealed class JpsStatisticsReportService {
|
|||||||
abstract fun buildStarted(context: CompileContext)
|
abstract fun buildStarted(context: CompileContext)
|
||||||
abstract fun buildFinish(context: CompileContext)
|
abstract fun buildFinish(context: CompileContext)
|
||||||
|
|
||||||
abstract fun moduleBuildFinished(chunk: ModuleChunk, context: CompileContext)
|
abstract fun moduleBuildFinished(chunk: ModuleChunk, context: CompileContext, exitCode: ModuleLevelBuilder.ExitCode)
|
||||||
abstract fun moduleBuildStarted(chunk: ModuleChunk)
|
abstract fun moduleBuildStarted(chunk: ModuleChunk)
|
||||||
|
|
||||||
|
abstract fun reportDirtyFiles(kotlinDirtySourceFilesHolder: KotlinDirtySourceFilesHolder)
|
||||||
|
abstract fun reportCompilerArguments(chunk: ModuleChunk, kotlinChunk: KotlinChunk)
|
||||||
|
abstract fun getMetricReporter(chunk: ModuleChunk): JpsBuilderMetricReporter?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -135,9 +78,13 @@ object DummyJpsStatisticsReportService : JpsStatisticsReportService() {
|
|||||||
|
|
||||||
override fun buildStarted(context: CompileContext) {}
|
override fun buildStarted(context: CompileContext) {}
|
||||||
override fun buildFinish(context: CompileContext) {}
|
override fun buildFinish(context: CompileContext) {}
|
||||||
override fun moduleBuildFinished(chunk: ModuleChunk, context: CompileContext) {}
|
override fun moduleBuildFinished(chunk: ModuleChunk, context: CompileContext, exitCode: ExitCode) {}
|
||||||
override fun moduleBuildStarted(chunk: ModuleChunk) {}
|
override fun moduleBuildStarted(chunk: ModuleChunk) {}
|
||||||
|
|
||||||
|
override fun reportDirtyFiles(kotlinDirtySourceFilesHolder: KotlinDirtySourceFilesHolder) {}
|
||||||
|
override fun reportCompilerArguments(chunk: ModuleChunk, kotlinChunk: KotlinChunk) {}
|
||||||
|
override fun getMetricReporter(chunk: ModuleChunk): JpsBuilderMetricReporter? = null
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class JpsStatisticsReportServiceImpl(
|
class JpsStatisticsReportServiceImpl(
|
||||||
@@ -161,7 +108,7 @@ class JpsStatisticsReportServiceImpl(
|
|||||||
log.debug("JpsStatisticsReportService: Build started for $moduleName module")
|
log.debug("JpsStatisticsReportService: Build started for $moduleName module")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getMetricReporter(chunk: ModuleChunk): JpsBuilderMetricReporter? {
|
override fun getMetricReporter(chunk: ModuleChunk): JpsBuilderMetricReporter? {
|
||||||
val moduleName = chunk.name
|
val moduleName = chunk.name
|
||||||
return getMetricReporter(moduleName)
|
return getMetricReporter(moduleName)
|
||||||
}
|
}
|
||||||
@@ -176,7 +123,7 @@ class JpsStatisticsReportServiceImpl(
|
|||||||
return metricReporter
|
return metricReporter
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun moduleBuildFinished(chunk: ModuleChunk, context: CompileContext) {
|
override fun moduleBuildFinished(chunk: ModuleChunk, context: CompileContext, exitCode: ExitCode) {
|
||||||
val moduleName = chunk.name
|
val moduleName = chunk.name
|
||||||
val metrics = buildMetrics.remove(moduleName)
|
val metrics = buildMetrics.remove(moduleName)
|
||||||
if (metrics == null) {
|
if (metrics == null) {
|
||||||
@@ -184,7 +131,7 @@ class JpsStatisticsReportServiceImpl(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.debug("JpsStatisticsReportService: Build started for $moduleName module")
|
log.debug("JpsStatisticsReportService: Build started for $moduleName module")
|
||||||
metrics.buildFinish(chunk, context)
|
metrics.buildFinish(chunk, context, exitCode.name)
|
||||||
finishedModuleBuildMetrics.add(metrics)
|
finishedModuleBuildMetrics.add(metrics)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,9 +139,11 @@ class JpsStatisticsReportServiceImpl(
|
|||||||
val compileStatisticsData = finishedModuleBuildMetrics.map { it.flush(context) }
|
val compileStatisticsData = finishedModuleBuildMetrics.map { it.flush(context) }
|
||||||
httpService?.sendData(compileStatisticsData, loggerAdapter)
|
httpService?.sendData(compileStatisticsData, loggerAdapter)
|
||||||
fileReportSettings?.also {
|
fileReportSettings?.also {
|
||||||
FileReportService.reportBuildStatInFile(
|
JpsFileReportService(
|
||||||
it.buildReportDir, context.projectDescriptor.project.name, true, compileStatisticsData,
|
it.buildReportDir, context.projectDescriptor.project.name, true, loggerAdapter
|
||||||
BuildStartParameters(tasks = listOf(jpsBuildTaskName)), emptyList(), loggerAdapter
|
).process(
|
||||||
|
compileStatisticsData,
|
||||||
|
BuildStartParameters(tasks = listOf(jpsBuildTaskName)), emptyList(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -203,6 +152,20 @@ class JpsStatisticsReportServiceImpl(
|
|||||||
return getMetricReporter(chunk)?.measure(metric, action) ?: action.invoke()
|
return getMetricReporter(chunk)?.measure(metric, action) ?: action.invoke()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun reportDirtyFiles(kotlinDirtySourceFilesHolder: KotlinDirtySourceFilesHolder) {
|
||||||
|
getMetricReporter(kotlinDirtySourceFilesHolder.chunk)?.let {
|
||||||
|
it.addChangedFiles(kotlinDirtySourceFilesHolder.allRemovedFilesFiles.map { it.path })
|
||||||
|
it.addChangedFiles(kotlinDirtySourceFilesHolder.allDirtyFiles.map { it.path })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun reportCompilerArguments(chunk: ModuleChunk, kotlinChunk: KotlinChunk) {
|
||||||
|
getMetricReporter(chunk)?.let {
|
||||||
|
it.addCompilerArguments(kotlinChunk.compilerArguments.freeArgs)
|
||||||
|
it.setKotlinLanguageVersion(kotlinChunk.compilerArguments.languageVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun buildStarted(context: CompileContext) {
|
override fun buildStarted(context: CompileContext) {
|
||||||
loggerAdapter.info("Build started for $context with enabled build metric reports.")
|
loggerAdapter.info("Build started for $context with enabled build metric reports.")
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.jps.build.KotlinDirtySourceFilesHolder
|
|||||||
import org.jetbrains.kotlin.jps.build.ModuleBuildTarget
|
import org.jetbrains.kotlin.jps.build.ModuleBuildTarget
|
||||||
import org.jetbrains.kotlin.jps.model.k2MetadataCompilerArguments
|
import org.jetbrains.kotlin.jps.model.k2MetadataCompilerArguments
|
||||||
import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings
|
import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings
|
||||||
|
import org.jetbrains.kotlin.jps.statistic.JpsBuilderMetricReporter
|
||||||
|
|
||||||
private const val COMMON_BUILD_META_INFO_FILE_NAME = "common-build-meta-info.txt"
|
private const val COMMON_BUILD_META_INFO_FILE_NAME = "common-build-meta-info.txt"
|
||||||
|
|
||||||
@@ -47,7 +48,8 @@ class KotlinCommonModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModu
|
|||||||
override fun compileModuleChunk(
|
override fun compileModuleChunk(
|
||||||
commonArguments: CommonCompilerArguments,
|
commonArguments: CommonCompilerArguments,
|
||||||
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
||||||
environment: JpsCompilerEnvironment
|
environment: JpsCompilerEnvironment,
|
||||||
|
buildMetricReporter: JpsBuilderMetricReporter?
|
||||||
): Boolean {
|
): Boolean {
|
||||||
require(chunk.representativeTarget == this)
|
require(chunk.representativeTarget == this)
|
||||||
|
|
||||||
@@ -60,7 +62,8 @@ class KotlinCommonModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModu
|
|||||||
environment,
|
environment,
|
||||||
destination,
|
destination,
|
||||||
dependenciesOutputDirs + libraryFiles,
|
dependenciesOutputDirs + libraryFiles,
|
||||||
sourceFiles // incremental K2MetadataCompiler not supported yet
|
sourceFiles, // incremental K2MetadataCompiler not supported yet
|
||||||
|
buildMetricReporter
|
||||||
)
|
)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.jps.model.k2JsCompilerArguments
|
|||||||
import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings
|
import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings
|
||||||
import org.jetbrains.kotlin.jps.model.productionOutputFilePath
|
import org.jetbrains.kotlin.jps.model.productionOutputFilePath
|
||||||
import org.jetbrains.kotlin.jps.model.testOutputFilePath
|
import org.jetbrains.kotlin.jps.model.testOutputFilePath
|
||||||
|
import org.jetbrains.kotlin.jps.statistic.JpsBuilderMetricReporter
|
||||||
import org.jetbrains.kotlin.utils.JsLibraryUtils
|
import org.jetbrains.kotlin.utils.JsLibraryUtils
|
||||||
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils.JS_EXT
|
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils.JS_EXT
|
||||||
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils.META_JS_SUFFIX
|
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils.META_JS_SUFFIX
|
||||||
@@ -92,7 +93,8 @@ class KotlinJsModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleBu
|
|||||||
override fun compileModuleChunk(
|
override fun compileModuleChunk(
|
||||||
commonArguments: CommonCompilerArguments,
|
commonArguments: CommonCompilerArguments,
|
||||||
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
||||||
environment: JpsCompilerEnvironment
|
environment: JpsCompilerEnvironment,
|
||||||
|
buildMetricReporter: JpsBuilderMetricReporter?
|
||||||
): Boolean {
|
): Boolean {
|
||||||
require(chunk.representativeTarget == this)
|
require(chunk.representativeTarget == this)
|
||||||
|
|
||||||
@@ -116,7 +118,8 @@ class KotlinJsModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleBu
|
|||||||
sourceMapRoots,
|
sourceMapRoots,
|
||||||
libraries,
|
libraries,
|
||||||
friendBuildTargetsMetaFiles,
|
friendBuildTargetsMetaFiles,
|
||||||
outputFile
|
outputFile,
|
||||||
|
buildMetricReporter
|
||||||
)
|
)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache
|
|||||||
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalJvmCache
|
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalJvmCache
|
||||||
import org.jetbrains.kotlin.jps.model.k2JvmCompilerArguments
|
import org.jetbrains.kotlin.jps.model.k2JvmCompilerArguments
|
||||||
import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings
|
import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings
|
||||||
|
import org.jetbrains.kotlin.jps.statistic.JpsBuilderMetricReporter
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||||
import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder
|
import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder
|
||||||
@@ -99,7 +100,8 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB
|
|||||||
override fun compileModuleChunk(
|
override fun compileModuleChunk(
|
||||||
commonArguments: CommonCompilerArguments,
|
commonArguments: CommonCompilerArguments,
|
||||||
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
||||||
environment: JpsCompilerEnvironment
|
environment: JpsCompilerEnvironment,
|
||||||
|
buildMetricReporter: JpsBuilderMetricReporter?
|
||||||
): Boolean {
|
): Boolean {
|
||||||
require(chunk.representativeTarget == this)
|
require(chunk.representativeTarget == this)
|
||||||
|
|
||||||
@@ -144,7 +146,8 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB
|
|||||||
module.k2JvmCompilerArguments,
|
module.k2JvmCompilerArguments,
|
||||||
module.kotlinCompilerSettings,
|
module.kotlinCompilerSettings,
|
||||||
environment,
|
environment,
|
||||||
moduleFile
|
moduleFile,
|
||||||
|
buildMetricReporter
|
||||||
)
|
)
|
||||||
} finally {
|
} finally {
|
||||||
if (System.getProperty(DELETE_MODULE_FILE_PROPERTY) != "false") {
|
if (System.getProperty(DELETE_MODULE_FILE_PROPERTY) != "false") {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.jps.incremental.loadDiff
|
|||||||
import org.jetbrains.kotlin.jps.incremental.localCacheVersionManager
|
import org.jetbrains.kotlin.jps.incremental.localCacheVersionManager
|
||||||
import org.jetbrains.kotlin.jps.model.productionOutputFilePath
|
import org.jetbrains.kotlin.jps.model.productionOutputFilePath
|
||||||
import org.jetbrains.kotlin.jps.model.testOutputFilePath
|
import org.jetbrains.kotlin.jps.model.testOutputFilePath
|
||||||
|
import org.jetbrains.kotlin.jps.statistic.JpsBuilderMetricReporter
|
||||||
import org.jetbrains.kotlin.modules.TargetId
|
import org.jetbrains.kotlin.modules.TargetId
|
||||||
import org.jetbrains.kotlin.progress.CompilationCanceledException
|
import org.jetbrains.kotlin.progress.CompilationCanceledException
|
||||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||||
@@ -202,7 +203,8 @@ abstract class KotlinModuleBuildTarget<BuildMetaInfoType : BuildMetaInfo> intern
|
|||||||
abstract fun compileModuleChunk(
|
abstract fun compileModuleChunk(
|
||||||
commonArguments: CommonCompilerArguments,
|
commonArguments: CommonCompilerArguments,
|
||||||
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
||||||
environment: JpsCompilerEnvironment
|
environment: JpsCompilerEnvironment,
|
||||||
|
buildMetricReporter: JpsBuilderMetricReporter?
|
||||||
): Boolean
|
): Boolean
|
||||||
|
|
||||||
open fun registerOutputItems(outputConsumer: ModuleLevelBuilder.OutputConsumer, outputItems: List<GeneratedFile>) {
|
open fun registerOutputItems(outputConsumer: ModuleLevelBuilder.OutputConsumer, outputItems: List<GeneratedFile>) {
|
||||||
|
|||||||
+3
-1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.jps.build.KotlinCompileContext
|
|||||||
import org.jetbrains.kotlin.jps.build.KotlinDirtySourceFilesHolder
|
import org.jetbrains.kotlin.jps.build.KotlinDirtySourceFilesHolder
|
||||||
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache
|
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache
|
||||||
import org.jetbrains.kotlin.jps.model.platform
|
import org.jetbrains.kotlin.jps.model.platform
|
||||||
|
import org.jetbrains.kotlin.jps.statistic.JpsBuilderMetricReporter
|
||||||
import org.jetbrains.kotlin.platform.idePlatformKind
|
import org.jetbrains.kotlin.platform.idePlatformKind
|
||||||
|
|
||||||
class KotlinUnsupportedModuleBuildTarget(
|
class KotlinUnsupportedModuleBuildTarget(
|
||||||
@@ -40,7 +41,8 @@ class KotlinUnsupportedModuleBuildTarget(
|
|||||||
override fun compileModuleChunk(
|
override fun compileModuleChunk(
|
||||||
commonArguments: CommonCompilerArguments,
|
commonArguments: CommonCompilerArguments,
|
||||||
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
||||||
environment: JpsCompilerEnvironment
|
environment: JpsCompilerEnvironment,
|
||||||
|
buildMetricReporter: JpsBuilderMetricReporter?
|
||||||
): Boolean {
|
): Boolean {
|
||||||
shouldNotBeCalled()
|
shouldNotBeCalled()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="jdk" jdkName="IDEA_JDK" jdkType="JavaSDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="KotlinRuntime" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/kotlinProject.iml" filepath="$PROJECT_DIR$/kotlinProject.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" assert-keyword="true" jdk-15="true" project-jdk-name="IDEA_JDK" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
class Foo()
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun main() {
|
||||||
|
Foo()
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.gradle.plugin.statistics
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.GradleBuildPerformanceMetric
|
||||||
|
import org.jetbrains.kotlin.build.report.metrics.GradleBuildTime
|
||||||
|
import org.jetbrains.kotlin.build.report.statistics.file.FileReportService
|
||||||
|
import org.jetbrains.kotlin.buildtools.api.KotlinLogger
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class GradleFileReportService(
|
||||||
|
buildReportDir: File,
|
||||||
|
projectName: String,
|
||||||
|
printMetrics: Boolean,
|
||||||
|
logger: KotlinLogger,
|
||||||
|
) : FileReportService<GradleBuildTime, GradleBuildPerformanceMetric>(buildReportDir, projectName, printMetrics, logger) {}
|
||||||
+15
-13
@@ -10,12 +10,12 @@ import org.gradle.api.logging.Logging
|
|||||||
import org.gradle.tooling.events.task.TaskFinishEvent
|
import org.gradle.tooling.events.task.TaskFinishEvent
|
||||||
import org.jetbrains.kotlin.build.report.metrics.ValueType
|
import org.jetbrains.kotlin.build.report.metrics.ValueType
|
||||||
import org.jetbrains.kotlin.build.report.statistics.HttpReportService
|
import org.jetbrains.kotlin.build.report.statistics.HttpReportService
|
||||||
import org.jetbrains.kotlin.build.report.statistics.file.FileReportService
|
|
||||||
import org.jetbrains.kotlin.build.report.statistics.formatSize
|
import org.jetbrains.kotlin.build.report.statistics.formatSize
|
||||||
import org.jetbrains.kotlin.build.report.statistics.BuildFinishStatisticsData
|
import org.jetbrains.kotlin.build.report.statistics.BuildFinishStatisticsData
|
||||||
import org.jetbrains.kotlin.build.report.statistics.BuildStartParameters
|
import org.jetbrains.kotlin.build.report.statistics.BuildStartParameters
|
||||||
import org.jetbrains.kotlin.build.report.statistics.StatTag
|
import org.jetbrains.kotlin.build.report.statistics.StatTag
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
|
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.statistics.GradleFileReportService
|
||||||
import org.jetbrains.kotlin.gradle.report.data.BuildExecutionData
|
import org.jetbrains.kotlin.gradle.report.data.BuildExecutionData
|
||||||
import org.jetbrains.kotlin.gradle.report.data.BuildOperationRecord
|
import org.jetbrains.kotlin.gradle.report.data.BuildOperationRecord
|
||||||
import org.jetbrains.kotlin.gradle.report.data.GradleCompileStatisticsData
|
import org.jetbrains.kotlin.gradle.report.data.GradleCompileStatisticsData
|
||||||
@@ -51,7 +51,7 @@ class BuildReportsService {
|
|||||||
fun close(
|
fun close(
|
||||||
buildOperationRecords: Collection<BuildOperationRecord>,
|
buildOperationRecords: Collection<BuildOperationRecord>,
|
||||||
failureMessages: List<String>,
|
failureMessages: List<String>,
|
||||||
parameters: BuildReportParameters
|
parameters: BuildReportParameters,
|
||||||
) {
|
) {
|
||||||
val buildData = BuildExecutionData(
|
val buildData = BuildExecutionData(
|
||||||
startParameters = parameters.startParameters,
|
startParameters = parameters.startParameters,
|
||||||
@@ -65,14 +65,15 @@ class BuildReportsService {
|
|||||||
executorService.submit { reportBuildFinish(parameters) }
|
executorService.submit { reportBuildFinish(parameters) }
|
||||||
}
|
}
|
||||||
reportingSettings.fileReportSettings?.also {
|
reportingSettings.fileReportSettings?.also {
|
||||||
FileReportService.reportBuildStatInFile(
|
GradleFileReportService(
|
||||||
it.buildReportDir,
|
it.buildReportDir,
|
||||||
parameters.projectName,
|
parameters.projectName,
|
||||||
it.includeMetricsInReport,
|
it.includeMetricsInReport,
|
||||||
|
loggerAdapter
|
||||||
|
).process(
|
||||||
transformOperationRecordsToCompileStatisticsData(buildOperationRecords, parameters, onlyKotlinTask = false),
|
transformOperationRecordsToCompileStatisticsData(buildOperationRecords, parameters, onlyKotlinTask = false),
|
||||||
parameters.startParameters,
|
parameters.startParameters,
|
||||||
failureMessages.filter { it.isNotEmpty() },
|
failureMessages.filter { it.isNotEmpty() },
|
||||||
loggerAdapter
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +93,7 @@ class BuildReportsService {
|
|||||||
buildOperationRecords: Collection<BuildOperationRecord>,
|
buildOperationRecords: Collection<BuildOperationRecord>,
|
||||||
parameters: BuildReportParameters,
|
parameters: BuildReportParameters,
|
||||||
onlyKotlinTask: Boolean,
|
onlyKotlinTask: Boolean,
|
||||||
metricsToShow: Set<String>? = null
|
metricsToShow: Set<String>? = null,
|
||||||
) = buildOperationRecords.mapNotNull {
|
) = buildOperationRecords.mapNotNull {
|
||||||
prepareData(
|
prepareData(
|
||||||
taskResult = null,
|
taskResult = null,
|
||||||
@@ -112,7 +113,7 @@ class BuildReportsService {
|
|||||||
|
|
||||||
fun onFinish(
|
fun onFinish(
|
||||||
event: TaskFinishEvent, buildOperation: BuildOperationRecord,
|
event: TaskFinishEvent, buildOperation: BuildOperationRecord,
|
||||||
parameters: BuildReportParameters
|
parameters: BuildReportParameters,
|
||||||
) {
|
) {
|
||||||
addHttpReport(event, buildOperation, parameters)
|
addHttpReport(event, buildOperation, parameters)
|
||||||
}
|
}
|
||||||
@@ -162,7 +163,7 @@ class BuildReportsService {
|
|||||||
private fun addHttpReport(
|
private fun addHttpReport(
|
||||||
event: TaskFinishEvent,
|
event: TaskFinishEvent,
|
||||||
buildOperationRecord: BuildOperationRecord,
|
buildOperationRecord: BuildOperationRecord,
|
||||||
parameters: BuildReportParameters
|
parameters: BuildReportParameters,
|
||||||
) {
|
) {
|
||||||
parameters.httpService?.also { httpService ->
|
parameters.httpService?.also { httpService ->
|
||||||
val data =
|
val data =
|
||||||
@@ -189,7 +190,7 @@ class BuildReportsService {
|
|||||||
event: TaskFinishEvent,
|
event: TaskFinishEvent,
|
||||||
buildOperationRecord: BuildOperationRecord,
|
buildOperationRecord: BuildOperationRecord,
|
||||||
parameters: BuildReportParameters,
|
parameters: BuildReportParameters,
|
||||||
buildScanExtension: BuildScanExtensionHolder
|
buildScanExtension: BuildScanExtensionHolder,
|
||||||
) {
|
) {
|
||||||
val buildScanSettings = parameters.reportingSettings.buildScanReportSettings ?: return
|
val buildScanSettings = parameters.reportingSettings.buildScanReportSettings ?: return
|
||||||
|
|
||||||
@@ -212,7 +213,7 @@ class BuildReportsService {
|
|||||||
internal fun addBuildScanReport(
|
internal fun addBuildScanReport(
|
||||||
buildOperationRecords: Collection<BuildOperationRecord>,
|
buildOperationRecords: Collection<BuildOperationRecord>,
|
||||||
parameters: BuildReportParameters,
|
parameters: BuildReportParameters,
|
||||||
buildScanExtension: BuildScanExtensionHolder
|
buildScanExtension: BuildScanExtensionHolder,
|
||||||
) {
|
) {
|
||||||
val buildScanSettings = parameters.reportingSettings.buildScanReportSettings ?: return
|
val buildScanSettings = parameters.reportingSettings.buildScanReportSettings ?: return
|
||||||
|
|
||||||
@@ -256,14 +257,14 @@ class BuildReportsService {
|
|||||||
private fun addBuildScanValue(
|
private fun addBuildScanValue(
|
||||||
buildScan: BuildScanExtensionHolder,
|
buildScan: BuildScanExtensionHolder,
|
||||||
data: GradleCompileStatisticsData,
|
data: GradleCompileStatisticsData,
|
||||||
customValue: String
|
customValue: String,
|
||||||
) {
|
) {
|
||||||
buildScan.buildScan.value(data.getTaskName(), customValue)
|
buildScan.buildScan.value(data.getTaskName(), customValue)
|
||||||
customValues++
|
customValues++
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reportTryNextToConsole(
|
private fun reportTryNextToConsole(
|
||||||
data: BuildExecutionData
|
data: BuildExecutionData,
|
||||||
) {
|
) {
|
||||||
val tasksData = data.buildOperationRecord
|
val tasksData = data.buildOperationRecord
|
||||||
.filterIsInstance<TaskRecord>()
|
.filterIsInstance<TaskRecord>()
|
||||||
@@ -309,7 +310,8 @@ class BuildReportsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val timeData =
|
val timeData =
|
||||||
data.getBuildTimesMetrics().map { (key, value) -> "${key.getReadableString()}: ${value}ms" } //sometimes it is better to have separate variable to be able debug
|
data.getBuildTimesMetrics()
|
||||||
|
.map { (key, value) -> "${key.getReadableString()}: ${value}ms" } //sometimes it is better to have separate variable to be able debug
|
||||||
val perfData = data.getPerformanceMetrics().map { (key, value) ->
|
val perfData = data.getPerformanceMetrics().map { (key, value) ->
|
||||||
when (key.getType()) {
|
when (key.getType()) {
|
||||||
ValueType.BYTES -> "${key.getReadableString()}: ${formatSize(value)}"
|
ValueType.BYTES -> "${key.getReadableString()}: ${formatSize(value)}"
|
||||||
@@ -419,5 +421,5 @@ data class BuildReportParameters(
|
|||||||
val label: String?,
|
val label: String?,
|
||||||
val projectName: String,
|
val projectName: String,
|
||||||
val kotlinVersion: String,
|
val kotlinVersion: String,
|
||||||
val additionalTags: Set<StatTag>
|
val additionalTags: Set<StatTag>,
|
||||||
)
|
)
|
||||||
Reference in New Issue
Block a user