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.LookupSymbol
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.withLookupStorage
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.keysToMap
@@ -302,9 +301,10 @@ abstract class AbstractIncrementalJpsTest(
p.println("Begin of Lookup Maps")
p.println()
val lookupStorage = project.dataManager.getStorage(KotlinDataContainerTarget, JpsLookupStorageProvider)
lookupStorage.forceGC()
p.print(lookupStorage.dump(lookupsDuringTest))
project.dataManager.withLookupStorage { lookupStorage ->
lookupStorage.forceGC()
p.print(lookupStorage.dump(lookupsDuringTest))
}
p.println()
p.println("End of Lookup Maps")
@@ -380,7 +380,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
rebuildAfterCacheVersionChanged[target] = true
}
dataManager.getStorage(KotlinDataContainerTarget, JpsLookupStorageProvider).clean()
dataManager.withLookupStorage { it.clean() }
return
}
CacheVersion.Action.REBUILD_CHUNK -> {
@@ -405,7 +405,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
}
CacheVersion.Action.CLEAN_DATA_CONTAINER -> {
LOG.info("Clearing lookup cache")
dataManager.getStorage(KotlinDataContainerTarget, JpsLookupStorageProvider).clean()
dataManager.withLookupStorage { it.clean() }
cacheVersionsProvider.dataContainerVersion().clean()
}
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}")
val lookupStorage = dataManager.getStorage(KotlinDataContainerTarget, JpsLookupStorageProvider)
val removedFiles = chunk.targets.flatMap { KotlinSourceFileCollector.getRemovedKotlinFiles(dirtyFilesHolder, it) }
lookupStorage.removeLookupsFrom(filesToCompile.values().asSequence() + removedFiles.asSequence())
lookupStorage.addAll(lookupTracker.lookups.entrySet(), lookupTracker.pathInterner.values)
dataManager.withLookupStorage { lookupStorage ->
lookupStorage.removeLookupsFrom(filesToCompile.values().asSequence() + removedFiles.asSequence())
lookupStorage.addAll(lookupTracker.lookups.entrySet(), lookupTracker.pathInterner.values)
}
}
// if null is returned, nothing was done
@@ -818,15 +817,16 @@ private fun ChangesCollector.processChangesUsingLookups(
fsOperations: FSOperationsHelper,
caches: Iterable<IncrementalJvmCache>
) {
val lookupStorage = dataManager.getStorage(KotlinDataContainerTarget, JpsLookupStorageProvider)
val allCaches = caches.flatMap { it.thisWithDependentCaches }
val reporter = JpsICReporter()
reporter.report { "Start processing changes" }
val (dirtyLookupSymbols, dirtyClassFqNames) = getDirtyData(allCaches, reporter)
val dirtyFiles = mapLookupSymbolsToFiles(lookupStorage, dirtyLookupSymbols, reporter) +
mapClassesFqNamesToFiles(allCaches, dirtyClassFqNames, reporter)
val dirtyFilesFromLookups = dataManager.withLookupStorage {
mapLookupSymbolsToFiles(it, dirtyLookupSymbols, reporter)
}
val dirtyFiles = dirtyFilesFromLookups + mapClassesFqNamesToFiles(allCaches, dirtyClassFqNames, reporter)
fsOperations.markInChunkOrDependents(dirtyFiles.asIterable(), excludeFiles = compiledFiles)
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.incremental.CompileContext
import org.jetbrains.kotlin.incremental.LookupSymbol
import org.jetbrains.kotlin.jps.incremental.JpsLookupStorageProvider
import org.jetbrains.kotlin.jps.incremental.KotlinDataContainerTarget
import org.jetbrains.kotlin.jps.incremental.withLookupStorage
import java.io.File
import java.util.concurrent.Future
@@ -30,8 +29,9 @@ class KotlinLookupConstantSearch(context: CompileContext) : Callbacks.ConstantAf
fieldRemoved: Boolean,
accessChanged: Boolean
): Future<Callbacks.ConstantAffection> {
val storage = dataManager.getStorage(KotlinDataContainerTarget, JpsLookupStorageProvider)
val paths = storage.get(LookupSymbol(name = fieldName, scope = ownerClassName))
val paths = dataManager.withLookupStorage { storage ->
storage.get(LookupSymbol(name = fieldName, scope = ownerClassName))
}
return FixedFuture(Callbacks.ConstantAffection(paths.map(::File)))
}
}
@@ -17,12 +17,19 @@
package org.jetbrains.kotlin.jps.incremental
import org.jetbrains.jps.builders.storage.StorageProvider
import org.jetbrains.jps.incremental.storage.BuildDataManager
import org.jetbrains.jps.incremental.storage.StorageOwner
import org.jetbrains.kotlin.incremental.LookupStorage
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)
}
class JpsLookupStorage(targetDataDir: File) : StorageOwner, LookupStorage(targetDataDir)
private class JpsLookupStorage(targetDataDir: File) : StorageOwner, LookupStorage(targetDataDir)