forked from JetBrains/kotlin-native
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add initial support for producing and consuming cache
Dynamic cache isn't fully functional on Apple targets yet.
- Loading branch information
1 parent
fe591aa
commit 8205a26
Showing
16 changed files
with
394 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
....native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CacheSupport.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* | ||
* Copyright 2010-2019 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 | ||
|
||
import org.jetbrains.kotlin.config.CompilerConfiguration | ||
import org.jetbrains.kotlin.konan.file.File | ||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind | ||
import org.jetbrains.kotlin.konan.target.KonanTarget | ||
import org.jetbrains.kotlin.library.KotlinLibrary | ||
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult | ||
|
||
class CacheSupport( | ||
configuration: CompilerConfiguration, | ||
resolvedLibraries: KotlinLibraryResolveResult, | ||
target: KonanTarget, | ||
produce: CompilerOutputKind | ||
) { | ||
private val allLibraries = resolvedLibraries.getFullList() | ||
|
||
// TODO: consider using [FeaturedLibraries.kt]. | ||
private val fileToLibrary = allLibraries.associateBy { it.libraryFile } | ||
|
||
internal val cachedLibraries: CachedLibraries = run { | ||
val explicitCacheFiles = configuration.get(KonanConfigKeys.CACHED_LIBRARIES)!! | ||
|
||
val explicitCaches = explicitCacheFiles.entries.associate { (libraryPath, cachePath) -> | ||
val library = fileToLibrary[File(libraryPath)] | ||
?: configuration.reportCompilationError("cache not applied: library $libraryPath in $cachePath") | ||
|
||
library to cachePath | ||
} | ||
|
||
val implicitCacheDirectories = configuration.get(KonanConfigKeys.CACHE_DIRECTORIES)!! | ||
.map { | ||
File(it).takeIf { it.isDirectory } | ||
?: configuration.reportCompilationError("cache directory $it is not found or not a directory") | ||
} | ||
|
||
CachedLibraries( | ||
target = target, | ||
allLibraries = allLibraries, | ||
explicitCaches = explicitCaches, | ||
implicitCacheDirectories = implicitCacheDirectories | ||
) | ||
} | ||
|
||
internal val librariesToCache: Set<KotlinLibrary> = configuration.get(KonanConfigKeys.LIBRARIES_TO_CACHE)!! | ||
.map { File(it) }.map { | ||
fileToLibrary[it] ?: error("library to cache\n" + | ||
" ${it.absolutePath}\n" + | ||
"not found among resolved libraries:\n " + | ||
allLibraries.joinToString("\n ") { it.libraryFile.absolutePath }) | ||
}.toSet() | ||
.also { if (!produce.isCache) check(it.isEmpty()) } | ||
|
||
init { | ||
// Ensure dependencies of every cached library are cached too: | ||
resolvedLibraries.getFullList { libraries -> | ||
libraries.map { library -> | ||
val cache = cachedLibraries.getLibraryCache(library.library) | ||
if (cache != null || library.library in librariesToCache) { | ||
library.resolvedDependencies.forEach { | ||
if (!cachedLibraries.isLibraryCached(it.library) && it.library !in librariesToCache) { | ||
val description = if (cache != null) { | ||
"cached (in ${cache.path})" | ||
} else { | ||
"going to be cached" | ||
} | ||
configuration.reportCompilationError( | ||
"${library.library.libraryName} is $description, " + | ||
"but its dependency isn't: ${it.library.libraryName}" | ||
) | ||
} | ||
} | ||
} | ||
|
||
library | ||
} | ||
} | ||
|
||
// Ensure not making cache for libraries that are already cached: | ||
librariesToCache.forEach { | ||
val cache = cachedLibraries.getLibraryCache(it) | ||
if (cache != null) { | ||
configuration.reportCompilationError("Can't cache library '${it.libraryName}' " + | ||
"that is already cached in '${cache.path}'") | ||
} | ||
} | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
...tive/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CachedLibraries.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* Copyright 2010-2019 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 | ||
|
||
import org.jetbrains.kotlin.konan.file.File | ||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind | ||
import org.jetbrains.kotlin.konan.target.KonanTarget | ||
import org.jetbrains.kotlin.library.KotlinLibrary | ||
import org.jetbrains.kotlin.library.uniqueName | ||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult | ||
|
||
internal class CachedLibraries( | ||
private val target: KonanTarget, | ||
allLibraries: List<KotlinLibrary>, | ||
explicitCaches: Map<KotlinLibrary, String>, | ||
implicitCacheDirectories: List<File> | ||
) { | ||
|
||
class Cache(val kind: Kind, val path: String) { | ||
enum class Kind { DYNAMIC, STATIC } | ||
} | ||
|
||
private val allCaches: Map<KotlinLibrary, Cache> = allLibraries.mapNotNull { library -> | ||
val explicitPath = explicitCaches[library] | ||
|
||
val cache = if (explicitPath != null) { | ||
val kind = when { | ||
explicitPath.endsWith(target.family.dynamicSuffix) -> Cache.Kind.DYNAMIC | ||
explicitPath.endsWith(target.family.staticSuffix) -> Cache.Kind.STATIC | ||
else -> error("unexpected cache: $explicitPath") | ||
} | ||
Cache(kind, explicitPath) | ||
} else { | ||
implicitCacheDirectories.firstNotNullResult { dir -> | ||
val baseName = "${library.uniqueName}-cache" | ||
val dynamicFile = dir.child(getArtifactName(baseName, CompilerOutputKind.DYNAMIC_CACHE)) | ||
val staticFile = dir.child(getArtifactName(baseName, CompilerOutputKind.STATIC_CACHE)) | ||
|
||
when { | ||
dynamicFile.exists -> Cache(Cache.Kind.DYNAMIC, dynamicFile.absolutePath) | ||
staticFile.exists -> Cache(Cache.Kind.STATIC, staticFile.absolutePath) | ||
else -> null | ||
} | ||
} | ||
} | ||
|
||
cache?.let { library to it } | ||
}.toMap() | ||
|
||
private fun getArtifactName(baseName: String, kind: CompilerOutputKind) = | ||
"${kind.prefix(target)}$baseName${kind.suffix(target)}" | ||
|
||
fun isLibraryCached(library: KotlinLibrary): Boolean = | ||
getLibraryCache(library) != null | ||
|
||
fun getLibraryCache(library: KotlinLibrary): Cache? = | ||
allCaches[library] | ||
|
||
val hasStaticCaches = allCaches.values.any { | ||
when (it.kind) { | ||
Cache.Kind.STATIC -> true | ||
Cache.Kind.DYNAMIC -> false | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.