[KLIB] API4ABI: Avoid CCE in HashMap.computeIfAbsent()
^KT-54402
This commit is contained in:
committed by
Space Team
parent
0f33d71de3
commit
064600d351
+25
-3
@@ -23,6 +23,9 @@ import org.jetbrains.kotlin.library.abi.AbiTypeNullability.*
|
|||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.SpecialNames
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
|
import org.jetbrains.kotlin.storage.CacheWithNotNullValues
|
||||||
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.utils.*
|
import org.jetbrains.kotlin.utils.*
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.ifTrue
|
import org.jetbrains.kotlin.utils.addToStdlib.ifTrue
|
||||||
@@ -116,13 +119,20 @@ private class LibraryDeserializer(
|
|||||||
val packageFQN = fileReader.deserializeFqName(proto.fqNameList)
|
val packageFQN = fileReader.deserializeFqName(proto.fqNameList)
|
||||||
packageName = AbiCompoundName(packageFQN)
|
packageName = AbiCompoundName(packageFQN)
|
||||||
|
|
||||||
|
val fileName = if (proto.hasFileEntry() && proto.fileEntry.hasName()) proto.fileEntry.name else "<unknown>"
|
||||||
|
|
||||||
val fileSignature = FileSignature(
|
val fileSignature = FileSignature(
|
||||||
id = Any(), // Just an unique object.
|
id = Any(), // Just an unique object.
|
||||||
fqName = FqName(packageFQN),
|
fqName = FqName(packageFQN),
|
||||||
fileName = if (proto.hasFileEntry() && proto.fileEntry.hasName()) proto.fileEntry.name else "<unknown>"
|
fileName = fileName
|
||||||
)
|
)
|
||||||
signatureDeserializer = IdSignatureDeserializer(fileReader, fileSignature, interner)
|
signatureDeserializer = IdSignatureDeserializer(fileReader, fileSignature, interner)
|
||||||
typeDeserializer = TypeDeserializer(fileReader, signatureDeserializer)
|
|
||||||
|
typeDeserializer = TypeDeserializer(
|
||||||
|
storageManager = LockBasedStorageManager("file '$fileName', package '$packageFQN'"),
|
||||||
|
libraryFile = fileReader,
|
||||||
|
signatureDeserializer = signatureDeserializer
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeTo(output: MutableList<AbiDeclaration>) {
|
fun deserializeTo(output: MutableList<AbiDeclaration>) {
|
||||||
@@ -551,10 +561,22 @@ private class LibraryDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class TypeDeserializer(
|
private class TypeDeserializer(
|
||||||
|
storageManager: StorageManager,
|
||||||
private val libraryFile: IrLibraryFile,
|
private val libraryFile: IrLibraryFile,
|
||||||
private val signatureDeserializer: IdSignatureDeserializer
|
private val signatureDeserializer: IdSignatureDeserializer
|
||||||
) {
|
) {
|
||||||
private val typeIdToTypeCache = HashMap<Int, AbiType>()
|
/**
|
||||||
|
* Type Id -> [AbiType] cache.
|
||||||
|
*
|
||||||
|
* Implementation detail: The cache is backed by [CacheWithNotNullValues] instance provided by
|
||||||
|
* [LockBasedStorageManager.createCacheWithNotNullValues]. Unlike regular [java.util.Map] implementations
|
||||||
|
* that may throw an exception (preferably [java.util.ConcurrentModificationException]) if a mapping
|
||||||
|
* function in [java.util.Map.computeIfAbsent] attempts to modify the same map, or even may lead to
|
||||||
|
* 1-thread deadlocks (a real case with [java.util.concurrent.ConcurrentHashMap]), the cache based on
|
||||||
|
* [CacheWithNotNullValues] is always safe: It allows recursive calls of the mapping function to
|
||||||
|
* compute values for nested entities by design.
|
||||||
|
*/
|
||||||
|
private val typeIdToTypeCache = storageManager.createCacheWithNotNullValues<Int, AbiType>()
|
||||||
private val nonPublicTopLevelClassNames = HashSet<AbiQualifiedName>()
|
private val nonPublicTopLevelClassNames = HashSet<AbiQualifiedName>()
|
||||||
|
|
||||||
fun deserializeType(typeId: Int, typeParameterResolver: TypeParameterResolver): AbiType {
|
fun deserializeType(typeId: Int, typeParameterResolver: TypeParameterResolver): AbiType {
|
||||||
|
|||||||
Reference in New Issue
Block a user