[K/N][caches] Aligned caches layout for per-module and per-file cases

This commit is contained in:
Igor Chevdar
2022-05-21 00:30:24 +05:00
committed by Space
parent b92580937a
commit aba8d8a859
4 changed files with 35 additions and 16 deletions
@@ -54,8 +54,8 @@ class CachedLibraries(
val result = mutableListOf<SerializedInlineFunctionReference>() val result = mutableListOf<SerializedInlineFunctionReference>()
when (granularity) { when (granularity) {
Granularity.MODULE -> { Granularity.MODULE -> {
val directory = File(path).absoluteFile.parent val directory = File(path).absoluteFile.parentFile.parentFile
val data = File(directory, INLINE_FUNCTION_BODIES_FILE_NAME).readBytes() val data = directory.child(PER_FILE_CACHE_IR_LEVEL_DIR_NAME).child(INLINE_FUNCTION_BODIES_FILE_NAME).readBytes()
InlineFunctionBodyReferenceSerializer.deserializeTo(data, result) InlineFunctionBodyReferenceSerializer.deserializeTo(data, result)
} }
Granularity.FILE -> { Granularity.FILE -> {
@@ -72,8 +72,8 @@ class CachedLibraries(
val result = mutableListOf<SerializedClassFields>() val result = mutableListOf<SerializedClassFields>()
when (granularity) { when (granularity) {
Granularity.MODULE -> { Granularity.MODULE -> {
val directory = File(path).absoluteFile.parent val directory = File(path).absoluteFile.parentFile.parentFile
val data = File(directory, CLASS_FIELDS_FILE_NAME).readBytes() val data = directory.child(PER_FILE_CACHE_IR_LEVEL_DIR_NAME).child(CLASS_FIELDS_FILE_NAME).readBytes()
ClassFieldsSerializer.deserializeTo(data, result) ClassFieldsSerializer.deserializeTo(data, result)
} }
Granularity.FILE -> { Granularity.FILE -> {
@@ -90,14 +90,15 @@ class CachedLibraries(
private val cacheDirsContents = mutableMapOf<String, Set<String>>() private val cacheDirsContents = mutableMapOf<String, Set<String>>()
private fun selectCache(library: KotlinLibrary, cacheDir: File): Cache? { private fun selectCache(library: KotlinLibrary, cacheDir: File): Cache? {
val cacheBinaryPartDir = cacheDir.child(PER_FILE_CACHE_BINARY_LEVEL_DIR_NAME)
// See Linker.renameOutput why is it ok to have an empty cache directory. // See Linker.renameOutput why is it ok to have an empty cache directory.
val cacheDirContents = cacheDirsContents.getOrPut(cacheDir.absolutePath) { val cacheDirContents = cacheDirsContents.getOrPut(cacheDir.absolutePath) {
cacheDir.listFilesOrEmpty.map { it.absolutePath }.toSet() cacheBinaryPartDir.listFilesOrEmpty.map { it.absolutePath }.toSet()
} }
if (cacheDirContents.isEmpty()) return null if (cacheDirContents.isEmpty()) return null
val baseName = getCachedLibraryName(library) val baseName = getCachedLibraryName(library)
val dynamicFile = cacheDir.child(getArtifactName(baseName, CompilerOutputKind.DYNAMIC_CACHE)) val dynamicFile = cacheBinaryPartDir.child(getArtifactName(baseName, CompilerOutputKind.DYNAMIC_CACHE))
val staticFile = cacheDir.child(getArtifactName(baseName, CompilerOutputKind.STATIC_CACHE)) val staticFile = cacheBinaryPartDir.child(getArtifactName(baseName, CompilerOutputKind.STATIC_CACHE))
if (dynamicFile.absolutePath in cacheDirContents && staticFile.absolutePath in cacheDirContents) if (dynamicFile.absolutePath in cacheDirContents && staticFile.absolutePath in cacheDirContents)
error("Both dynamic and static caches files cannot be in the same directory." + error("Both dynamic and static caches files cannot be in the same directory." +
@@ -48,7 +48,7 @@ internal class CacheStorage(val context: Context) {
} }
fun saveAdditionalCacheInfo() { fun saveAdditionalCacheInfo() {
context.config.outputFiles.tempCacheDirectory!!.mkdirs() context.config.outputFiles.prepareTempDirectories()
if (!isPreliminaryCache) if (!isPreliminaryCache)
saveCacheBitcodeDependencies() saveCacheBitcodeDependencies()
if (isPreliminaryCache || context.configuration.get(KonanConfigKeys.FILE_TO_CACHE) == null) { if (isPreliminaryCache || context.configuration.get(KonanConfigKeys.FILE_TO_CACHE) == null) {
@@ -17,7 +17,7 @@ import kotlin.random.Random
/** /**
* Creates and stores terminal compiler outputs. * Creates and stores terminal compiler outputs.
*/ */
class OutputFiles(outputPath: String?, target: KonanTarget, val produce: CompilerOutputKind, producePerFileCache: Boolean) { class OutputFiles(outputPath: String?, target: KonanTarget, val produce: CompilerOutputKind, val producePerFileCache: Boolean) {
private val prefix = produce.prefix(target) private val prefix = produce.prefix(target)
private val suffix = produce.suffix(target) private val suffix = produce.suffix(target)
@@ -53,22 +53,40 @@ class OutputFiles(outputPath: String?, target: KonanTarget, val produce: Compile
val cacheFileName = File((pathToPerFileCache ?: outputName).fullOutputName()).absoluteFile.name val cacheFileName = File((pathToPerFileCache ?: outputName).fullOutputName()).absoluteFile.name
val dynamicCacheInstallName = File(outputName).child(cacheFileName).absolutePath private fun File.cacheBinaryPart() =
if (producePerFileCache)
this
else
this.child(CachedLibraries.PER_FILE_CACHE_BINARY_LEVEL_DIR_NAME)
private fun File.cacheIrPart() =
if (producePerFileCache)
this
else
this.child(CachedLibraries.PER_FILE_CACHE_IR_LEVEL_DIR_NAME)
val dynamicCacheInstallName = File(outputName).cacheBinaryPart().child(cacheFileName).absolutePath
val tempCacheDirectory = val tempCacheDirectory =
if (produce.isCache) if (produce.isCache)
File(outputName + Random.nextLong().toString()) File(outputName + Random.nextLong().toString())
else null else null
val nativeBinaryFile = tempCacheDirectory?.child(cacheFileName)?.absolutePath ?: mainFileName fun prepareTempDirectories() {
tempCacheDirectory?.mkdirs()
tempCacheDirectory?.cacheBinaryPart()?.mkdirs()
tempCacheDirectory?.cacheIrPart()?.mkdirs()
}
val nativeBinaryFile = tempCacheDirectory?.cacheBinaryPart()?.child(cacheFileName)?.absolutePath ?: mainFileName
val symbolicInfoFile = "$nativeBinaryFile.dSYM" val symbolicInfoFile = "$nativeBinaryFile.dSYM"
val bitcodeDependenciesFile = tempCacheDirectory?.child(CachedLibraries.BITCODE_DEPENDENCIES_FILE_NAME) val bitcodeDependenciesFile = tempCacheDirectory?.cacheBinaryPart()?.child(CachedLibraries.BITCODE_DEPENDENCIES_FILE_NAME)
val inlineFunctionBodiesFile = tempCacheDirectory?.child(CachedLibraries.INLINE_FUNCTION_BODIES_FILE_NAME) val inlineFunctionBodiesFile = tempCacheDirectory?.cacheIrPart()?.child(CachedLibraries.INLINE_FUNCTION_BODIES_FILE_NAME)
val classFieldsFile = tempCacheDirectory?.child(CachedLibraries.CLASS_FIELDS_FILE_NAME) val classFieldsFile = tempCacheDirectory?.cacheIrPart()?.child(CachedLibraries.CLASS_FIELDS_FILE_NAME)
private fun String.fullOutputName() = prefixBaseNameIfNeeded(prefix).suffixIfNeeded(suffix) private fun String.fullOutputName() = prefixBaseNameIfNeeded(prefix).suffixIfNeeded(suffix)
@@ -475,8 +475,8 @@ internal fun PhaseConfig.konanPhasesConfig(config: KonanConfig) {
// Don't serialize anything to a final executable. // Don't serialize anything to a final executable.
disableUnless(serializerPhase, config.produce == CompilerOutputKind.LIBRARY) disableUnless(serializerPhase, config.produce == CompilerOutputKind.LIBRARY)
disableUnless(entryPointPhase, config.produce == CompilerOutputKind.PROGRAM) disableUnless(entryPointPhase, config.produce == CompilerOutputKind.PROGRAM)
disableUnless(buildAdditionalCacheInfoPhase, config.produce.isCache && config.lazyIrForCaches) disableUnless(buildAdditionalCacheInfoPhase, config.produce.isCache)
disableUnless(saveAdditionalCacheInfoPhase, config.produce.isCache && config.lazyIrForCaches) disableUnless(saveAdditionalCacheInfoPhase, config.produce.isCache)
disableUnless(finalizeCachePhase, config.produce.isCache) disableUnless(finalizeCachePhase, config.produce.isCache)
disableUnless(exportInternalAbiPhase, config.produce.isCache) disableUnless(exportInternalAbiPhase, config.produce.isCache)
disableUnless(buildCExportsPhase, config.produce.isNativeLibrary) disableUnless(buildCExportsPhase, config.produce.isNativeLibrary)