[K/JS] Rework IR deserialization and lowering phases to consume less memory
This commit is contained in:
@@ -11,6 +11,7 @@ dependencies {
|
||||
api(project(":compiler:util"))
|
||||
implementation(project(":compiler:psi"))
|
||||
compileOnly(commonDependency("org.jetbrains.kotlin:kotlin-reflect")) { isTransitive = false }
|
||||
compileOnly(commonDependency("org.jetbrains.intellij.deps.fastutil:intellij-deps-fastutil"))
|
||||
|
||||
compileOnly(intellijCore())
|
||||
}
|
||||
|
||||
+3
-3
@@ -228,14 +228,14 @@ private fun StringBuilder.appendProjectDependencies(
|
||||
return
|
||||
}
|
||||
|
||||
val incomingDependencyIdToDependencies: MutableMap<ResolvedDependencyId, MutableCollection<ResolvedDependency>> = mutableMapOf()
|
||||
val incomingDependencyIdToDependencies: MutableMap<ResolvedDependencyId, MutableCollection<ResolvedDependency>> = hashMapOf()
|
||||
allModules.values.forEach { module ->
|
||||
module.requestedVersionsByIncomingDependencies.keys.forEach { incomingDependencyId ->
|
||||
incomingDependencyIdToDependencies.getOrPut(incomingDependencyId) { mutableListOf() } += module
|
||||
}
|
||||
}
|
||||
|
||||
val renderedModules: MutableSet<ResolvedDependencyId> = mutableSetOf()
|
||||
val renderedModules: MutableSet<ResolvedDependencyId> = hashSetOf()
|
||||
var everDependenciesOmitted = false
|
||||
|
||||
fun renderModules(modules: Collection<ResolvedDependency>, parentData: Data?) {
|
||||
@@ -346,7 +346,7 @@ private fun findPotentiallyConflictingOutgoingDependencies(
|
||||
)
|
||||
|
||||
// Reverse dependency index.
|
||||
val outgoingDependenciesIndex: MutableMap<ResolvedDependencyId, MutableList<OutgoingDependency>> = mutableMapOf()
|
||||
val outgoingDependenciesIndex: MutableMap<ResolvedDependencyId, MutableList<OutgoingDependency>> = hashMapOf()
|
||||
|
||||
allModules.values.forEach { module ->
|
||||
module.requestedVersionsByIncomingDependencies.forEach { (incomingDependencyId, requestedVersion) ->
|
||||
|
||||
+5
-5
@@ -88,10 +88,10 @@ open class UserVisibleIrModulesSupport(externalDependenciesLoader: ExternalDepen
|
||||
selectedVersion = ResolvedDependencyVersion.EMPTY,
|
||||
// Assumption: As we don't know for sure which modules the source code module depends on directly and which modules
|
||||
// it depends on transitively, so let's assume it depends on all modules directly.
|
||||
requestedVersionsByIncomingDependencies = mutableMapOf(
|
||||
requestedVersionsByIncomingDependencies = hashMapOf(
|
||||
ResolvedDependencyId.DEFAULT_SOURCE_CODE_MODULE_ID to ResolvedDependencyVersion.EMPTY
|
||||
),
|
||||
artifactPaths = mutableSetOf()
|
||||
artifactPaths = hashSetOf()
|
||||
)
|
||||
|
||||
val outgoingDependencyIds = deserializer.moduleDependencies.map { getUserVisibleModuleId(it) }
|
||||
@@ -108,7 +108,7 @@ open class UserVisibleIrModulesSupport(externalDependenciesLoader: ExternalDepen
|
||||
*/
|
||||
protected fun mergedModules(deserializers: Collection<IrModuleDeserializer>): MutableMap<ResolvedDependencyId, ResolvedDependency> {
|
||||
val externalDependencyModulesByNames: Map</* unique name */ String, ResolvedDependency> =
|
||||
mutableMapOf<String, ResolvedDependency>().apply {
|
||||
hashMapOf<String, ResolvedDependency>().apply {
|
||||
externalDependencyModules.forEach { externalDependency ->
|
||||
externalDependency.id.uniqueNames.forEach { uniqueName ->
|
||||
this[uniqueName] = externalDependency
|
||||
@@ -122,7 +122,7 @@ open class UserVisibleIrModulesSupport(externalDependenciesLoader: ExternalDepen
|
||||
// The build system may express a group of modules where one module is a library KLIB and one or more modules
|
||||
// are just C-interop KLIBs as a single module with multiple artifacts. We need to expand them so that every particular
|
||||
// module/artifact will be represented as an individual [ResolvedDependency] instance.
|
||||
val artifactPathsToOriginModules: MutableMap<ResolvedDependencyArtifactPath, ResolvedDependency> = mutableMapOf()
|
||||
val artifactPathsToOriginModules: MutableMap<ResolvedDependencyArtifactPath, ResolvedDependency> = hashMapOf()
|
||||
externalDependencyModules.forEach { originModule ->
|
||||
originModule.artifactPaths.forEach { artifactPath -> artifactPathsToOriginModules[artifactPath] = originModule }
|
||||
}
|
||||
@@ -180,7 +180,7 @@ open class UserVisibleIrModulesSupport(externalDependenciesLoader: ExternalDepen
|
||||
}
|
||||
}
|
||||
|
||||
return (externalDependencyModules + providedModules).associateByTo(mutableMapOf()) { it.id }
|
||||
return (externalDependencyModules + providedModules).associateByTo(hashMapOf()) { it.id }
|
||||
}
|
||||
|
||||
protected data class ModuleWithUninitializedDependencies(
|
||||
|
||||
+8
-7
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||
import org.jetbrains.kotlin.utils.filterIsInstanceAnd
|
||||
|
||||
class FakeOverrideChecker(
|
||||
private val irMangler: KotlinMangler.IrMangler,
|
||||
@@ -39,25 +40,25 @@ class FakeOverrideChecker(
|
||||
|
||||
val descriptorFakeOverrides = classDescriptor.unsubstitutedMemberScope
|
||||
.getDescriptorsFiltered(DescriptorKindFilter.CALLABLES)
|
||||
.asSequence()
|
||||
.filterIsInstance<CallableMemberDescriptor>()
|
||||
.filter { it.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE }
|
||||
.filterNot { it.visibility == DescriptorVisibilities.PRIVATE || it.visibility == DescriptorVisibilities.INVISIBLE_FAKE }
|
||||
|
||||
val descriptorSignatures = descriptorFakeOverrides
|
||||
.map { with(descriptorMangler) { it.signatureString(compatibleMode) } }
|
||||
.sorted()
|
||||
.toMutableList()
|
||||
.apply { sort() }
|
||||
|
||||
val irFakeOverrides = clazz.declarations
|
||||
val irFakeOverrides = clazz.declarations.asSequence()
|
||||
.filterIsInstance<IrOverridableMember>()
|
||||
.filter { it.isFakeOverride }
|
||||
|
||||
irFakeOverrides.forEach {
|
||||
checkOverriddenSymbols(it)
|
||||
}
|
||||
.onEach { checkOverriddenSymbols(it) }
|
||||
|
||||
val irSignatures = irFakeOverrides
|
||||
.map { with(irMangler) { it.signatureString(compatibleMode) } }
|
||||
.sorted()
|
||||
.toMutableList()
|
||||
.apply { sort() }
|
||||
|
||||
// We can't have equality here because dependency libraries could have
|
||||
// been compiled with -friend-modules.
|
||||
|
||||
+10
-6
@@ -27,14 +27,18 @@ abstract class BasicIrModuleDeserializer(
|
||||
override val klib: IrLibrary,
|
||||
override val strategyResolver: (String) -> DeserializationStrategy,
|
||||
libraryAbiVersion: KotlinAbiVersion,
|
||||
private val containsErrorCode: Boolean = false
|
||||
private val containsErrorCode: Boolean = false,
|
||||
private val shouldSaveDeserializationState: Boolean = true,
|
||||
) : IrModuleDeserializer(moduleDescriptor, libraryAbiVersion) {
|
||||
|
||||
private val fileToDeserializerMap = mutableMapOf<IrFile, IrFileDeserializer>()
|
||||
|
||||
private val moduleDeserializationState = ModuleDeserializationState()
|
||||
|
||||
protected val moduleReversedFileIndex = mutableMapOf<IdSignature, FileDeserializationState>()
|
||||
protected var fileDeserializationStates: List<FileDeserializationState> = emptyList()
|
||||
get() = if (!shouldSaveDeserializationState) error("File deserialization state are not cached inside the instance because `shouldSaveDeserializationState` was set as `false`") else field
|
||||
|
||||
protected val moduleReversedFileIndex = hashMapOf<IdSignature, FileDeserializationState>()
|
||||
|
||||
override val moduleDependencies by lazy {
|
||||
moduleDescriptor.allDependencyModules
|
||||
@@ -46,8 +50,6 @@ abstract class BasicIrModuleDeserializer(
|
||||
return fileToDeserializerMap.values.filterNot { strategyResolver(it.file.fileEntry.name).onDemand }
|
||||
}
|
||||
|
||||
protected lateinit var fileDeserializationStates: List<FileDeserializationState>
|
||||
|
||||
override fun init(delegate: IrModuleDeserializer) {
|
||||
val fileCount = klib.fileCount()
|
||||
|
||||
@@ -64,7 +66,9 @@ abstract class BasicIrModuleDeserializer(
|
||||
moduleFragment.files.add(file)
|
||||
}
|
||||
|
||||
this.fileDeserializationStates = fileDeserializationStates
|
||||
if (shouldSaveDeserializationState) {
|
||||
this.fileDeserializationStates = fileDeserializationStates
|
||||
}
|
||||
|
||||
fileToDeserializerMap.values.forEach { it.symbolDeserializer.deserializeExpectActualMapping() }
|
||||
}
|
||||
@@ -128,7 +132,7 @@ abstract class BasicIrModuleDeserializer(
|
||||
fileStrategy.needBodies,
|
||||
allowErrorNodes,
|
||||
fileStrategy.inlineBodies,
|
||||
moduleDeserializer
|
||||
moduleDeserializer,
|
||||
)
|
||||
|
||||
fileToDeserializerMap[file] = fileDeserializationState.fileDeserializer
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ abstract class GlobalDeclarationTable(
|
||||
) {
|
||||
val publicIdSignatureComputer = PublicIdSignatureComputer(mangler)
|
||||
|
||||
protected val table = mutableMapOf<IrDeclaration, IdSignature>()
|
||||
protected val table = hashMapOf<IrDeclaration, IdSignature>()
|
||||
|
||||
constructor(mangler: KotlinMangler.IrMangler) : this(mangler, IdSignatureClashTracker.DEFAULT_TRACKER)
|
||||
|
||||
@@ -53,7 +53,7 @@ abstract class GlobalDeclarationTable(
|
||||
}
|
||||
|
||||
open class DeclarationTable(globalTable: GlobalDeclarationTable) {
|
||||
protected val table = mutableMapOf<IrDeclaration, IdSignature>()
|
||||
protected val table = hashMapOf<IrDeclaration, IdSignature>()
|
||||
protected open val globalDeclarationTable: GlobalDeclarationTable = globalTable
|
||||
// TODO: we need to disentangle signature construction with declaration tables.
|
||||
open val signaturer: IdSignatureSerializer = IdSignatureSerializer(globalTable.publicIdSignatureComputer, this)
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ class ExpectActualTable(val expectDescriptorToSymbol: MutableMap<DeclarationDesc
|
||||
}
|
||||
|
||||
private fun IrDeclaration.recordRightHandSide(): Map<DeclarationDescriptor, IrSymbol> {
|
||||
val rightHandSide = mutableMapOf<DeclarationDescriptor, IrSymbol>()
|
||||
val rightHandSide = hashMapOf<DeclarationDescriptor, IrSymbol>()
|
||||
|
||||
this.acceptVoid(object : IrElementVisitorVoid {
|
||||
override fun visitElement(element: IrElement) {
|
||||
|
||||
+10
-7
@@ -5,9 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.serialization
|
||||
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
|
||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||
import org.jetbrains.kotlin.ir.util.IdSignature.FileSignature
|
||||
import org.jetbrains.kotlin.utils.newHashMapWithExpectedSize
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.AccessorIdSignature as ProtoAccessorIdSignature
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.CommonIdSignature as ProtoCommonIdSignature
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.CompositeSignature as ProtoCompositeSignature
|
||||
@@ -18,7 +18,8 @@ import org.jetbrains.kotlin.backend.common.serialization.proto.LocalSignature as
|
||||
|
||||
class IdSignatureDeserializer(
|
||||
private val libraryFile: IrLibraryFile,
|
||||
private val fileSignature: FileSignature?
|
||||
private val fileSignature: FileSignature?,
|
||||
private val internationService: IrInterningService
|
||||
) {
|
||||
|
||||
private fun loadSignatureProto(index: Int): ProtoIdSignature {
|
||||
@@ -35,8 +36,8 @@ class IdSignatureDeserializer(
|
||||
}
|
||||
|
||||
private fun deserializePublicIdSignature(proto: ProtoCommonIdSignature): IdSignature.CommonSignature {
|
||||
val pkg = libraryFile.deserializeFqName(proto.packageFqNameList)
|
||||
val cls = libraryFile.deserializeFqName(proto.declarationFqNameList)
|
||||
val pkg = internationService.string(libraryFile.deserializeFqName(proto.packageFqNameList))
|
||||
val cls = internationService.string(libraryFile.deserializeFqName(proto.declarationFqNameList))
|
||||
val memberId = if (proto.hasMemberUniqId()) proto.memberUniqId else null
|
||||
|
||||
return IdSignature.CommonSignature(pkg, cls, memberId, proto.flags)
|
||||
@@ -49,8 +50,9 @@ class IdSignatureDeserializer(
|
||||
val hash = proto.accessorHashId
|
||||
val mask = proto.flags
|
||||
|
||||
val declarationFqName = internationService.string("${propertySignature.declarationFqName}.$name")
|
||||
val accessorSignature =
|
||||
IdSignature.CommonSignature(propertySignature.packageFqName, "${propertySignature.declarationFqName}.$name", hash, mask)
|
||||
IdSignature.CommonSignature(propertySignature.packageFqName, declarationFqName, hash, mask)
|
||||
|
||||
return IdSignature.AccessorSignature(propertySignature, accessorSignature)
|
||||
}
|
||||
@@ -70,7 +72,7 @@ class IdSignatureDeserializer(
|
||||
}
|
||||
|
||||
private fun deserializeLocalIdSignature(proto: ProtoLocalSignature): IdSignature.LocalSignature {
|
||||
val localFqn = libraryFile.deserializeFqName(proto.localFqNameList)
|
||||
val localFqn = internationService.string(libraryFile.deserializeFqName(proto.localFqNameList))
|
||||
val localHash = if (proto.hasLocalHash()) proto.localHash else null
|
||||
val description = if (proto.hasDebugInfo()) libraryFile.debugInfo(proto.debugInfo) else null
|
||||
return IdSignature.LocalSignature(localFqn, localHash, description)
|
||||
@@ -93,6 +95,7 @@ class IdSignatureDeserializer(
|
||||
}
|
||||
|
||||
fun signatureToIndexMapping(): Map<IdSignature, Int> {
|
||||
return signatureCache.entries.associate { it.value to it.key }
|
||||
if (signatureCache.isEmpty()) return emptyMap()
|
||||
return signatureCache.entries.associateTo(newHashMapWithExpectedSize(signatureCache.size)) { it.value to it.key }
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -105,7 +105,7 @@ class CurrentModuleWithICDeserializer(
|
||||
icReaderFactory: (IrLibrary) -> IrModuleDeserializer) :
|
||||
IrModuleDeserializer(delegate.moduleDescriptor, KotlinAbiVersion.CURRENT) {
|
||||
|
||||
private val dirtyDeclarations = mutableMapOf<IdSignature, IrSymbol>()
|
||||
private val dirtyDeclarations = hashMapOf<IdSignature, IrSymbol>()
|
||||
private val icKlib = ICKotlinLibrary(icData)
|
||||
|
||||
private val icDeserializer: IrModuleDeserializer = icReaderFactory(icKlib)
|
||||
|
||||
+11
-17
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.*
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrBlock as ProtoBlock
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrBlockBody as ProtoBlockBody
|
||||
@@ -81,7 +82,7 @@ class IrBodyDeserializer(
|
||||
private val declarationDeserializer: IrDeclarationDeserializer
|
||||
) {
|
||||
|
||||
private val fileLoops = mutableMapOf<Int, IrLoop>()
|
||||
private val fileLoops = hashMapOf<Int, IrLoop>()
|
||||
|
||||
private fun deserializeLoopHeader(loopIndex: Int, loopBuilder: () -> IrLoop): IrLoop =
|
||||
fileLoops.getOrPut(loopIndex, loopBuilder)
|
||||
@@ -90,14 +91,7 @@ class IrBodyDeserializer(
|
||||
proto: ProtoBlockBody,
|
||||
start: Int, end: Int
|
||||
): IrBlockBody {
|
||||
|
||||
val statements = mutableListOf<IrStatement>()
|
||||
|
||||
val statementProtos = proto.statementList
|
||||
statementProtos.forEach {
|
||||
statements.add(deserializeStatement(it) as IrStatement)
|
||||
}
|
||||
|
||||
val statements = proto.statementList.memoryOptimizedMap { deserializeStatement(it) as IrStatement }
|
||||
return irFactory.createBlockBody(start, end, statements)
|
||||
}
|
||||
|
||||
@@ -163,14 +157,14 @@ class IrBodyDeserializer(
|
||||
|
||||
private fun deserializeMemberAccessCommon(access: IrMemberAccessExpression<*>, proto: ProtoMemberAccessCommon) {
|
||||
|
||||
proto.valueArgumentList.mapIndexed { i, arg ->
|
||||
proto.valueArgumentList.forEachIndexed { i, arg ->
|
||||
if (arg.hasExpression()) {
|
||||
val expr = deserializeExpression(arg.expression)
|
||||
access.putValueArgument(i, expr)
|
||||
}
|
||||
}
|
||||
|
||||
proto.typeArgumentList.mapIndexed { i, arg ->
|
||||
proto.typeArgumentList.forEachIndexed { i, arg ->
|
||||
access.putTypeArgument(i, declarationDeserializer.deserializeNullableIrType(arg))
|
||||
}
|
||||
|
||||
@@ -211,16 +205,16 @@ class IrBodyDeserializer(
|
||||
|
||||
val klass = constructorCall.symbol.owner.parentAsClass
|
||||
|
||||
val typeParameters = extractTypeParameters(klass)
|
||||
val typeParameters = extractTypeParameters(klass).ifEmpty {
|
||||
return IrSimpleTypeBuilder().apply { classifier = klass.symbol }.buildSimpleType()
|
||||
}
|
||||
|
||||
val typeArguments = ArrayList<IrTypeArgument>(typeParameters.size)
|
||||
val typeParameterSymbols = ArrayList<IrTypeParameterSymbol>(typeParameters.size)
|
||||
val rawType = with(IrSimpleTypeBuilder()) {
|
||||
arguments = typeParameters.run {
|
||||
mapTo(ArrayList(size)) {
|
||||
classifier = it.symbol
|
||||
buildTypeProjection()
|
||||
}
|
||||
arguments = typeParameters.memoryOptimizedMap {
|
||||
classifier = it.symbol
|
||||
buildTypeProjection()
|
||||
}
|
||||
classifier = klass.symbol
|
||||
buildSimpleType()
|
||||
|
||||
+40
-46
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.ir.types.impl.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.utils.*
|
||||
import kotlin.collections.set
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrAnonymousInit as ProtoAnonymousInit
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrClass as ProtoClass
|
||||
@@ -52,9 +53,9 @@ import org.jetbrains.kotlin.backend.common.serialization.proto.IrInlineClassRepr
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrLocalDelegatedProperty as ProtoLocalDelegatedProperty
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrMultiFieldValueClassRepresentation as ProtoIrMultiFieldValueClassRepresentation
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrProperty as ProtoProperty
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrSimpleTypeNullability as ProtoSimpleTypeNullablity
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrSimpleType as ProtoSimpleType
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrSimpleTypeLegacy as ProtoSimpleTypeLegacy
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrSimpleTypeNullability as ProtoSimpleTypeNullablity
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrStatement as ProtoStatement
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrType as ProtoType
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrTypeAbbreviation as ProtoTypeAbbreviation
|
||||
@@ -76,27 +77,27 @@ class IrDeclarationDeserializer(
|
||||
private val platformFakeOverrideClassFilter: FakeOverrideClassFilter,
|
||||
private val fakeOverrideBuilder: FakeOverrideBuilder,
|
||||
private val compatibilityMode: CompatibilityMode,
|
||||
private val partialLinkageEnabled: Boolean
|
||||
private val partialLinkageEnabled: Boolean,
|
||||
private val internationService: IrInterningService,
|
||||
) {
|
||||
|
||||
private val bodyDeserializer = IrBodyDeserializer(builtIns, allowErrorNodes, irFactory, libraryFile, this)
|
||||
|
||||
private fun deserializeString(index: Int): String {
|
||||
return libraryFile.string(index)
|
||||
}
|
||||
|
||||
private fun deserializeName(index: Int): Name {
|
||||
val name = libraryFile.string(index)
|
||||
return Name.guessByFirstCharacter(name)
|
||||
return internationService.name(Name.guessByFirstCharacter(deserializeString(index)))
|
||||
}
|
||||
|
||||
private val irTypeCache = mutableMapOf<Int, IrType>()
|
||||
|
||||
private fun loadTypeProto(index: Int): ProtoType {
|
||||
return libraryFile.type(index)
|
||||
}
|
||||
private val irTypeCache = hashMapOf<Int, IrType>()
|
||||
|
||||
fun deserializeNullableIrType(index: Int): IrType? = if (index == -1) null else deserializeIrType(index)
|
||||
|
||||
fun deserializeIrType(index: Int): IrType {
|
||||
return irTypeCache.getOrPut(index) {
|
||||
val typeData = loadTypeProto(index)
|
||||
val typeData = libraryFile.type(index)
|
||||
deserializeIrTypeData(typeData)
|
||||
}
|
||||
}
|
||||
@@ -110,9 +111,7 @@ class IrDeclarationDeserializer(
|
||||
}
|
||||
|
||||
internal fun deserializeAnnotations(annotations: List<ProtoConstructorCall>): List<IrConstructorCall> {
|
||||
return annotations.map {
|
||||
bodyDeserializer.deserializeAnnotation(it)
|
||||
}
|
||||
return annotations.memoryOptimizedMap { bodyDeserializer.deserializeAnnotation(it) }
|
||||
}
|
||||
|
||||
private fun deserializeSimpleTypeNullability(proto: ProtoSimpleTypeNullablity) = when (proto) {
|
||||
@@ -125,8 +124,9 @@ class IrDeclarationDeserializer(
|
||||
val symbol = deserializeIrSymbolAndRemap(proto.classifier)
|
||||
.checkSymbolType<IrClassifierSymbol>(fallbackSymbolKind = /* just the first possible option */ CLASS_SYMBOL)
|
||||
|
||||
val arguments = proto.argumentList.map { deserializeIrTypeArgument(it) }
|
||||
val arguments = proto.argumentList.memoryOptimizedMap { deserializeIrTypeArgument(it) }
|
||||
val annotations = deserializeAnnotations(proto.annotationList)
|
||||
val abbreviation = if (proto.hasAbbreviation()) deserializeTypeAbbreviation(proto.abbreviation) else null
|
||||
|
||||
return IrSimpleTypeImpl(
|
||||
null,
|
||||
@@ -134,7 +134,7 @@ class IrDeclarationDeserializer(
|
||||
deserializeSimpleTypeNullability(proto.nullability),
|
||||
arguments,
|
||||
annotations,
|
||||
if (proto.hasAbbreviation()) deserializeTypeAbbreviation(proto.abbreviation) else null
|
||||
abbreviation
|
||||
)
|
||||
}
|
||||
|
||||
@@ -142,8 +142,9 @@ class IrDeclarationDeserializer(
|
||||
val symbol = deserializeIrSymbolAndRemap(proto.classifier)
|
||||
.checkSymbolType<IrClassifierSymbol>(fallbackSymbolKind = /* just the first possible option */ CLASS_SYMBOL)
|
||||
|
||||
val arguments = proto.argumentList.map { deserializeIrTypeArgument(it) }
|
||||
val arguments = proto.argumentList.memoryOptimizedMap { deserializeIrTypeArgument(it) }
|
||||
val annotations = deserializeAnnotations(proto.annotationList)
|
||||
val abbreviation = if (proto.hasAbbreviation()) deserializeTypeAbbreviation(proto.abbreviation) else null
|
||||
|
||||
return IrSimpleTypeImpl(
|
||||
null,
|
||||
@@ -151,7 +152,7 @@ class IrDeclarationDeserializer(
|
||||
SimpleTypeNullability.fromHasQuestionMark(proto.hasQuestionMark),
|
||||
arguments,
|
||||
annotations,
|
||||
if (proto.hasAbbreviation()) deserializeTypeAbbreviation(proto.abbreviation) else null
|
||||
abbreviation
|
||||
)
|
||||
}
|
||||
|
||||
@@ -159,13 +160,19 @@ class IrDeclarationDeserializer(
|
||||
IrTypeAbbreviationImpl(
|
||||
deserializeIrSymbolAndRemap(proto.typeAlias).checkSymbolType(TYPEALIAS_SYMBOL),
|
||||
proto.hasQuestionMark,
|
||||
proto.argumentList.map { deserializeIrTypeArgument(it) },
|
||||
proto.argumentList.memoryOptimizedMap { deserializeIrTypeArgument(it) },
|
||||
deserializeAnnotations(proto.annotationList)
|
||||
)
|
||||
|
||||
private val SIMPLE_DYNAMIC_TYPE = IrDynamicTypeImpl(null, emptyList(), Variance.INVARIANT)
|
||||
|
||||
private fun deserializeDynamicType(proto: ProtoDynamicType): IrDynamicType {
|
||||
val annotations = deserializeAnnotations(proto.annotationList)
|
||||
return IrDynamicTypeImpl(null, annotations, Variance.INVARIANT)
|
||||
return if (proto.annotationCount == 0) {
|
||||
SIMPLE_DYNAMIC_TYPE
|
||||
} else {
|
||||
val annotations = deserializeAnnotations(proto.annotationList)
|
||||
IrDynamicTypeImpl(null, annotations, Variance.INVARIANT)
|
||||
}
|
||||
}
|
||||
|
||||
private fun deserializeErrorType(proto: ProtoErrorType): IrErrorType {
|
||||
@@ -205,7 +212,7 @@ class IrDeclarationDeserializer(
|
||||
}
|
||||
|
||||
// Delegating symbol maps to it's delegate only inside the declaration the symbol belongs to.
|
||||
private val delegatedSymbolMap = mutableMapOf<IrSymbol, IrSymbol>()
|
||||
private val delegatedSymbolMap = hashMapOf<IrSymbol, IrSymbol>()
|
||||
|
||||
internal fun deserializeIrSymbol(code: Long): IrSymbol {
|
||||
return symbolDeserializer.deserializeIrSymbol(code)
|
||||
@@ -367,7 +374,7 @@ class IrDeclarationDeserializer(
|
||||
}.usingParent {
|
||||
typeParameters = deserializeTypeParameters(proto.typeParameterList, true)
|
||||
|
||||
superTypes = proto.superTypeList.map { deserializeIrType(it) }
|
||||
superTypes = proto.superTypeList.memoryOptimizedMap { deserializeIrType(it) }
|
||||
|
||||
withExternalValue(isExternal) {
|
||||
val oldDeclarations = declarations.toSet()
|
||||
@@ -389,8 +396,8 @@ class IrDeclarationDeserializer(
|
||||
else -> computeMissingInlineClassRepresentationForCompatibility(this)
|
||||
}
|
||||
|
||||
// It has been desided not to deserialize the list of sealed subclasses because of KT-54028
|
||||
// sealedSubclasses = proto.sealedSubclassList.map { deserializeIrSymbol(it).checkSymbolType(CLASS_SYMBOL) }
|
||||
// It has been decided not to deserialize the list of sealed subclasses because of KT-54028
|
||||
// sealedSubclasses = proto.sealedSubclassList.memoryOptimizedMap { deserializeIrSymbol(it).checkSymbolType(CLASS_SYMBOL) }
|
||||
|
||||
fakeOverrideBuilder.enqueueClass(this, signature, compatibilityMode)
|
||||
}
|
||||
@@ -403,9 +410,9 @@ class IrDeclarationDeserializer(
|
||||
)
|
||||
|
||||
private fun deserializeMultiFieldValueClassRepresentation(proto: ProtoIrMultiFieldValueClassRepresentation): MultiFieldValueClassRepresentation<IrSimpleType> {
|
||||
val names = proto.underlyingPropertyNameList.map { deserializeName(it) }
|
||||
val types = proto.underlyingPropertyTypeList.map { deserializeIrType(it) as IrSimpleType }
|
||||
return MultiFieldValueClassRepresentation(names zip types)
|
||||
val names = proto.underlyingPropertyNameList.memoryOptimizedMap { deserializeName(it) }
|
||||
val types = proto.underlyingPropertyTypeList.memoryOptimizedMap { deserializeIrType(it) as IrSimpleType }
|
||||
return MultiFieldValueClassRepresentation(names memoryOptimizedZip types)
|
||||
}
|
||||
|
||||
private fun computeMissingInlineClassRepresentationForCompatibility(irClass: IrClass): InlineClassRepresentation<IrSimpleType> {
|
||||
@@ -447,30 +454,17 @@ class IrDeclarationDeserializer(
|
||||
|
||||
private fun deserializeTypeParameters(protos: List<ProtoTypeParameter>, isGlobal: Boolean): List<IrTypeParameter> {
|
||||
// NOTE: fun <C : MutableCollection<in T>, T : Any> Array<out T?>.filterNotNullTo(destination: C): C
|
||||
val result = ArrayList<IrTypeParameter>(protos.size)
|
||||
for (index in protos.indices) {
|
||||
val proto = protos[index]
|
||||
result.add(deserializeIrTypeParameter(proto, index, isGlobal))
|
||||
return protos.memoryOptimizedMapIndexed { index, proto ->
|
||||
deserializeIrTypeParameter(proto, index, isGlobal).apply {
|
||||
superTypes = proto.superTypeList.memoryOptimizedMap { deserializeIrType(it) }
|
||||
}
|
||||
}
|
||||
|
||||
for (i in protos.indices) {
|
||||
result[i].superTypes = protos[i].superTypeList.map { deserializeIrType(it) }
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun deserializeValueParameters(protos: List<ProtoValueParameter>): List<IrValueParameter> {
|
||||
val result = ArrayList<IrValueParameter>(protos.size)
|
||||
|
||||
for (i in protos.indices) {
|
||||
result.add(deserializeIrValueParameter(protos[i], i))
|
||||
}
|
||||
|
||||
return result
|
||||
return protos.memoryOptimizedMapIndexed { index, proto -> deserializeIrValueParameter(proto, index) }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* In `declarations-only` mode in case of private property/function with inferred anonymous private type like this
|
||||
* class C {
|
||||
@@ -609,7 +603,7 @@ class IrDeclarationDeserializer(
|
||||
flags.isFakeOverride
|
||||
)
|
||||
}.apply {
|
||||
overriddenSymbols = proto.overriddenList.map { deserializeIrSymbolAndRemap(it).checkSymbolType(FUNCTION_SYMBOL) }
|
||||
overriddenSymbols = proto.overriddenList.memoryOptimizedMap { deserializeIrSymbolAndRemap(it).checkSymbolType(FUNCTION_SYMBOL) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -74,6 +74,7 @@ class FileDeserializationState(
|
||||
::addIdSignature,
|
||||
linker::handleExpectActualMapping,
|
||||
symbolProcessor = linker.symbolProcessor,
|
||||
internationService = linker.internationService
|
||||
) { idSignature, symbolKind ->
|
||||
linker.deserializeOrReturnUnboundIrSymbolIfPartialLinkageEnabled(idSignature, symbolKind, moduleDeserializer)
|
||||
}
|
||||
@@ -91,7 +92,8 @@ class FileDeserializationState(
|
||||
linker.fakeOverrideBuilder.platformSpecificClassFilter,
|
||||
linker.fakeOverrideBuilder,
|
||||
compatibilityMode = moduleDeserializer.compatibilityMode,
|
||||
linker.partialLinkageSupport.isEnabled
|
||||
linker.partialLinkageSupport.isEnabled,
|
||||
internationService = linker.internationService
|
||||
)
|
||||
|
||||
val fileDeserializer = IrFileDeserializer(file, fileReader, fileProto, symbolDeserializer, declarationDeserializer)
|
||||
|
||||
+5
-5
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.library.impl.IrMemoryDeclarationWriter
|
||||
import org.jetbrains.kotlin.library.impl.IrMemoryStringWriter
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.utils.filterIsInstanceAnd
|
||||
import java.io.File
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.AccessorIdSignature as ProtoAccessorIdSignature
|
||||
import org.jetbrains.kotlin.backend.common.serialization.proto.Actual as ProtoActual
|
||||
@@ -125,7 +126,7 @@ open class IrFileSerializer(
|
||||
private val normalizeAbsolutePaths: Boolean = false,
|
||||
private val sourceBaseDirs: Collection<String>
|
||||
) {
|
||||
private val loopIndex = mutableMapOf<IrLoop, Int>()
|
||||
private val loopIndex = hashMapOf<IrLoop, Int>()
|
||||
private var currentLoopIndex = 0
|
||||
|
||||
// For every actual we keep a corresponding expects' uniqIds.
|
||||
@@ -134,10 +135,10 @@ open class IrFileSerializer(
|
||||
|
||||
// The same type can be used multiple times in a file
|
||||
// so use this index to store type data only once.
|
||||
private val protoTypeMap = mutableMapOf<IrTypeKey, Int>()
|
||||
private val protoTypeMap = hashMapOf<IrTypeKey, Int>()
|
||||
protected val protoTypeArray = arrayListOf<ProtoType>()
|
||||
|
||||
private val protoStringMap = mutableMapOf<String, Int>()
|
||||
private val protoStringMap = hashMapOf<String, Int>()
|
||||
protected val protoStringArray = arrayListOf<String>()
|
||||
|
||||
// The same signature could be used multiple times in a file
|
||||
@@ -1444,8 +1445,7 @@ open class IrFileSerializer(
|
||||
|
||||
// Make sure that all top level properties are initialized on library's load.
|
||||
file.declarations
|
||||
.filterIsInstance<IrProperty>()
|
||||
.filter { it.backingField?.initializer != null && keepOrderOfProperties(it) }
|
||||
.filterIsInstanceAnd<IrProperty> { it.backingField?.initializer != null && keepOrderOfProperties(it) }
|
||||
.forEach {
|
||||
val fieldSymbol = it.backingField?.symbol ?: error("Not found ID ${it.render()}")
|
||||
proto.addExplicitlyExportedToCompiler(serializeIrSymbol(fieldSymbol))
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.serialization
|
||||
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
|
||||
|
||||
/**
|
||||
* The interface provide an API for interning [String] and [Name] values
|
||||
* to save memory by eliminating duplicates of instances of those classes
|
||||
*/
|
||||
class IrInterningService {
|
||||
/**
|
||||
* We use here an open-addressing map, because it consumes at least twice lesser memory than with bucket-based implementation:
|
||||
* - Open-addressing (cost per entry): ref to key + ref to value
|
||||
* - Bucket-based (cost per entry): hash code + ref to key + ref to value + ref to the next node + class header with memory alignment
|
||||
*/
|
||||
private val strings by lazy { ObjectOpenHashSet<String>() }
|
||||
private val names by lazy { ObjectOpenHashSet<Name>() }
|
||||
|
||||
fun string(string: String): String {
|
||||
return strings.addOrGet(string)
|
||||
}
|
||||
|
||||
fun name(name: Name): Name {
|
||||
return names.addOrGet(name)
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
strings.clear()
|
||||
names.clear()
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -25,11 +25,12 @@ class IrSymbolDeserializer(
|
||||
val actuals: List<Actual>,
|
||||
val enqueueLocalTopLevelDeclaration: (IdSignature) -> Unit,
|
||||
val handleExpectActualMapping: (IdSignature, IrSymbol) -> IrSymbol,
|
||||
internationService: IrInterningService,
|
||||
val symbolProcessor: IrSymbolDeserializer.(IrSymbol, IdSignature) -> IrSymbol = { s, _ -> s },
|
||||
fileSignature: IdSignature.FileSignature = IdSignature.FileSignature(fileSymbol),
|
||||
val deserializePublicSymbol: (IdSignature, BinarySymbolData.SymbolKind) -> IrSymbol
|
||||
) {
|
||||
val deserializedSymbols: MutableMap<IdSignature, IrSymbol> = mutableMapOf()
|
||||
val deserializedSymbols: MutableMap<IdSignature, IrSymbol> = hashMapOf()
|
||||
|
||||
fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
|
||||
return deserializedSymbols.getOrPut(idSig) {
|
||||
@@ -84,7 +85,7 @@ class IrSymbolDeserializer(
|
||||
}
|
||||
}
|
||||
|
||||
val signatureDeserializer = IdSignatureDeserializer(libraryFile, fileSignature)
|
||||
val signatureDeserializer = IdSignatureDeserializer(libraryFile, fileSignature, internationService)
|
||||
|
||||
fun deserializeIdSignature(index: Int): IdSignature {
|
||||
return signatureDeserializer.deserializeIdSignature(index)
|
||||
|
||||
+15
-8
@@ -15,7 +15,10 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.builders.TranslationPluginContext
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.linkage.IrDeserializer
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
@@ -32,22 +35,23 @@ abstract class KotlinIrLinker(
|
||||
private val exportedDependencies: List<ModuleDescriptor>,
|
||||
val symbolProcessor: IrSymbolDeserializer.(IrSymbol, IdSignature) -> IrSymbol = { s, _ -> s },
|
||||
) : IrDeserializer, FileLocalAwareLinker {
|
||||
val internationService = IrInterningService()
|
||||
|
||||
// Kotlin-MPP related data. Consider some refactoring
|
||||
val expectIdSignatureToActualIdSignature = mutableMapOf<IdSignature, IdSignature>()
|
||||
val topLevelActualIdSignatureToModuleDeserializer = mutableMapOf<IdSignature, IrModuleDeserializer>()
|
||||
internal val expectSymbols = mutableMapOf<IdSignature, IrSymbol>()
|
||||
internal val actualSymbols = mutableMapOf<IdSignature, IrSymbol>()
|
||||
val topLevelActualIdSignatureToModuleDeserializer = hashMapOf<IdSignature, IrModuleDeserializer>()
|
||||
internal val expectSymbols = hashMapOf<IdSignature, IrSymbol>()
|
||||
internal val actualSymbols = hashMapOf<IdSignature, IrSymbol>()
|
||||
|
||||
val modulesWithReachableTopLevels = mutableSetOf<IrModuleDeserializer>()
|
||||
val modulesWithReachableTopLevels = hashSetOf<IrModuleDeserializer>()
|
||||
|
||||
protected val deserializersForModules = mutableMapOf<String, IrModuleDeserializer>()
|
||||
protected val deserializersForModules = hashMapOf<String, IrModuleDeserializer>()
|
||||
|
||||
abstract val fakeOverrideBuilder: FakeOverrideBuilder
|
||||
|
||||
abstract val translationPluginContext: TranslationPluginContext?
|
||||
|
||||
private val triedToDeserializeDeclarationForSymbol = mutableSetOf<IrSymbol>()
|
||||
private val triedToDeserializeDeclarationForSymbol = hashSetOf<IrSymbol>()
|
||||
|
||||
private lateinit var linkerExtensions: Collection<IrDeserializer.IrLinkerExtension>
|
||||
|
||||
@@ -204,6 +208,10 @@ abstract class KotlinIrLinker(
|
||||
deserializersForModules.values.forEach { it.init() }
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
internationService.clear()
|
||||
}
|
||||
|
||||
override fun postProcess(inOrAfterLinkageStep: Boolean) {
|
||||
// TODO: Expect/actual actualization should be fixed to cope with the situation when either expect or actual symbol is unbound.
|
||||
finalizeExpectActualLinker()
|
||||
@@ -224,7 +232,6 @@ abstract class KotlinIrLinker(
|
||||
deserializersForModules.values.asSequence().map { it.moduleFragment }
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: fix IrPluginContext to make it not produce additional external reference
|
||||
// symbolTable.noUnboundLeft("unbound after fake overrides:")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user