JVM_IR: use ConcurrentHashMap

Replace mutable maps and sets accessed from by-file lowerings with
ConcurrentHashMap, so that lowerings can operate on them in parallel.
This commit is contained in:
Georgy Bronnikov
2021-01-13 16:41:09 +03:00
parent 23da2bde67
commit 4e9bedc2fc
9 changed files with 34 additions and 27 deletions
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.backend.common
import org.jetbrains.kotlin.ir.declarations.*
import java.util.concurrent.ConcurrentHashMap
import kotlin.reflect.KMutableProperty0
import kotlin.reflect.KProperty
@@ -47,7 +48,7 @@ open class DefaultMapping : Mapping {
override val reflectedNameAccessor: Mapping.Delegate<IrClass, IrSimpleFunction> = newMapping()
protected open fun <K : IrDeclaration, V> newMapping() = object : Mapping.Delegate<K, V>() {
private val map: MutableMap<K, V> = mutableMapOf()
private val map: MutableMap<K, V> = ConcurrentHashMap()
override operator fun get(key: K): V? {
return map[key]
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.psi2ir.PsiErrorBuilder
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.org.objectweb.asm.Type
import java.util.concurrent.ConcurrentHashMap
class JvmBackendContext(
val state: GenerationState,
@@ -55,7 +56,7 @@ class JvmBackendContext(
val classNameOverride: MutableMap<IrClass, JvmClassName>
get() = generatorExtensions.classNameOverride
override val extractedLocalClasses: MutableSet<IrClass> = hashSetOf()
override val extractedLocalClasses: MutableSet<IrClass> = ConcurrentHashMap.newKeySet()
override val irFactory: IrFactory = IrFactoryImpl
@@ -78,7 +79,7 @@ class JvmBackendContext(
val irIntrinsics by lazy { IrIntrinsicMethods(irBuiltIns, ir.symbols) }
private val localClassType = mutableMapOf<IrAttributeContainer, Type>()
private val localClassType = ConcurrentHashMap<IrAttributeContainer, Type>()
internal fun getLocalClassType(container: IrAttributeContainer): Type? =
localClassType[container.attributeOwnerId]
@@ -87,18 +88,18 @@ class JvmBackendContext(
localClassType[container.attributeOwnerId] = value
}
internal val isEnclosedInConstructor = mutableSetOf<IrAttributeContainer>()
internal val isEnclosedInConstructor = ConcurrentHashMap.newKeySet<IrAttributeContainer>()
internal val classCodegens = mutableMapOf<IrClass, ClassCodegen>()
val localDelegatedProperties = mutableMapOf<IrAttributeContainer, List<IrLocalDelegatedPropertySymbol>>()
val localDelegatedProperties = ConcurrentHashMap<IrAttributeContainer, List<IrLocalDelegatedPropertySymbol>>()
internal val multifileFacadesToAdd = mutableMapOf<JvmClassName, MutableList<IrClass>>()
val multifileFacadeForPart = mutableMapOf<IrClass, JvmClassName>()
internal val multifileFacadeClassForPart = mutableMapOf<IrClass, IrClass>()
internal val multifileFacadeMemberToPartMember = mutableMapOf<IrSimpleFunction, IrSimpleFunction>()
internal val hiddenConstructors = mutableMapOf<IrConstructor, IrConstructor>()
internal val hiddenConstructors = ConcurrentHashMap<IrConstructor, IrConstructor>()
internal val collectionStubComputer = CollectionStubComputer(this)
@@ -112,19 +113,19 @@ class JvmBackendContext(
overridesWithoutStubs.getOrElse(function) { function.overriddenSymbols }
internal val bridgeLoweringCache = BridgeLowering.BridgeLoweringCache(this)
internal val functionsWithSpecialBridges: MutableSet<IrFunction> = HashSet()
internal val functionsWithSpecialBridges: MutableSet<IrFunction> = ConcurrentHashMap.newKeySet()
override var inVerbosePhase: Boolean = false
override var inVerbosePhase: Boolean = false // TODO: needs parallelizing
override val configuration get() = state.configuration
override val internalPackageFqn = FqName("kotlin.jvm")
val suspendLambdaToOriginalFunctionMap = mutableMapOf<IrFunctionReference, IrFunction>()
val suspendFunctionOriginalToView = mutableMapOf<IrFunction, IrFunction>()
val suspendLambdaToOriginalFunctionMap = ConcurrentHashMap<IrFunctionReference, IrFunction>()
val suspendFunctionOriginalToView = ConcurrentHashMap<IrFunction, IrFunction>()
val fakeContinuation: IrExpression = createFakeContinuation(this)
val staticDefaultStubs = mutableMapOf<IrSimpleFunctionSymbol, IrSimpleFunction>()
val staticDefaultStubs = ConcurrentHashMap<IrSimpleFunctionSymbol, IrSimpleFunction>()
val inlineClassReplacements = MemoizedInlineClassReplacements(state.functionsWithInlineClassReturnTypesMangled, irFactory, this)
@@ -30,19 +30,20 @@ import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
import java.util.concurrent.ConcurrentHashMap
class JvmCachedDeclarations(
private val context: JvmBackendContext,
private val languageVersionSettings: LanguageVersionSettings
) {
private val singletonFieldDeclarations = HashMap<IrSymbolOwner, IrField>()
private val interfaceCompanionFieldDeclarations = HashMap<IrSymbolOwner, IrField>()
private val staticBackingFields = HashMap<IrProperty, IrField>()
private val singletonFieldDeclarations = ConcurrentHashMap<IrSymbolOwner, IrField>()
private val interfaceCompanionFieldDeclarations = ConcurrentHashMap<IrSymbolOwner, IrField>()
private val staticBackingFields = ConcurrentHashMap<IrProperty, IrField>()
private val defaultImplsMethods = HashMap<IrSimpleFunction, IrSimpleFunction>()
private val defaultImplsClasses = HashMap<IrClass, IrClass>()
private val defaultImplsRedirections = HashMap<IrSimpleFunction, IrSimpleFunction>()
private val defaultImplsOriginalMethods = HashMap<IrSimpleFunction, IrSimpleFunction>()
private val defaultImplsMethods = ConcurrentHashMap<IrSimpleFunction, IrSimpleFunction>()
private val defaultImplsClasses = ConcurrentHashMap<IrClass, IrClass>()
private val defaultImplsRedirections = ConcurrentHashMap<IrSimpleFunction, IrSimpleFunction>()
private val defaultImplsOriginalMethods = ConcurrentHashMap<IrSimpleFunction, IrSimpleFunction>()
fun getFieldForEnumEntry(enumEntry: IrEnumEntry): IrField =
singletonFieldDeclarations.getOrPut(enumEntry) {
@@ -124,7 +124,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
private fun IrSimpleFunction.isInvisibleInMultifilePart(): Boolean =
name.asString() != "<clinit>" &&
(parent as? IrClass)?.attributeOwnerId in context.multifileFacadeForPart &&
(parent as? IrClass)?.attributeOwnerId in context.multifileFacadeForPart.keys &&
(DescriptorVisibilities.isPrivate(suspendFunctionOriginal().visibility) ||
originalForDefaultAdapter?.isInvisibleInMultifilePart() == true)
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.Method
import java.util.concurrent.ConcurrentHashMap
/*
* Generate bridge methods to fix virtual dispatch after type erasure and to adapt Kotlin collections to
@@ -595,7 +596,7 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
// It might benefit performance, but can lead to confusing behavior if some declarations are changed along the way.
// For example, adding an override for a declaration whose signature is already cached can result in incorrect signature
// if its return type is a primitive type, and the new override's return type is an object type.
private val signatureCache = hashMapOf<IrFunctionSymbol, Method>()
private val signatureCache = ConcurrentHashMap<IrFunctionSymbol, Method>()
fun computeJvmMethod(function: IrFunction): Method =
signatureCache.getOrPut(function.symbol) { context.methodSignatureMapper.mapAsmMethod(function) }
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
import org.jetbrains.kotlin.utils.addToStdlib.cast
import java.util.concurrent.ConcurrentHashMap
internal val collectionStubMethodLowering = makeIrFilePhase(
::CollectionStubMethodLowering,
@@ -469,7 +470,7 @@ internal class CollectionStubComputer(val context: JvmBackendContext) {
}
}
private val stubsCache = mutableMapOf<IrClass, List<StubsForCollectionClass>>()
private val stubsCache = ConcurrentHashMap<IrClass, List<StubsForCollectionClass>>()
fun stubsForCollectionClasses(irClass: IrClass): List<StubsForCollectionClass> =
stubsCache.getOrPut(irClass) {
@@ -23,11 +23,12 @@ import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
import org.jetbrains.kotlin.name.Name
import java.util.concurrent.ConcurrentHashMap
class JvmInnerClassesSupport(private val irFactory: IrFactory) : InnerClassesSupport {
private val outerThisDeclarations = HashMap<IrClass, IrField>()
private val innerClassConstructors = HashMap<IrConstructor, IrConstructor>()
private val originalInnerClassPrimaryConstructorByClass = HashMap<IrClass, IrConstructor>()
private val outerThisDeclarations = ConcurrentHashMap<IrClass, IrField>()
private val innerClassConstructors = ConcurrentHashMap<IrConstructor, IrConstructor>()
private val originalInnerClassPrimaryConstructorByClass = ConcurrentHashMap<IrClass, IrConstructor>()
override fun getOuterThisField(innerClass: IrClass): IrField =
outerThisDeclarations.getOrPut(innerClass) {
@@ -217,7 +217,7 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
private val IrConstructor.isOrShouldBeHidden: Boolean
get() {
if (this in context.hiddenConstructors)
if (this in context.hiddenConstructors.keys)
return true
if (origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER ||
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.util.concurrent.ConcurrentHashMap
/**
* Keeps track of replacement functions and inline class box/unbox functions.
@@ -45,9 +46,9 @@ class MemoizedInlineClassReplacements(
private val context: JvmBackendContext
) {
private val storageManager = LockBasedStorageManager("inline-class-replacements")
private val propertyMap = mutableMapOf<IrPropertySymbol, IrProperty>()
private val propertyMap = ConcurrentHashMap<IrPropertySymbol, IrProperty>()
internal val originalFunctionForStaticReplacement: MutableMap<IrFunction, IrFunction> = HashMap()
internal val originalFunctionForStaticReplacement: MutableMap<IrFunction, IrFunction> = ConcurrentHashMap()
/**
* Get a replacement for a function or a constructor.