[JS IR] Invalidate IC cache after modifying language settings

^KT-54010 Fixed
This commit is contained in:
Alexander Korepanov
2022-09-13 14:41:42 +02:00
committed by Space
parent dd7d669464
commit 639af77b91
4 changed files with 28 additions and 13 deletions
@@ -303,10 +303,13 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
messageCollector.report(INFO, "IC rebuilt overall time: ${System.currentTimeMillis() - start}ms")
for ((libFile, srcFiles) in cacheUpdater.getDirtyFileStats()) {
val isCleanBuild = srcFiles.values.all { it.contains(DirtyFileState.ADDED_FILE) }
val msg = if (isCleanBuild) "fully rebuilt" else "partially rebuilt"
val (msg, showFiles) = when {
srcFiles.values.all { it.contains(DirtyFileState.ADDED_FILE) } -> "fully rebuilt due to clean build" to false
srcFiles.values.all { it.contains(DirtyFileState.MODIFIED_CONFIG) } -> "fully rebuilt due to config modification" to false
else -> "partially rebuilt" to true
}
messageCollector.report(INFO, "module [${File(libFile.path).name}] was $msg")
if (!isCleanBuild) {
if (showFiles) {
for ((srcFile, stat) in srcFiles) {
val statStr = stat.joinToString { it.str }
messageCollector.report(INFO, " file [${File(srcFile.path).name}]: ($statStr)")
@@ -37,6 +37,7 @@ fun interface CacheExecutor {
enum class DirtyFileState(val str: String) {
ADDED_FILE("added file"),
MODIFIED_CONFIG("modified config"),
MODIFIED_IR("modified ir"),
UPDATED_EXPORTS("updated exports"),
UPDATED_IMPORTS("updated imports"),
@@ -189,13 +190,14 @@ class CacheUpdater(
val removedFilesMetadata = mutableMapOf<KotlinLibraryFile, Map<KotlinSourceFile, KotlinSourceFileMetadata>>()
val modifiedFiles = KotlinSourceFileMap(incrementalCaches.entries.associate { (lib, cache) ->
val (dirtyFiles, removedFiles, newFiles) = cache.collectModifiedFiles(configHash)
val (dirtyFiles, removedFiles, newFiles, modifiedConfigFiles) = cache.collectModifiedFiles(configHash)
val fileStats by lazy(LazyThreadSafetyMode.NONE) { dirtyFileStats.getOrPutFiles(lib) }
newFiles.forEach { fileStats.addDirtFileStat(it, DirtyFileState.ADDED_FILE) }
modifiedConfigFiles.forEach { fileStats.addDirtFileStat(it, DirtyFileState.MODIFIED_CONFIG) }
removedFiles.forEach { fileStats.addDirtFileStat(it.key, DirtyFileState.REMOVED_FILE) }
dirtyFiles.forEach {
if (it.key !in newFiles) {
if (it.key !in newFiles && it.key !in modifiedConfigFiles) {
fileStats.addDirtFileStat(it.key, DirtyFileState.MODIFIED_IR)
}
}
@@ -6,10 +6,9 @@
package org.jetbrains.kotlin.ir.backend.js.ic
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CrossModuleReferences
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
@@ -75,6 +74,8 @@ internal fun CompilerConfiguration.configHashForIC() = HashCalculatorForIC().app
update(key.toString())
update(getBoolean(key).toString())
}
update(languageVersionSettings.toString())
}.finalize()
internal fun IrElement.irElementHashForIC() = HashCalculatorForIC().also {
@@ -103,16 +103,19 @@ class IncrementalCache(private val library: KotlinLibrary, cachePath: String) {
}
data class ModifiedFiles(
val modified: Map<KotlinSourceFile, KotlinSourceFileMetadata> = emptyMap(),
val removed: Map<KotlinSourceFile, KotlinSourceFileMetadata> = emptyMap(),
val newFiles: Set<KotlinSourceFile> = emptySet()
val dirtyFiles: Map<KotlinSourceFile, KotlinSourceFileMetadata> = emptyMap(),
val removedFiles: Map<KotlinSourceFile, KotlinSourceFileMetadata> = emptyMap(),
val newFiles: Set<KotlinSourceFile> = emptySet(),
val modifiedConfigFiles: Set<KotlinSourceFile> = emptySet(),
)
fun collectModifiedFiles(configHash: ICHash): ModifiedFiles {
var isConfigModified = false
val klibFileHash = library.libraryFile.javaFile().fileHashForIC()
cacheHeader = when {
cacheHeader.configHash != configHash -> {
cacheDir.deleteRecursively()
isConfigModified = cacheHeader.configHash != ICHash()
CacheHeader(klibFileHash, configHash)
}
cacheHeader.klibFileHash != klibFileHash -> CacheHeader(klibFileHash, configHash)
@@ -121,14 +124,14 @@ class IncrementalCache(private val library: KotlinLibrary, cachePath: String) {
val cachedFingerprints = loadCachedFingerprints()
val deletedFiles = cachedFingerprints.keys.toMutableSet()
val newFiles = mutableSetOf<KotlinSourceFile>()
val unknownFiles = mutableSetOf<KotlinSourceFile>()
val newFingerprints = kotlinLibraryHeader.sourceFiles.mapIndexed { index, file -> file to library.fingerprint(index) }
val modifiedFiles = buildMap(newFingerprints.size) {
for ((file, fileNewFingerprint) in newFingerprints) {
val oldFingerprint = cachedFingerprints[file]
if (oldFingerprint == null) {
newFiles += file
unknownFiles += file
}
if (oldFingerprint != fileNewFingerprint) {
val metadata = fetchSourceFileMetadata(file, false)
@@ -148,7 +151,13 @@ class IncrementalCache(private val library: KotlinLibrary, cachePath: String) {
forceRebuildJs = deletedFiles.isNotEmpty()
commitCacheHeader(newFingerprints)
return ModifiedFiles(modifiedFiles, removedFilesMetadata, newFiles)
val (newFiles, modifiedConfigFiles) = if (isConfigModified) {
emptySet<KotlinSourceFile>() to unknownFiles
} else {
unknownFiles to emptySet<KotlinSourceFile>()
}
return ModifiedFiles(modifiedFiles, removedFilesMetadata, newFiles, modifiedConfigFiles)
}
fun fetchSourceFileFullMetadata(srcFile: KotlinSourceFile): KotlinSourceFileMetadata {