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:
+5
-5
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user