diff --git a/build.xml b/build.xml
index 34ade247460..ae08d9d5fb4 100644
--- a/build.xml
+++ b/build.xml
@@ -202,8 +202,8 @@
-
-
+
+
diff --git a/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/KotlinCompilerClient.kt b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/KotlinCompilerClient.kt
index cdcfe11ff62..0d0335eb4a6 100644
--- a/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/KotlinCompilerClient.kt
+++ b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/KotlinCompilerClient.kt
@@ -42,7 +42,7 @@ public class KotlinCompilerClient {
companion object {
- val DAEMON_STARTUP_TIMEOUT_MS = 10000L
+ val DAEMON_DEFAULT_STARTUP_TIMEOUT_MS = 10000L
private fun connectToService(compilerId: CompilerId, daemonOptions: DaemonOptions, errStream: PrintStream): CompileService? {
@@ -103,16 +103,25 @@ public class KotlinCompilerClient {
try {
// trying to wait for process
if (daemonOptions.startEcho.isNotEmpty()) {
+ val daemonStartupTimeout = System.getProperty(COMPILE_DAEMON_STARTUP_TIMEOUT_PROPERTY)?.let {
+ try {
+ it.toLong()
+ }
+ catch (e: Exception) {
+ errStream.println("[daemon client] unable to interpret $COMPILE_DAEMON_STARTUP_TIMEOUT_PROPERTY property ('$it'); using default timeout $DAEMON_DEFAULT_STARTUP_TIMEOUT_MS ms")
+ null
+ }
+ } ?: DAEMON_DEFAULT_STARTUP_TIMEOUT_MS
errStream.println("[daemon client] waiting for daemon to respond")
- val succeeded = isEchoRead.tryAcquire(DAEMON_STARTUP_TIMEOUT_MS, TimeUnit.MILLISECONDS)
+ val succeeded = isEchoRead.tryAcquire(daemonStartupTimeout, TimeUnit.MILLISECONDS)
if (!daemon.isAlive())
throw Exception("Daemon terminated unexpectedly")
if (!succeeded)
- throw Exception("Unable to get response from daemon in $DAEMON_STARTUP_TIMEOUT_MS ms")
+ throw Exception("Unable to get response from daemon in $daemonStartupTimeout ms")
}
else
// without startEcho defined waiting for max timeout
- Thread.sleep(DAEMON_STARTUP_TIMEOUT_MS)
+ Thread.sleep(DAEMON_DEFAULT_STARTUP_TIMEOUT_MS)
}
finally {
// assuming that all important output is already done, the rest should be routed to the log by the daemon itself
@@ -207,7 +216,7 @@ public class KotlinCompilerClient {
if (!clientOptions.stop) {
if (compilerId.compilerClasspath.none()) {
// attempt to find compiler to use
- println("compiler wasn't explicitly specified, attempt to find appropriate jar")
+ System.err.println("compiler wasn't explicitly specified, attempt to find appropriate jar")
System.getProperty("java.class.path")
?.split(File.pathSeparator)
?.map { File(it).parent }
@@ -231,7 +240,7 @@ public class KotlinCompilerClient {
val daemon = connectToCompileService(compilerId, daemonLaunchingOptions, daemonOptions, System.out, autostart = !clientOptions.stop, checkId = !clientOptions.stop)
if (daemon == null) {
- if (clientOptions.stop) println("No daemon found to shut down")
+ if (clientOptions.stop) System.err.println("No daemon found to shut down")
else throw Exception("Unable to connect to daemon")
}
else when {
diff --git a/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/DaemonParams.kt b/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/DaemonParams.kt
index eacf096d24b..acb9d55b515 100644
--- a/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/DaemonParams.kt
+++ b/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/DaemonParams.kt
@@ -31,6 +31,7 @@ public val COMPILE_DAEMON_DEFAULT_PORT: Int = 17031
public val COMPILE_DAEMON_ENABLED_PROPERTY: String ="kotlin.daemon.enabled"
public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String ="kotlin.daemon.jvm.options"
public val COMPILE_DAEMON_OPTIONS_PROPERTY: String ="kotlin.daemon.options"
+public val COMPILE_DAEMON_STARTUP_TIMEOUT_PROPERTY: String ="kotlin.daemon.startup.timeout"
public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String ="--daemon-"
public val COMPILE_DAEMON_TIMEOUT_INFINITE_S: Int = 0
public val COMPILE_DAEMON_MEMORY_THRESHOLD_INFINITE: Long = 0L
@@ -66,11 +67,11 @@ class StringPropMapper>(dest: C,
fromString = fromString, toString = toString, skipIf = skipIf, mergeDelimiter = mergeDelimiter)
class BoolPropMapper>(dest: C, prop: P, names: List = listOf())
- : PropMapper(dest = dest, prop = prop, names = if (names.any()) names else listOf(prop.name),
+ : PropMapper(dest = dest, prop = prop, names = if (names.any()) names else listOf(prop.name),
fromString = { true }, toString = { null }, skipIf = { !prop.get(dest) })
-class RestPropMapper>>(dest: C, prop: P)
- : PropMapper, P>(dest = dest, prop = prop, toString = { null }, fromString = { arrayListOf() })
+class RestPropMapper>>(dest: C, prop: P)
+ : PropMapper, P>(dest = dest, prop = prop, toString = { null }, fromString = { arrayListOf() })
{
override fun toArgs(prefix: String): List = prop.get(dest).map { prefix + it }
override fun apply(s: String) = add(s)
@@ -248,7 +249,10 @@ public fun configureDaemonLaunchingOptions(opts: DaemonJVMOptions, inheritMemory
ManagementFactory.getRuntimeMXBean().inputArguments.filterExtractProps(opts.mappers, "-")
System.getProperty(COMPILE_DAEMON_JVM_OPTIONS_PROPERTY)?.let {
- opts.jvmParams.addAll(it.trim('"', '\'').split(",").filterExtractProps(opts.mappers, "-", opts.restMapper))
+ opts.jvmParams.addAll( it.trim('"', '\'')
+ .split("(?) {
+ log.info("Kotlin compiler daemon version " + (loadVersionFromResource() ?: ""))
+ log.info("daemon JVM args: " + ManagementFactory.getRuntimeMXBean().inputArguments.joinToString(" "))
+ log.info("daemon args: " + args.joinToString(" "))
+
val compilerId = CompilerId()
val daemonOptions = DaemonOptions()
val filteredArgs = args.asIterable().filterExtractProps(compilerId, daemonOptions, prefix = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX)
diff --git a/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt
index 7b40d0efbb9..dcd7c488c14 100644
--- a/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt
+++ b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt
@@ -26,15 +26,11 @@ import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.rmi.*
import org.jetbrains.kotlin.rmi.service.RemoteIncrementalCacheClient
import org.jetbrains.kotlin.rmi.service.RemoteOutputStreamClient
-import java.io.IOException
import java.io.PrintStream
-import java.lang.management.ManagementFactory
-import java.net.URLClassLoader
import java.rmi.registry.Registry
import java.rmi.server.UnicastRemoteObject
import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.ReentrantReadWriteLock
-import java.util.jar.Manifest
import java.util.logging.Logger
import kotlin.concurrent.read
import kotlin.concurrent.write
@@ -104,43 +100,19 @@ class CompileServiceImpl>(
return (rt.totalMemory() - rt.freeMemory())
}
- fun usedMemoryMX(): Long {
- System.gc()
- val memoryMXBean= ManagementFactory.getMemoryMXBean()
- val memHeap=memoryMXBean.getHeapMemoryUsage()
- return memHeap.used
- }
-
- // TODO: consider using version as a part of compiler ID or drop this function
- private fun loadKotlinVersionFromResource(): String {
- (javaClass.classLoader as? URLClassLoader)
- ?.findResource("META-INF/MANIFEST.MF")
- ?.let {
- try {
- return Manifest(it.openStream()).mainAttributes.getValue("Implementation-Version") ?: ""
- }
- catch (e: IOException) {}
- }
- return ""
- }
-
-
fun checkedCompile(args: Array, body: () -> R): R {
try {
if (args.none())
throw IllegalArgumentException("Error: empty arguments list.")
log.info("Starting compilation with args: " + args.joinToString(" "))
- val startMemMX = usedMemoryMX() / 1024
val startMem = usedMemory() / 1024
val startTime = System.nanoTime()
val res = body()
val endTime = System.nanoTime()
val endMem = usedMemory() / 1024
- val endMemMX = usedMemoryMX() / 1024
log.info("Done with result " + res.toString())
log.info("Elapsed time: " + TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + " ms")
log.info("Used memory: $endMem kb (${"%+d".format(endMem - startMem)} kb)")
- log.info("Used memory (from MemoryMXBean): $endMemMX kb (${"%+d".format(endMemMX - startMemMX)} kb)")
return res
}
catch (e: Exception) {