[K/N] Make runtime logs enablement compile-time evaluatable

This commit is contained in:
Aleksei.Glushko
2023-10-16 20:41:10 +02:00
committed by Space Team
parent beeb016a9f
commit 2b2b8dd090
15 changed files with 321 additions and 308 deletions
@@ -118,7 +118,40 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
configuration.report(CompilerMessageSeverity.STRONG_WARNING, "Legacy exception handling in workers is deprecated")
}
} ?: WorkerExceptionHandling.USE_HOOK
val runtimeLogs: String? get() = configuration.get(KonanConfigKeys.RUNTIME_LOGS)
val runtimeLogsEnabled: Boolean by lazy {
configuration.get(KonanConfigKeys.RUNTIME_LOGS) != null
}
val runtimeLogs: Map<LoggingTag, LoggingLevel> by lazy {
val default = LoggingTag.entries.associateWith { LoggingLevel.None }
val cfgString = configuration.get(KonanConfigKeys.RUNTIME_LOGS) ?: return@lazy default
fun <T> error(message: String): T? {
configuration.report(CompilerMessageSeverity.STRONG_WARNING, "$message. No logging will be performed.")
return null
}
fun parseSingleTagLevel(tagLevel: String): Pair<LoggingTag, LoggingLevel>? {
val parts = tagLevel.split("=")
val tagStr = parts[0]
val tag = tagStr.let {
LoggingTag.parse(it) ?: error("Failed to parse log tag at \"$tagStr\"")
}
val levelStr = parts.getOrNull(1) ?: error("Failed to parse log tag-level pair at \"$tagLevel\"")
val level = parts.getOrNull(1)?.let {
LoggingLevel.parse(it) ?: error("Failed to parse log level at \"$levelStr\"")
}
if (level == LoggingLevel.None) return error("Invalid log level: \"$levelStr\"")
return tag?.let { t -> level?.let { l -> Pair(t, l) } }
}
val configured = cfgString.split(",").map { parseSingleTagLevel(it) ?: return@lazy default }
default + configured
}
val suspendFunctionsFromAnyThreadFromObjC: Boolean by lazy { configuration.get(BinaryOptions.objcExportSuspendFunctionLaunchThreadRestriction) == ObjCExportSuspendFunctionLaunchThreadRestriction.NONE }
val freezing: Freezing get() = configuration.get(BinaryOptions.freezing)?.also {
if (it != Freezing.Disabled) {
@@ -474,7 +507,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
internal val ignoreCacheReason = when {
optimizationsEnabled -> "for optimized compilation"
sanitizer != null -> "with sanitizers enabled"
runtimeLogs != null -> "with runtime logs"
runtimeLogsEnabled -> "with runtime logs"
else -> null
}
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
package org.jetbrains.kotlin.backend.konan
// Must match `Level` in Logging.hpp
enum class LoggingLevel(val ord: Int) {
None(0), // marks disable logs, should not be used for other purposes
Error(1),
Warning(2),
Info(3),
Debug(4);
companion object {
fun parse(str: String) = LoggingLevel.entries.firstOrNull {
it.name.equals(str, ignoreCase = true)
}
}
}
// Must match `Tag` in Logging.hpp
enum class LoggingTag(val ord: Int) {
Logging(0),
RT(1),
GC(2),
MM(3),
TLS(4),
Pause(5),
Alloc(6),
Balancing(7);
companion object {
fun parse(str: String) = entries.firstOrNull {
it.name.equals(str, ignoreCase = true)
}
}
}
@@ -3039,9 +3039,10 @@ internal fun NativeGenerationState.generateRuntimeConstantsModule() : LLVMModule
setRuntimeConstGlobal("Kotlin_runtimeAssertsMode", llvm.constInt32(config.runtimeAssertsMode.value))
setRuntimeConstGlobal("Kotlin_disableMmap", llvm.constInt32(if (config.disableMmap) 1 else 0))
setRuntimeConstGlobal("Kotlin_disableAllocatorOverheadEstimate", llvm.constInt32(if (config.disableAllocatorOverheadEstimate) 1 else 0))
val runtimeLogs = config.runtimeLogs?.let {
static.cStringLiteral(it)
} ?: NullPointer(llvm.int8Type)
val runtimeLogs = ConstArray(llvm.int32Type, LoggingTag.entries.sortedBy { it.ord }.map {
config.runtimeLogs[it]!!.ord.let { llvm.constInt32(it) }
})
setRuntimeConstGlobal("Kotlin_runtimeLogs", runtimeLogs)
setRuntimeConstGlobal("Kotlin_freezingEnabled", llvm.constInt32(if (config.freezing.enableFreezeAtRuntime) 1 else 0))
setRuntimeConstGlobal("Kotlin_freezingChecksEnabled", llvm.constInt32(if (config.freezing.enableFreezeChecks) 1 else 0))
@@ -831,6 +831,31 @@ standaloneTest("cleaner_in_tls_worker") {
flags = ['-opt-in=kotlin.native.internal.InternalForKotlinNative']
}
standaloneTest('logging') {
outputChecker = { out ->
out.toLowerCase().contains("[logging]") && // loging reports configured log levels on info level
out.toLowerCase().contains("logging = debug") &&
out.toLowerCase().contains("gc = info") &&
out.toLowerCase().contains("mm = warning") &&
out.toLowerCase().contains("tls = error") &&
out.toLowerCase().contains("[gc]") // gc reports initialization on info level
}
source = "runtime/basic/logging.kt"
flags = ['-Xruntime-logs=gc=info,mm=warning,tls=error,logging=debug']
}
standaloneTest('logging_invalid') {
outputChecker = { it.isEmpty() }
source = "runtime/basic/logging.kt"
flags = ['-Xruntime-logs=invalid=unknown,logging=debug']
}
standaloneTest('logging_override') {
outputChecker = { it.isEmpty() }
source = "runtime/basic/logging.kt"
flags = ['-Xruntime-logs=logging=info,logging=debug,logging=none']
}
standaloneTest("worker_bound_reference0") {
source = "runtime/concurrent/worker_bound_reference0.kt"
flags = ['-tr']
@@ -0,0 +1,6 @@
/*
* 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.
*/
fun main() {}