incremental compiler caches: code cleanup and simplification

This commit is contained in:
nik
2014-12-23 18:58:12 +03:00
committed by Evgeny Gerashchenko
parent 09942d7c09
commit 6e9f94d1ea
4 changed files with 35 additions and 34 deletions
@@ -56,6 +56,7 @@ import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.jps.model.JpsProject import org.jetbrains.jps.model.JpsProject
import org.jetbrains.kotlin.compilerRunner.SimpleOutputItem import org.jetbrains.kotlin.compilerRunner.SimpleOutputItem
import org.jetbrains.kotlin.utils.LibraryUtils import org.jetbrains.kotlin.utils.LibraryUtils
import org.jetbrains.kotlin.load.kotlin.incremental.cache.IncrementalCache
public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
class object { class object {
@@ -88,8 +89,8 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
val dataManager = context.getProjectDescriptor().dataManager val dataManager = context.getProjectDescriptor().dataManager
if (chunk.getTargets().any { CacheFormatVersion(File(dataManager.getDataPaths().getTargetDataRoot(it), IncrementalCacheImpl.DIRECTORY_NAME)).isIncompatible() }) { if (chunk.getTargets().any { dataManager.getDataPaths().getKotlinCacheVersion(it).isIncompatible() }) {
chunk.getTargets().forEach { dataManager.getStorage(it, IncrementalCacheStorageProvider).clean() } chunk.getTargets().forEach { dataManager.getKotlinCache(it).clean() }
return CHUNK_REBUILD_REQUIRED return CHUNK_REBUILD_REQUIRED
} }
@@ -100,7 +101,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
messageCollector.report(INFO, "Kotlin JPS plugin version " + KotlinVersion.VERSION, NO_LOCATION) messageCollector.report(INFO, "Kotlin JPS plugin version " + KotlinVersion.VERSION, NO_LOCATION)
val incrementalCaches = chunk.getTargets().keysToMap { dataManager.getStorage(it, IncrementalCacheStorageProvider) } val incrementalCaches = chunk.getTargets().keysToMap { dataManager.getKotlinCache(it) }
val environment = createCompileEnvironment(incrementalCaches) val environment = createCompileEnvironment(incrementalCaches)
if (!environment.success()) { if (!environment.success()) {
environment.reportErrorsTo(messageCollector) environment.reportErrorsTo(messageCollector)
@@ -164,7 +165,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
return OK return OK
} }
private fun createCompileEnvironment(incrementalCaches: Map<ModuleBuildTarget, IncrementalCacheImpl>): CompilerEnvironment { private fun createCompileEnvironment(incrementalCaches: Map<ModuleBuildTarget, IncrementalCache>): CompilerEnvironment {
val compilerServices = Services.Builder() val compilerServices = Services.Builder()
.register(javaClass<IncrementalCacheProvider>(), IncrementalCacheProviderImpl(incrementalCaches)) .register(javaClass<IncrementalCacheProvider>(), IncrementalCacheProviderImpl(incrementalCaches))
.build() .build()
@@ -42,63 +42,59 @@ import java.io.IOException
import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.kotlin.header.isCompatiblePackageFacadeKind import org.jetbrains.kotlin.load.kotlin.header.isCompatiblePackageFacadeKind
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind
import org.jetbrains.jps.incremental.storage.BuildDataManager
import org.jetbrains.jps.builders.BuildTarget
import org.jetbrains.jps.builders.storage.BuildDataPaths
val INLINE_ANNOTATION_DESC = "Lkotlin/inline;" val INLINE_ANNOTATION_DESC = "Lkotlin/inline;"
public class CacheFormatVersion(val baseDir: File) { private val CACHE_DIRECTORY_NAME = "kotlin"
class CacheFormatVersion(targetDataRoot: File) {
class object { class object {
// Change this when incremental cache format changes // Change this when incremental cache format changes
private val INCREMENTAL_CACHE_OWN_VERSION = 1 private val INCREMENTAL_CACHE_OWN_VERSION = 1
val CACHE_FORMAT_VERSION: Int = INCREMENTAL_CACHE_OWN_VERSION * 1000000 + JvmAbi.VERSION private val CACHE_FORMAT_VERSION: Int = INCREMENTAL_CACHE_OWN_VERSION * 1000000 + JvmAbi.VERSION
val FORMAT_VERSION_TXT: String = "format-version.txt" val FORMAT_VERSION_FILE_PATH: String = "$CACHE_DIRECTORY_NAME/format-version.txt"
} }
private fun getFile(): File { private val file = File(targetDataRoot, FORMAT_VERSION_FILE_PATH)
return File(baseDir, "format-version.txt")
}
public fun isIncompatible(): Boolean { public fun isIncompatible(): Boolean {
val version = load() if (!file.exists()) return false
return version != -1 && version != CACHE_FORMAT_VERSION
}
private fun load(): Int { return file.readText().toInt() != CACHE_FORMAT_VERSION
val versionFile = getFile()
if (!versionFile.exists()) return -1
return versionFile.readText().toInt()
} }
fun saveIfNeeded() { fun saveIfNeeded() {
val versionFile = getFile() if (!file.exists()) {
if (!versionFile.exists()) { file.writeText(CACHE_FORMAT_VERSION.toString())
versionFile.writeText(CACHE_FORMAT_VERSION.toString())
} }
} }
fun clean() { fun clean() {
getFile().delete() file.delete()
} }
} }
public class IncrementalCacheImpl(val baseDir: File): StorageOwner, IncrementalCache { public class IncrementalCacheImpl(targetDataRoot: File): StorageOwner, IncrementalCache {
class object { class object {
val DIRECTORY_NAME = "kotlin"
val PROTO_MAP = "proto.tab" val PROTO_MAP = "proto.tab"
val CONSTANTS_MAP = "constants.tab" val CONSTANTS_MAP = "constants.tab"
val INLINE_FUNCTIONS = "inline-functions.tab" val INLINE_FUNCTIONS = "inline-functions.tab"
val PACKAGE_PARTS = "package-parts.tab" val PACKAGE_PARTS = "package-parts.tab"
} }
private val baseDir = File(targetDataRoot, CACHE_DIRECTORY_NAME)
private val protoMap = ProtoMap() private val protoMap = ProtoMap()
private val constantsMap = ConstantsMap() private val constantsMap = ConstantsMap()
private val inlineFunctionsMap = InlineFunctionsMap() private val inlineFunctionsMap = InlineFunctionsMap()
private val packagePartMap = PackagePartMap() private val packagePartMap = PackagePartMap()
private val maps = listOf(protoMap, constantsMap, inlineFunctionsMap, packagePartMap) private val maps = listOf(protoMap, constantsMap, inlineFunctionsMap, packagePartMap)
private val cacheFormatVersion = CacheFormatVersion(baseDir) private val cacheFormatVersion = CacheFormatVersion(targetDataRoot)
public fun saveFileToCache(sourceFiles: Collection<File>, classFile: File): RecompilationDecision { public fun saveFileToCache(sourceFiles: Collection<File>, classFile: File): RecompilationDecision {
if (classFile.extension.toLowerCase() != "class") return DO_NOTHING if (classFile.extension.toLowerCase() != "class") return DO_NOTHING
@@ -510,12 +506,16 @@ public class IncrementalCacheImpl(val baseDir: File): StorageOwner, IncrementalC
} }
} }
public object IncrementalCacheStorageProvider : StorageProvider<IncrementalCacheImpl>() { private val storageProvider = object: StorageProvider<IncrementalCacheImpl>() {
override fun createStorage(targetDataDir: File?): IncrementalCacheImpl { override fun createStorage(targetDataDir: File): IncrementalCacheImpl {
return IncrementalCacheImpl(File(targetDataDir, IncrementalCacheImpl.DIRECTORY_NAME)) return IncrementalCacheImpl(targetDataDir)
} }
} }
public fun BuildDataPaths.getKotlinCacheVersion(target: BuildTarget<*>): CacheFormatVersion = CacheFormatVersion(getTargetDataRoot(target))
public fun BuildDataManager.getKotlinCache(target: BuildTarget<*>): IncrementalCacheImpl = getStorage(target, storageProvider)
private fun ByteArray.md5(): Long { private fun ByteArray.md5(): Long {
val d = MessageDigest.getInstance("MD5").digest(this)!! val d = MessageDigest.getInstance("MD5").digest(this)!!
return ((d[0].toLong() and 0xFFL) return ((d[0].toLong() and 0xFFL)
@@ -530,8 +530,8 @@ private fun ByteArray.md5(): Long {
} }
private object ByteArrayExternalizer: DataExternalizer<ByteArray> { private object ByteArrayExternalizer: DataExternalizer<ByteArray> {
override fun save(out: DataOutput, value: ByteArray?) { override fun save(out: DataOutput, value: ByteArray) {
out.writeInt(value!!.size) out.writeInt(value.size())
out.write(value) out.write(value)
} }
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.load.kotlin.incremental.cache.IncrementalCacheProvid
import org.jetbrains.jps.incremental.ModuleBuildTarget import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.kotlin.load.kotlin.incremental.cache.IncrementalCache import org.jetbrains.kotlin.load.kotlin.incremental.cache.IncrementalCache
public class IncrementalCacheProviderImpl(caches: Map<ModuleBuildTarget, IncrementalCacheImpl>): IncrementalCacheProvider { public class IncrementalCacheProviderImpl(caches: Map<ModuleBuildTarget, IncrementalCache>): IncrementalCacheProvider {
private val idToCache = caches.mapKeys { it.key.getId()!! } private val idToCache = caches.mapKeys { it.key.getId()!! }
override fun getIncrementalCache(moduleId: String): IncrementalCache { override fun getIncrementalCache(moduleId: String): IncrementalCache {
@@ -37,7 +37,7 @@ public class IncrementalCacheVersionChangedTest : AbstractIncrementalJpsTest() {
override fun performAdditionalModifications() { override fun performAdditionalModifications() {
val storageForTargetType = BuildDataPathsImpl(myDataStorageRoot).getTargetTypeDataRoot(JavaModuleBuildTargetType.PRODUCTION) val storageForTargetType = BuildDataPathsImpl(myDataStorageRoot).getTargetTypeDataRoot(JavaModuleBuildTargetType.PRODUCTION)
val relativePath = "module/${File.separator}${IncrementalCacheImpl.DIRECTORY_NAME}/${CacheFormatVersion.FORMAT_VERSION_TXT}" val relativePath = "module/${CacheFormatVersion.FORMAT_VERSION_FILE_PATH}"
val cacheVersionFile = File(storageForTargetType, relativePath) val cacheVersionFile = File(storageForTargetType, relativePath)
assertTrue(cacheVersionFile.exists()) assertTrue(cacheVersionFile.exists())