Save changed functions to incremental cache
This commit is contained in:
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.load.kotlin.header.isCompatiblePackageFacadeKind
|
|||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.InlineRegistering
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.InlineRegistering
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName.byInternalName
|
||||||
import org.jetbrains.kotlin.serialization.Flags
|
import org.jetbrains.kotlin.serialization.Flags
|
||||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.visibility
|
import org.jetbrains.kotlin.serialization.deserialization.visibility
|
||||||
@@ -106,6 +107,7 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
|
|||||||
val SOURCE_TO_CLASSES = "source-to-classes.tab"
|
val SOURCE_TO_CLASSES = "source-to-classes.tab"
|
||||||
val CLASS_TO_SOURCES = "class-to-sources.tab"
|
val CLASS_TO_SOURCES = "class-to-sources.tab"
|
||||||
val DIRTY_OUTPUT_CLASSES = "dirty-output-classes.tab"
|
val DIRTY_OUTPUT_CLASSES = "dirty-output-classes.tab"
|
||||||
|
val DIRTY_INLINE_FUNCTIONS = "dirty-inline-functions.tab"
|
||||||
val HAS_INLINE_TO = "has-inline-to.tab"
|
val HAS_INLINE_TO = "has-inline-to.tab"
|
||||||
|
|
||||||
private val MODULE_MAPPING_FILE_NAME = "." + ModuleMapping.MAPPING_FILE_EXT
|
private val MODULE_MAPPING_FILE_NAME = "." + ModuleMapping.MAPPING_FILE_EXT
|
||||||
@@ -119,6 +121,7 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
|
|||||||
private val sourceToClassesMap = SourceToClassesMap()
|
private val sourceToClassesMap = SourceToClassesMap()
|
||||||
private val classToSourcesMap = ClassToSourcesMap()
|
private val classToSourcesMap = ClassToSourcesMap()
|
||||||
private val dirtyOutputClassesMap = DirtyOutputClassesMap()
|
private val dirtyOutputClassesMap = DirtyOutputClassesMap()
|
||||||
|
private val dirtyInlineFunctionsMap = DirtyInlineFunctionsMap()
|
||||||
private val hasInlineTo = OneToManyPathsMapping(File(baseDir, HAS_INLINE_TO))
|
private val hasInlineTo = OneToManyPathsMapping(File(baseDir, HAS_INLINE_TO))
|
||||||
|
|
||||||
private val maps = listOf(protoMap, constantsMap, inlineFunctionsMap, packagePartMap, sourceToClassesMap, dirtyOutputClassesMap)
|
private val maps = listOf(protoMap, constantsMap, inlineFunctionsMap, packagePartMap, sourceToClassesMap, dirtyOutputClassesMap)
|
||||||
@@ -253,6 +256,7 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
|
|||||||
inlineFunctionsMap.remove(className)
|
inlineFunctionsMap.remove(className)
|
||||||
}
|
}
|
||||||
dirtyOutputClassesMap.clean()
|
dirtyOutputClassesMap.clean()
|
||||||
|
dirtyInlineFunctionsMap.clean()
|
||||||
return recompilationDecision
|
return recompilationDecision
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,7 +554,7 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
|
|||||||
InlineFunctionsMapExternalizer
|
InlineFunctionsMapExternalizer
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun getInlineFunctionsMap(bytes: ByteArray): Map<String, Long>? {
|
private fun getInlineFunctionsMap(bytes: ByteArray): Map<String, Long> {
|
||||||
val result = HashMap<String, Long>()
|
val result = HashMap<String, Long>()
|
||||||
|
|
||||||
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.ASM5) {
|
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.ASM5) {
|
||||||
@@ -579,31 +583,44 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
|
|||||||
|
|
||||||
}, 0)
|
}, 0)
|
||||||
|
|
||||||
return if (result.isEmpty()) null else result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun process(className: JvmClassName, bytes: ByteArray): Boolean {
|
public fun process(className: JvmClassName, bytes: ByteArray): Boolean {
|
||||||
return put(className, getInlineFunctionsMap(bytes))
|
return put(className, getInlineFunctionsMap(bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun put(className: JvmClassName, inlineFunctionsMap: Map<String, Long>?): Boolean {
|
private fun put(className: JvmClassName, newMap: Map<String, Long>): Boolean {
|
||||||
val key = className.getInternalName()
|
val internalName = className.internalName
|
||||||
|
val oldMap = storage[internalName] ?: emptyMap()
|
||||||
|
|
||||||
val oldMap = storage[key]
|
val changed = hashSetOf<String>()
|
||||||
if (oldMap == inlineFunctionsMap) {
|
val allFunctions = oldMap.keySet() + newMap.keySet()
|
||||||
return false
|
|
||||||
|
for (fn in allFunctions) {
|
||||||
|
val oldHash = oldMap[fn]
|
||||||
|
val newHash = newMap[fn]
|
||||||
|
|
||||||
|
if (oldHash != newHash) {
|
||||||
|
changed.add(fn)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (inlineFunctionsMap != null) {
|
|
||||||
storage.put(key, inlineFunctionsMap)
|
when {
|
||||||
|
newMap.isNotEmpty() -> storage.put(internalName, newMap)
|
||||||
|
else -> storage.remove(internalName)
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
storage.remove(key)
|
if (changed.isNotEmpty()) {
|
||||||
|
dirtyInlineFunctionsMap.put(className, changed.toList())
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun remove(className: JvmClassName) {
|
public fun remove(className: JvmClassName) {
|
||||||
put(className, null)
|
storage.remove(className.internalName)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dumpValue(value: Map<String, Long>): String {
|
override fun dumpValue(value: Map<String, Long>): String {
|
||||||
@@ -735,6 +752,24 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
|
|||||||
override fun dumpValue(value: Boolean) = ""
|
override fun dumpValue(value: Boolean) = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inner class DirtyInlineFunctionsMap : BasicMap<List<String>>() {
|
||||||
|
override fun createMap(): PersistentHashMap<String, List<String>> = PersistentHashMap(
|
||||||
|
File(baseDir, DIRTY_INLINE_FUNCTIONS),
|
||||||
|
EnumeratorStringDescriptor(),
|
||||||
|
StringListExternalizer
|
||||||
|
)
|
||||||
|
|
||||||
|
public fun getEntries(): Map<JvmClassName, List<String>> =
|
||||||
|
storage.allKeysWithExistingMapping
|
||||||
|
.toMap(JvmClassName::byInternalName) { storage[it] }
|
||||||
|
|
||||||
|
public fun put(className: JvmClassName, changedFunctions: List<String>) {
|
||||||
|
storage.put(className.internalName, changedFunctions)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dumpValue(value: List<String>) = value.toString()
|
||||||
|
}
|
||||||
|
|
||||||
enum class RecompilationDecision {
|
enum class RecompilationDecision {
|
||||||
DO_NOTHING,
|
DO_NOTHING,
|
||||||
RECOMPILE_OTHER_KOTLIN_IN_CHUNK,
|
RECOMPILE_OTHER_KOTLIN_IN_CHUNK,
|
||||||
|
|||||||
Reference in New Issue
Block a user