Synchronize access to lookup storage in JPS

Storage operations are synchronized already,
but BuildDataManager.getStorage is not synchronized,
so maybe it is possible to create multiple LookupStorage
instances.

    #KT-22535
    #KT-22995
This commit is contained in:
Alexey Tsvetkov
2018-02-22 01:45:49 +03:00
parent 3a609a9472
commit 8ab9366ae5
4 changed files with 28 additions and 21 deletions
@@ -47,9 +47,8 @@ import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.incremental.CacheVersion import org.jetbrains.kotlin.incremental.CacheVersion
import org.jetbrains.kotlin.incremental.LookupSymbol import org.jetbrains.kotlin.incremental.LookupSymbol
import org.jetbrains.kotlin.incremental.testingUtils.* import org.jetbrains.kotlin.incremental.testingUtils.*
import org.jetbrains.kotlin.jps.incremental.JpsLookupStorageProvider
import org.jetbrains.kotlin.jps.incremental.KotlinDataContainerTarget
import org.jetbrains.kotlin.jps.incremental.getKotlinCache import org.jetbrains.kotlin.jps.incremental.getKotlinCache
import org.jetbrains.kotlin.jps.incremental.withLookupStorage
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.keysToMap import org.jetbrains.kotlin.utils.keysToMap
@@ -302,9 +301,10 @@ abstract class AbstractIncrementalJpsTest(
p.println("Begin of Lookup Maps") p.println("Begin of Lookup Maps")
p.println() p.println()
val lookupStorage = project.dataManager.getStorage(KotlinDataContainerTarget, JpsLookupStorageProvider) project.dataManager.withLookupStorage { lookupStorage ->
lookupStorage.forceGC() lookupStorage.forceGC()
p.print(lookupStorage.dump(lookupsDuringTest)) p.print(lookupStorage.dump(lookupsDuringTest))
}
p.println() p.println()
p.println("End of Lookup Maps") p.println("End of Lookup Maps")
@@ -380,7 +380,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
rebuildAfterCacheVersionChanged[target] = true rebuildAfterCacheVersionChanged[target] = true
} }
dataManager.getStorage(KotlinDataContainerTarget, JpsLookupStorageProvider).clean() dataManager.withLookupStorage { it.clean() }
return return
} }
CacheVersion.Action.REBUILD_CHUNK -> { CacheVersion.Action.REBUILD_CHUNK -> {
@@ -405,7 +405,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
} }
CacheVersion.Action.CLEAN_DATA_CONTAINER -> { CacheVersion.Action.CLEAN_DATA_CONTAINER -> {
LOG.info("Clearing lookup cache") LOG.info("Clearing lookup cache")
dataManager.getStorage(KotlinDataContainerTarget, JpsLookupStorageProvider).clean() dataManager.withLookupStorage { it.clean() }
cacheVersionsProvider.dataContainerVersion().clean() cacheVersionsProvider.dataContainerVersion().clean()
} }
else -> { else -> {
@@ -617,12 +617,11 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
) { ) {
if (lookupTracker !is LookupTrackerImpl) throw AssertionError("Lookup tracker is expected to be LookupTrackerImpl, got ${lookupTracker::class.java}") if (lookupTracker !is LookupTrackerImpl) throw AssertionError("Lookup tracker is expected to be LookupTrackerImpl, got ${lookupTracker::class.java}")
val lookupStorage = dataManager.getStorage(KotlinDataContainerTarget, JpsLookupStorageProvider)
val removedFiles = chunk.targets.flatMap { KotlinSourceFileCollector.getRemovedKotlinFiles(dirtyFilesHolder, it) } val removedFiles = chunk.targets.flatMap { KotlinSourceFileCollector.getRemovedKotlinFiles(dirtyFilesHolder, it) }
lookupStorage.removeLookupsFrom(filesToCompile.values().asSequence() + removedFiles.asSequence()) dataManager.withLookupStorage { lookupStorage ->
lookupStorage.removeLookupsFrom(filesToCompile.values().asSequence() + removedFiles.asSequence())
lookupStorage.addAll(lookupTracker.lookups.entrySet(), lookupTracker.pathInterner.values) lookupStorage.addAll(lookupTracker.lookups.entrySet(), lookupTracker.pathInterner.values)
}
} }
// if null is returned, nothing was done // if null is returned, nothing was done
@@ -818,15 +817,16 @@ private fun ChangesCollector.processChangesUsingLookups(
fsOperations: FSOperationsHelper, fsOperations: FSOperationsHelper,
caches: Iterable<IncrementalJvmCache> caches: Iterable<IncrementalJvmCache>
) { ) {
val lookupStorage = dataManager.getStorage(KotlinDataContainerTarget, JpsLookupStorageProvider)
val allCaches = caches.flatMap { it.thisWithDependentCaches } val allCaches = caches.flatMap { it.thisWithDependentCaches }
val reporter = JpsICReporter() val reporter = JpsICReporter()
reporter.report { "Start processing changes" } reporter.report { "Start processing changes" }
val (dirtyLookupSymbols, dirtyClassFqNames) = getDirtyData(allCaches, reporter) val (dirtyLookupSymbols, dirtyClassFqNames) = getDirtyData(allCaches, reporter)
val dirtyFiles = mapLookupSymbolsToFiles(lookupStorage, dirtyLookupSymbols, reporter) + val dirtyFilesFromLookups = dataManager.withLookupStorage {
mapClassesFqNamesToFiles(allCaches, dirtyClassFqNames, reporter) mapLookupSymbolsToFiles(it, dirtyLookupSymbols, reporter)
}
val dirtyFiles = dirtyFilesFromLookups + mapClassesFqNamesToFiles(allCaches, dirtyClassFqNames, reporter)
fsOperations.markInChunkOrDependents(dirtyFiles.asIterable(), excludeFiles = compiledFiles) fsOperations.markInChunkOrDependents(dirtyFiles.asIterable(), excludeFiles = compiledFiles)
reporter.report { "End of processing changes" } reporter.report { "End of processing changes" }
@@ -10,8 +10,7 @@ import org.jetbrains.jps.builders.java.ConstantSearchProvider
import org.jetbrains.jps.builders.java.dependencyView.Callbacks import org.jetbrains.jps.builders.java.dependencyView.Callbacks
import org.jetbrains.jps.incremental.CompileContext import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.kotlin.incremental.LookupSymbol import org.jetbrains.kotlin.incremental.LookupSymbol
import org.jetbrains.kotlin.jps.incremental.JpsLookupStorageProvider import org.jetbrains.kotlin.jps.incremental.withLookupStorage
import org.jetbrains.kotlin.jps.incremental.KotlinDataContainerTarget
import java.io.File import java.io.File
import java.util.concurrent.Future import java.util.concurrent.Future
@@ -30,8 +29,9 @@ class KotlinLookupConstantSearch(context: CompileContext) : Callbacks.ConstantAf
fieldRemoved: Boolean, fieldRemoved: Boolean,
accessChanged: Boolean accessChanged: Boolean
): Future<Callbacks.ConstantAffection> { ): Future<Callbacks.ConstantAffection> {
val storage = dataManager.getStorage(KotlinDataContainerTarget, JpsLookupStorageProvider) val paths = dataManager.withLookupStorage { storage ->
val paths = storage.get(LookupSymbol(name = fieldName, scope = ownerClassName)) storage.get(LookupSymbol(name = fieldName, scope = ownerClassName))
}
return FixedFuture(Callbacks.ConstantAffection(paths.map(::File))) return FixedFuture(Callbacks.ConstantAffection(paths.map(::File)))
} }
} }
@@ -17,12 +17,19 @@
package org.jetbrains.kotlin.jps.incremental package org.jetbrains.kotlin.jps.incremental
import org.jetbrains.jps.builders.storage.StorageProvider import org.jetbrains.jps.builders.storage.StorageProvider
import org.jetbrains.jps.incremental.storage.BuildDataManager
import org.jetbrains.jps.incremental.storage.StorageOwner import org.jetbrains.jps.incremental.storage.StorageOwner
import org.jetbrains.kotlin.incremental.LookupStorage import org.jetbrains.kotlin.incremental.LookupStorage
import java.io.File import java.io.File
object JpsLookupStorageProvider : StorageProvider<JpsLookupStorage>() { @Synchronized
fun <T> BuildDataManager.withLookupStorage(fn: (LookupStorage) -> T): T {
val lookupStorage = getStorage(KotlinDataContainerTarget, JpsLookupStorageProvider)
return fn(lookupStorage)
}
private object JpsLookupStorageProvider : StorageProvider<JpsLookupStorage>() {
override fun createStorage(targetDataDir: File): JpsLookupStorage = JpsLookupStorage(targetDataDir) override fun createStorage(targetDataDir: File): JpsLookupStorage = JpsLookupStorage(targetDataDir)
} }
class JpsLookupStorage(targetDataDir: File) : StorageOwner, LookupStorage(targetDataDir) private class JpsLookupStorage(targetDataDir: File) : StorageOwner, LookupStorage(targetDataDir)