diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt index 9bce68f6ed9..2c07c9d2a25 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt @@ -150,9 +150,13 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration return resolvedLibraries.filterRoots { (!it.isDefault && !this.purgeUserLibs) || it.isNeededForLink }.getFullList(TopologicalLibraryOrder) as List } + val shouldCoverSources = configuration.getBoolean(KonanConfigKeys.COVERAGE) + val shouldCoverLibraries = !configuration.getList(KonanConfigKeys.LIBRARIES_TO_COVER).isNullOrEmpty() + internal val runtimeNativeLibraries: List = mutableListOf().apply { add(if (debug) "debug.bc" else "release.bc") add(if (memoryModel == MemoryModel.STRICT) "strict.bc" else "relaxed.bc") + if (shouldCoverLibraries || shouldCoverSources) add("profileRuntime.bc") }.map { File(distribution.defaultNatives(target)).child(it).absolutePath } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageManager.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageManager.kt index d215ce6b966..4ad86aa63f9 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageManager.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageManager.kt @@ -21,8 +21,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module */ internal class CoverageManager(val context: Context) { - private val shouldCoverProgram: Boolean = - context.config.configuration.getBoolean(KonanConfigKeys.COVERAGE) + private val shouldCoverSources: Boolean = + context.config.shouldCoverSources private val librariesToCover: Set = context.config.coveredLibraries.map { it.libraryName }.toSet() @@ -39,7 +39,7 @@ internal class CoverageManager(val context: Context) { ?: defaultOutputFilePath val enabled: Boolean = - shouldCoverProgram || librariesToCover.isNotEmpty() + shouldCoverSources || librariesToCover.isNotEmpty() init { if (enabled && !checkRestrictions()) { @@ -60,10 +60,10 @@ internal class CoverageManager(val context: Context) { filesRegionsInfo.flatMap { it.functions }.firstOrNull { it.function == irFunction } private val coveredModules: Set by lazy { - val coveredUserCode = if (shouldCoverProgram) setOf(context.moduleDescriptor) else emptySet() + val coveredUserCode = if (shouldCoverSources) setOf(context.moduleDescriptor) else emptySet() val coveredLibs = context.irModules.filter { it.key in librariesToCover }.values .map { it.descriptor }.toSet() - val coveredIncludedLibs = if (shouldCoverProgram) context.getIncludedLibraryDescriptors().toSet() else emptySet() + val coveredIncludedLibs = if (shouldCoverSources) context.getIncludedLibraryDescriptors().toSet() else emptySet() coveredLibs + coveredUserCode + coveredIncludedLibs } diff --git a/runtime/build.gradle b/runtime/build.gradle index 1a8d6b27528..be8a8ef5b3a 100644 --- a/runtime/build.gradle +++ b/runtime/build.gradle @@ -21,6 +21,7 @@ targetList.each { targetName -> dependsOn "${targetName}Release" dependsOn "${targetName}Strict" dependsOn "${targetName}Relaxed" + dependsOn "${targetName}ProfileRuntime" target targetName includeRuntime(delegate) linkerArgs project.file("../common/build/$targetName/hash.bc").path @@ -60,6 +61,12 @@ targetList.each { targetName -> target targetName includeRuntime(delegate) } + + task ("${targetName}ProfileRuntime", type: CompileCppToBitcode) { + name "profileRuntime" + srcRoot file('src/profile_runtime') + target targetName + } } task hostRuntime(dependsOn: "${hostName}Runtime") diff --git a/runtime/src/profile_runtime/cpp/ProfileRuntime.cpp b/runtime/src/profile_runtime/cpp/ProfileRuntime.cpp new file mode 100644 index 00000000000..46e9c43b45b --- /dev/null +++ b/runtime/src/profile_runtime/cpp/ProfileRuntime.cpp @@ -0,0 +1,28 @@ +// Define symbols that are required for code coverage but missing in compiler-RT for MinGW.
 +// See https://reviews.llvm.org/D58106/ for details. +#ifdef KONAN_WINDOWS + +#include + +extern "C" { + +__attribute__((used)) +int lprofGetHostName(char *hostName, int length) { + const int maxHostNameLength = 128; + WCHAR buffer[maxHostNameLength]; + DWORD bufferSize = sizeof(buffer); + COMPUTER_NAME_FORMAT nameType = ComputerNameDnsFullyQualified; + if (!GetComputerNameExW(nameType, buffer, &bufferSize)) { + return -1; + } + int bytesWritten = WideCharToMultiByte(CP_UTF8, 0, buffer, -1, hostName, length, nullptr, nullptr); + if (bytesWritten == 0) { + return -1; + } else { + return 0; + } +} + +} + +#endif