[K/N] Disable cache on some non-default configurations

There are some compiler keys that affect code-generation or set of
linked runtime libraries. If caching is enabled, this would be handled
incorrectly, as cached version can be built with other combination of
this keys.

For now, we just disable cache for all non-default configurations.
This commit adds more correct definition of this non-default.

^KT-52613
This commit is contained in:
Pavel Kunyavskiy
2022-06-03 14:09:10 +02:00
committed by Space
parent 5abbb8666d
commit 9e9c9530e7
3 changed files with 57 additions and 48 deletions
@@ -16,9 +16,7 @@ import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
class CacheSupport( class CacheSupport(
private val configuration: CompilerConfiguration, private val configuration: CompilerConfiguration,
resolvedLibraries: KotlinLibraryResolveResult, resolvedLibraries: KotlinLibraryResolveResult,
optimizationsEnabled: Boolean, ignoreCacheReason: String?,
memoryModel: MemoryModel,
propertyLazyInitialization: Boolean,
target: KonanTarget, target: KonanTarget,
produce: CompilerOutputKind produce: CompilerOutputKind
) { ) {
@@ -55,19 +53,11 @@ class CacheSupport(
val hasCachedLibs = explicitCacheFiles.isNotEmpty() || implicitCacheDirectories.isNotEmpty() val hasCachedLibs = explicitCacheFiles.isNotEmpty() || implicitCacheDirectories.isNotEmpty()
val ignoreReason = when { if (ignoreCacheReason != null && hasCachedLibs) {
optimizationsEnabled -> "for optimized compilation" configuration.report(CompilerMessageSeverity.WARNING, "Cached libraries will not be used $ignoreCacheReason")
memoryModel != MemoryModel.EXPERIMENTAL -> "with strict memory model"
!propertyLazyInitialization -> "without lazy top levels initialization"
configuration.get(BinaryOptions.stripDebugInfoFromNativeLibs) == false -> "with native libs debug info"
else -> null
} }
if (ignoreReason != null && hasCachedLibs) { val ignoreCachedLibraries = ignoreCacheReason != null
configuration.report(CompilerMessageSeverity.WARNING, "Cached libraries will not be used $ignoreReason")
}
val ignoreCachedLibraries = ignoreReason != null
CachedLibraries( CachedLibraries(
target = target, target = target,
allLibraries = allLibraries, allLibraries = allLibraries,
@@ -454,8 +454,7 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
fun shouldContainDebugInfo() = config.debug fun shouldContainDebugInfo() = config.debug
fun shouldContainLocationDebugInfo() = shouldContainDebugInfo() || config.lightDebug fun shouldContainLocationDebugInfo() = shouldContainDebugInfo() || config.lightDebug
fun shouldContainAnyDebugInfo() = shouldContainDebugInfo() || shouldContainLocationDebugInfo() fun shouldContainAnyDebugInfo() = shouldContainDebugInfo() || shouldContainLocationDebugInfo()
fun shouldUseDebugInfoFromNativeLibs() = shouldContainAnyDebugInfo() && fun shouldUseDebugInfoFromNativeLibs() = shouldContainAnyDebugInfo() && config.useDebugInfoInNativeLibs
config.configuration.get(BinaryOptions.stripDebugInfoFromNativeLibs) == false
fun shouldOptimize() = config.optimizationsEnabled fun shouldOptimize() = config.optimizationsEnabled
fun ghaEnabled() = ::globalHierarchyAnalysisResult.isInitialized fun ghaEnabled() = ::globalHierarchyAnalysisResult.isInitialized
@@ -61,6 +61,13 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
val generateDebugTrampoline = debug && configuration.get(KonanConfigKeys.GENERATE_DEBUG_TRAMPOLINE) ?: false val generateDebugTrampoline = debug && configuration.get(KonanConfigKeys.GENERATE_DEBUG_TRAMPOLINE) ?: false
val optimizationsEnabled = configuration.getBoolean(KonanConfigKeys.OPTIMIZATION) val optimizationsEnabled = configuration.getBoolean(KonanConfigKeys.OPTIMIZATION)
private val defaultMemoryModel get() =
if (target.supportsThreads()) {
MemoryModel.EXPERIMENTAL
} else {
MemoryModel.STRICT
}
val memoryModel: MemoryModel by lazy { val memoryModel: MemoryModel by lazy {
when (configuration.get(BinaryOptions.memoryModel)) { when (configuration.get(BinaryOptions.memoryModel)) {
MemoryModel.STRICT -> MemoryModel.STRICT MemoryModel.STRICT -> MemoryModel.STRICT
@@ -75,30 +82,26 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
configuration.report(CompilerMessageSeverity.STRONG_WARNING, configuration.report(CompilerMessageSeverity.STRONG_WARNING,
"Experimental memory model requires threads, which are not supported on target ${target.name}. Used strict memory model.") "Experimental memory model requires threads, which are not supported on target ${target.name}. Used strict memory model.")
MemoryModel.STRICT MemoryModel.STRICT
} else if (destroyRuntimeMode == DestroyRuntimeMode.LEGACY) {
configuration.report(CompilerMessageSeverity.STRONG_WARNING,
"Experimental memory model is incompatible with 'legacy' destroy runtime mode. Used strict memory model.")
MemoryModel.STRICT
} else { } else {
MemoryModel.EXPERIMENTAL MemoryModel.EXPERIMENTAL
} }
} }
null -> { null -> defaultMemoryModel
if (target.supportsThreads() && destroyRuntimeMode != DestroyRuntimeMode.LEGACY) { }.also {
MemoryModel.EXPERIMENTAL if (it == MemoryModel.EXPERIMENTAL && destroyRuntimeMode == DestroyRuntimeMode.LEGACY) {
} else { configuration.report(CompilerMessageSeverity.ERROR,
MemoryModel.STRICT "Experimental memory model is incompatible with 'legacy' destroy runtime mode.")
}
} }
} }
} }
val destroyRuntimeMode: DestroyRuntimeMode get() = configuration.get(KonanConfigKeys.DESTROY_RUNTIME_MODE)!! val destroyRuntimeMode: DestroyRuntimeMode get() = configuration.get(KonanConfigKeys.DESTROY_RUNTIME_MODE)!!
private val defaultGC get() = if (target.supportsThreads()) GC.CONCURRENT_MARK_AND_SWEEP else GC.SAME_THREAD_MARK_AND_SWEEP
val gc: GC by lazy { val gc: GC by lazy {
val configGc = configuration.get(KonanConfigKeys.GARBAGE_COLLECTOR) val configGc = configuration.get(KonanConfigKeys.GARBAGE_COLLECTOR)
val (gcFallbackReason, realGc) = when { val (gcFallbackReason, realGc) = when {
configGc == GC.CONCURRENT_MARK_AND_SWEEP && !target.supportsThreads() -> configGc == GC.CONCURRENT_MARK_AND_SWEEP && !target.supportsThreads() ->
"Concurrent mark and sweep gc is not supported for this target. Fallback to Same thread mark and sweep is done" to GC.SAME_THREAD_MARK_AND_SWEEP "Concurrent mark and sweep gc is not supported for this target. Fallback to Same thread mark and sweep is done" to GC.SAME_THREAD_MARK_AND_SWEEP
configGc == null -> null to GC.CONCURRENT_MARK_AND_SWEEP configGc == null -> null to defaultGC
else -> null to configGc else -> null to configGc
} }
if (gcFallbackReason != null) { if (gcFallbackReason != null) {
@@ -113,13 +116,14 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
} }
val runtimeLogs: String? get() = configuration.get(KonanConfigKeys.RUNTIME_LOGS) val runtimeLogs: String? get() = configuration.get(KonanConfigKeys.RUNTIME_LOGS)
val suspendFunctionsFromAnyThreadFromObjC: Boolean by lazy { configuration.get(BinaryOptions.objcExportSuspendFunctionLaunchThreadRestriction) == ObjCExportSuspendFunctionLaunchThreadRestriction.NONE } val suspendFunctionsFromAnyThreadFromObjC: Boolean by lazy { configuration.get(BinaryOptions.objcExportSuspendFunctionLaunchThreadRestriction) == ObjCExportSuspendFunctionLaunchThreadRestriction.NONE }
private val defaultFreezing get() = when (memoryModel) {
MemoryModel.EXPERIMENTAL -> Freezing.Disabled
else -> Freezing.Full
}
val freezing: Freezing by lazy { val freezing: Freezing by lazy {
val freezingMode = configuration.get(BinaryOptions.freezing) val freezingMode = configuration.get(BinaryOptions.freezing)
when { when {
freezingMode == null -> when (memoryModel) { freezingMode == null -> defaultFreezing
MemoryModel.EXPERIMENTAL -> Freezing.Disabled
else -> Freezing.Full
}
memoryModel != MemoryModel.EXPERIMENTAL && freezingMode != Freezing.Full -> { memoryModel != MemoryModel.EXPERIMENTAL && freezingMode != Freezing.Full -> {
configuration.report( configuration.report(
CompilerMessageSeverity.ERROR, CompilerMessageSeverity.ERROR,
@@ -205,12 +209,15 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
val shouldCoverSources = configuration.getBoolean(KonanConfigKeys.COVERAGE) val shouldCoverSources = configuration.getBoolean(KonanConfigKeys.COVERAGE)
private val shouldCoverLibraries = !configuration.getList(KonanConfigKeys.LIBRARIES_TO_COVER).isNullOrEmpty() private val shouldCoverLibraries = !configuration.getList(KonanConfigKeys.LIBRARIES_TO_COVER).isNullOrEmpty()
private val defaultAllocationMode get() = when {
memoryModel == MemoryModel.EXPERIMENTAL && target.supportsMimallocAllocator() -> AllocationMode.MIMALLOC
else -> AllocationMode.STD
}
val allocationMode by lazy { val allocationMode by lazy {
when (configuration.get(KonanConfigKeys.ALLOCATION_MODE)) { when (configuration.get(KonanConfigKeys.ALLOCATION_MODE)) {
null -> when { null -> defaultAllocationMode
memoryModel == MemoryModel.EXPERIMENTAL && target.supportsMimallocAllocator() -> AllocationMode.MIMALLOC
else -> AllocationMode.STD
}
AllocationMode.STD -> AllocationMode.STD AllocationMode.STD -> AllocationMode.STD
AllocationMode.MIMALLOC -> { AllocationMode.MIMALLOC -> {
if (target.supportsMimallocAllocator()) { if (target.supportsMimallocAllocator()) {
@@ -300,11 +307,12 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
internal val isInteropStubs: Boolean get() = manifestProperties?.getProperty("interop") == "true" internal val isInteropStubs: Boolean get() = manifestProperties?.getProperty("interop") == "true"
private val defaultPropertyLazyInitialization get() = when (memoryModel) {
MemoryModel.EXPERIMENTAL -> true
else -> false
}
internal val propertyLazyInitialization: Boolean get() = configuration.get(KonanConfigKeys.PROPERTY_LAZY_INITIALIZATION) ?: internal val propertyLazyInitialization: Boolean get() = configuration.get(KonanConfigKeys.PROPERTY_LAZY_INITIALIZATION) ?:
when (memoryModel) { defaultPropertyLazyInitialization
MemoryModel.EXPERIMENTAL -> true
else -> false
}
internal val lazyIrForCaches: Boolean get() = configuration.get(KonanConfigKeys.LAZY_IR_FOR_CACHES)!! internal val lazyIrForCaches: Boolean get() = configuration.get(KonanConfigKeys.LAZY_IR_FOR_CACHES)!!
@@ -324,15 +332,27 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
internal val testDumpFile: File? = configuration[KonanConfigKeys.TEST_DUMP_OUTPUT_PATH]?.let(::File) internal val testDumpFile: File? = configuration[KonanConfigKeys.TEST_DUMP_OUTPUT_PATH]?.let(::File)
internal val cacheSupport = CacheSupport( internal val useDebugInfoInNativeLibs= configuration.get(BinaryOptions.stripDebugInfoFromNativeLibs) == false
configuration = configuration,
resolvedLibraries = resolvedLibraries, internal val cacheSupport = run {
memoryModel = memoryModel, val ignoreCacheReason = when {
optimizationsEnabled = optimizationsEnabled, optimizationsEnabled -> "for optimized compilation"
propertyLazyInitialization = propertyLazyInitialization, memoryModel != defaultMemoryModel -> "with ${memoryModel.name.lowercase()} memory model"
target = target, propertyLazyInitialization != defaultPropertyLazyInitialization -> "with${if (propertyLazyInitialization) "" else "out"} lazy top levels initialization"
produce = produce useDebugInfoInNativeLibs -> "with native libs debug info"
) allocationMode != defaultAllocationMode -> "with ${allocationMode.name.lowercase()} allocator"
memoryModel == MemoryModel.EXPERIMENTAL && gc != defaultGC -> "with ${gc.name.lowercase()} garbage collector"
freezing != defaultFreezing -> "with ${freezing.name.replaceFirstChar { it.lowercase() }} freezing mode"
else -> null
}
CacheSupport(
configuration = configuration,
resolvedLibraries = resolvedLibraries,
ignoreCacheReason = ignoreCacheReason,
target = target,
produce = produce
)
}
internal val cachedLibraries: CachedLibraries internal val cachedLibraries: CachedLibraries
get() = cacheSupport.cachedLibraries get() = cacheSupport.cachedLibraries