Enabling parallel builds in JPS without daemon, enabling application environment disposing in tests, introducing keepalive property constant

This commit is contained in:
Ilya Chernikov
2015-10-30 15:58:28 +01:00
parent 63e1fa4cc0
commit 10036d7ef3
5 changed files with 38 additions and 10 deletions
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.cli.common
public val KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY = "kotlin.environment.keepalive"
@@ -54,6 +54,7 @@ import org.jetbrains.kotlin.asJava.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.CliModuleVisibilityManagerImpl import org.jetbrains.kotlin.cli.common.CliModuleVisibilityManagerImpl
import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
@@ -237,9 +238,12 @@ public class KotlinCoreEnvironment private constructor(
public fun createForProduction( public fun createForProduction(
parentDisposable: Disposable, configuration: CompilerConfiguration, configFilePaths: List<String> parentDisposable: Disposable, configuration: CompilerConfiguration, configFilePaths: List<String>
): KotlinCoreEnvironment { ): KotlinCoreEnvironment {
// JPS may run many instances of the compiler in parallel (there's an option for compiling independent modules in parallel in IntelliJ) val appEnv = getOrCreateApplicationEnvironmentForProduction(configuration, configFilePaths)
// All projects share the same ApplicationEnvironment, and when the last project is disposed, the ApplicationEnvironment is disposed as well // Disposing of the environment is unsafe in production then parallel builds are enabled, but turning it off universally
if (System.getProperty("kotlin.environment.keepalive") == null) { // breaks a lot of tests, therefore it is disabled for production and enabled for tests
if (System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY) == null || appEnv.application.isUnitTestMode) {
// JPS may run many instances of the compiler in parallel (there's an option for compiling independent modules in parallel in IntelliJ)
// All projects share the same ApplicationEnvironment, and when the last project is disposed, the ApplicationEnvironment is disposed as well
Disposer.register(parentDisposable, object : Disposable { Disposer.register(parentDisposable, object : Disposable {
override fun dispose() { override fun dispose() {
synchronized (APPLICATION_LOCK) { synchronized (APPLICATION_LOCK) {
@@ -250,7 +254,7 @@ public class KotlinCoreEnvironment private constructor(
} }
}) })
} }
val environment = KotlinCoreEnvironment(parentDisposable, getOrCreateApplicationEnvironmentForProduction(configuration, configFilePaths), configuration) val environment = KotlinCoreEnvironment(parentDisposable, appEnv, configuration)
synchronized (APPLICATION_LOCK) { synchronized (APPLICATION_LOCK) {
ourProjectCount++ ourProjectCount++
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.rmi package org.jetbrains.kotlin.rmi
import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY
import java.io.File import java.io.File
import java.io.Serializable import java.io.Serializable
import java.lang.management.ManagementFactory import java.lang.management.ManagementFactory
@@ -139,14 +140,14 @@ fun Iterable<String>.filterExtractProps(propMappers: List<PropMapper<*, *, *>>,
when { when {
propMapper != null -> { propMapper != null -> {
val optionLength = prefix.length() + matchingOption!!.length() val optionLength = prefix.length + matchingOption!!.length
when { when {
propMapper is BoolPropMapper<*, *> -> { propMapper is BoolPropMapper<*, *> -> {
if (param.length() > optionLength) if (param.length > optionLength)
throw IllegalArgumentException("Invalid switch option '$param', expecting $prefix$matchingOption without arguments") throw IllegalArgumentException("Invalid switch option '$param', expecting $prefix$matchingOption without arguments")
propMapper.apply("") propMapper.apply("")
} }
param.length() > optionLength -> param.length > optionLength ->
if (param[optionLength] != '=') { if (param[optionLength] != '=') {
if (propMapper.mergeDelimiter == null) if (propMapper.mergeDelimiter == null)
throw IllegalArgumentException("Invalid option syntax '$param', expecting $prefix$matchingOption[= ]<arg>") throw IllegalArgumentException("Invalid option syntax '$param', expecting $prefix$matchingOption[= ]<arg>")
@@ -265,7 +266,7 @@ public fun configureDaemonJVMOptions(opts: DaemonJVMOptions, inheritMemoryLimits
System.getProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY)?.let { opts.jvmParams.add("D$COMPILE_DAEMON_LOG_PATH_PROPERTY=\"$it\"" ) } System.getProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY)?.let { opts.jvmParams.add("D$COMPILE_DAEMON_LOG_PATH_PROPERTY=\"$it\"" ) }
opts.jvmParams.addAll(additionalParams) opts.jvmParams.addAll(additionalParams)
System.getProperty("kotlin.environment.keepalive")?.let { opts.jvmParams.add("Dkotlin.environment.keepalive=true") } System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY)?.let { opts.jvmParams.add("D$KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY") }
return opts return opts
} }
@@ -70,7 +70,7 @@ public class CompilerRunnerUtil {
} }
@Nullable @Nullable
public synchronized static Object invokeExecMethod( public static Object invokeExecMethod(
@NotNull String compilerClassName, @NotNull String compilerClassName,
@NotNull String[] arguments, @NotNull String[] arguments,
@NotNull CompilerEnvironment environment, @NotNull CompilerEnvironment environment,
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.compilerRunner
import com.intellij.util.xmlb.XmlSerializerUtil import com.intellij.util.xmlb.XmlSerializerUtil
import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
@@ -111,6 +112,9 @@ public object KotlinCompilerRunner {
val stream = ByteArrayOutputStream() val stream = ByteArrayOutputStream()
val out = PrintStream(stream) val out = PrintStream(stream)
if (System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY) == null)
System.setProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY, "")
val rc = CompilerRunnerUtil.invokeExecMethod(compilerClassName, argsArray, environment, messageCollector, out) val rc = CompilerRunnerUtil.invokeExecMethod(compilerClassName, argsArray, environment, messageCollector, out)
// exec() returns an ExitCode object, class of which is loaded with a different class loader, // exec() returns an ExitCode object, class of which is loaded with a different class loader,
@@ -139,7 +143,7 @@ public object KotlinCompilerRunner {
// the property should be set by default for daemon builds to avoid parallel building problems // the property should be set by default for daemon builds to avoid parallel building problems
// but it cannot be currently set by default globally, because it seems breaks many tests // but it cannot be currently set by default globally, because it seems breaks many tests
// TODO: find out how to get rid of the property and make it the default behavior // TODO: find out how to get rid of the property and make it the default behavior
daemonJVMOptions.jvmParams.add("Dkotlin.environment.keepalive") daemonJVMOptions.jvmParams.add("D$KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY")
val daemonReportMessages = ArrayList<DaemonReportMessage>() val daemonReportMessages = ArrayList<DaemonReportMessage>()