[IR SERIALIZATION] Get rid of UniqIdKey

This commit is contained in:
Roman Artemev
2019-08-14 16:24:03 +03:00
committed by romanart
parent aa313903cc
commit aa8b58e396
4 changed files with 49 additions and 65 deletions
@@ -25,7 +25,7 @@ abstract class DescriptorReferenceDeserializer(
val currentModule: ModuleDescriptor, val currentModule: ModuleDescriptor,
val mangler: KotlinMangler, val mangler: KotlinMangler,
val builtIns: IrBuiltIns, val builtIns: IrBuiltIns,
val resolvedForwardDeclarations: MutableMap<UniqIdKey, UniqIdKey> val resolvedForwardDeclarations: MutableMap<UniqId, UniqId>
) : DescriptorUniqIdAware { ) : DescriptorUniqIdAware {
protected open fun resolveSpecialDescriptor(fqn: FqName) = builtIns.builtIns.getBuiltInClassByFqName(fqn) protected open fun resolveSpecialDescriptor(fqn: FqName) = builtIns.builtIns.getBuiltInClassByFqName(fqn)
@@ -119,8 +119,8 @@ abstract class DescriptorReferenceDeserializer(
) { ) {
if (descriptor is DeserializedClassDescriptor) { if (descriptor is DeserializedClassDescriptor) {
val uniqId = UniqId(descriptor.getUniqId()!!, false) val uniqId = UniqId(descriptor.getUniqId()!!, false)
val newKey = UniqIdKey(null, uniqId) val newKey = uniqId
val oldKey = UniqIdKey(null, UniqId(protoIndex!!, false)) val oldKey = UniqId(protoIndex!!, false)
resolvedForwardDeclarations.put(oldKey, newKey) resolvedForwardDeclarations.put(oldKey, newKey)
} else { } else {
@@ -415,7 +415,7 @@ abstract class IrFileDeserializer(
} }
fun deserializeEnumConstructorCall( private fun deserializeEnumConstructorCall(
proto: ProtoEnumConstructorCall, proto: ProtoEnumConstructorCall,
start: Int, start: Int,
end: Int, end: Int,
@@ -1246,18 +1246,18 @@ abstract class IrFileDeserializer(
private val allKnownDeclarationOrigins = private val allKnownDeclarationOrigins =
IrDeclarationOrigin::class.nestedClasses.toList() + DeclarationFactory.FIELD_FOR_OUTER_THIS::class IrDeclarationOrigin::class.nestedClasses.toList() + DeclarationFactory.FIELD_FOR_OUTER_THIS::class
val declarationOriginIndex = private val declarationOriginIndex =
allKnownDeclarationOrigins.map { it.objectInstance as IrDeclarationOriginImpl }.associateBy { it.name } allKnownDeclarationOrigins.map { it.objectInstance as IrDeclarationOriginImpl }.associateBy { it.name }
fun deserializeIrDeclarationOrigin(proto: ProtoDeclarationOrigin): IrDeclarationOriginImpl { private fun deserializeIrDeclarationOrigin(proto: ProtoDeclarationOrigin): IrDeclarationOriginImpl {
val originName = deserializeString(proto.custom) val originName = deserializeString(proto.custom)
return declarationOriginIndex[originName] ?: object : IrDeclarationOriginImpl(originName) {} return declarationOriginIndex[originName] ?: object : IrDeclarationOriginImpl(originName) {}
} }
private val allKnownStatementOrigins = private val allKnownStatementOrigins =
IrStatementOrigin::class.nestedClasses.toList() IrStatementOrigin::class.nestedClasses.toList()
val statementOriginIndex = private val statementOriginIndex =
allKnownStatementOrigins.map { it.objectInstance as? IrStatementOriginImpl }.filterNotNull().associateBy { it.debugName } allKnownStatementOrigins.map { it.objectInstance as? IrStatementOriginImpl }.filterNotNull().associateBy { it.debugName }
fun deserializeIrStatementOrigin(proto: ProtoStatementOrigin): IrStatementOrigin { fun deserializeIrStatementOrigin(proto: ProtoStatementOrigin): IrStatementOrigin {
@@ -24,10 +24,8 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrLoopBase import org.jetbrains.kotlin.ir.expressions.impl.IrLoopBase
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.impl.* import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl
import org.jetbrains.kotlin.ir.util.IrDeserializer import org.jetbrains.kotlin.ir.util.IrDeserializer
@@ -63,33 +61,33 @@ abstract class KotlinIrLinker(
sealed class DeserializationState { sealed class DeserializationState {
val deserializedSymbols = mutableMapOf<UniqIdKey, IrSymbol>() val deserializedSymbols = mutableMapOf<UniqId, IrSymbol>()
val reachableTopLevels = mutableSetOf<UniqIdKey>() val reachableTopLevels = mutableSetOf<UniqId>()
val deserializedTopLevels = mutableSetOf<UniqIdKey>() val deserializedTopLevels = mutableSetOf<UniqId>()
operator fun contains(key: UniqIdKey) = key in deserializedSymbols operator fun contains(key: UniqId) = key in deserializedSymbols
operator fun get(key: UniqIdKey): IrSymbol = deserializedSymbols[key] ?: error("jfsdhsdfhksjdhfkjshdk") operator fun get(key: UniqId): IrSymbol = deserializedSymbols[key] ?: error("jfsdhsdfhksjdhfkjshdk")
abstract fun addUniqID(key: UniqIdKey) abstract fun addUniqID(key: UniqId)
protected open fun peekReachableKey(): UniqIdKey? = reachableTopLevels.firstOrNull() protected open fun peekReachableKey(): UniqId? = reachableTopLevels.firstOrNull()
class ModuleDeserializationState(val module: IrModuleDeserializer): DeserializationState() { class ModuleDeserializationState(val module: IrModuleDeserializer): DeserializationState() {
override fun addUniqID(key: UniqIdKey) { override fun addUniqID(key: UniqId) {
module.addModuleReachableTopLevel(key) module.addModuleReachableTopLevel(key)
} }
} }
class SimpleDeserializationState: DeserializationState() { class SimpleDeserializationState: DeserializationState() {
override fun addUniqID(key: UniqIdKey) { override fun addUniqID(key: UniqId) {
reachableTopLevels.add(key) reachableTopLevels.add(key)
} }
override fun peekReachableKey(): UniqIdKey { override fun peekReachableKey(): UniqId {
return reachableTopLevels.firstOrNull() ?: error("Expecting non-empty set") return reachableTopLevels.firstOrNull() ?: error("Expecting non-empty set")
} }
} }
fun processPendingDeclaration(processor: (UniqIdKey) -> Unit) { fun processPendingDeclaration(processor: (UniqId) -> Unit) {
do { do {
val reachableKey = peekReachableKey() ?: return val reachableKey = peekReachableKey() ?: return
@@ -114,7 +112,7 @@ abstract class KotlinIrLinker(
//TODO: This is Native specific. Eliminate me. //TODO: This is Native specific. Eliminate me.
private val forwardDeclarations = mutableSetOf<IrSymbol>() private val forwardDeclarations = mutableSetOf<IrSymbol>()
val resolvedForwardDeclarations = mutableMapOf<UniqIdKey, UniqIdKey>() val resolvedForwardDeclarations = mutableMapOf<UniqId, UniqId>()
protected val deserializersForModules = mutableMapOf<ModuleDescriptor, IrModuleDeserializer>() protected val deserializersForModules = mutableMapOf<ModuleDescriptor, IrModuleDeserializer>()
@@ -127,10 +125,10 @@ abstract class KotlinIrLinker(
val fileToDeserializerMap = mutableMapOf<IrFile, IrDeserializerForFile>() val fileToDeserializerMap = mutableMapOf<IrFile, IrDeserializerForFile>()
protected val moduleResolvedForwardDeclarations = mutableMapOf<UniqIdKey, UniqIdKey>() protected val moduleResolvedForwardDeclarations = mutableMapOf<UniqId, UniqId>()
private val moduleDeserializationState = DeserializationState.ModuleDeserializationState(this) private val moduleDeserializationState = DeserializationState.ModuleDeserializationState(this)
private val moduleReversedFileIndex = mutableMapOf<UniqIdKey, IrDeserializerForFile>() private val moduleReversedFileIndex = mutableMapOf<UniqId, IrDeserializerForFile>()
private val moduleDependencies = mutableListOf<IrModuleDeserializer>() private val moduleDependencies = mutableListOf<IrModuleDeserializer>()
// This is a heavy initializer // This is a heavy initializer
@@ -149,16 +147,16 @@ abstract class KotlinIrLinker(
private val deserializeBodies: Boolean = !onlyHeaders private val deserializeBodies: Boolean = !onlyHeaders
private val fileLocalResolvedForwardDeclarations = mutableMapOf<UniqIdKey, UniqIdKey>() private val fileLocalResolvedForwardDeclarations = mutableMapOf<UniqId, UniqId>()
val fileLocalDeserializationState = DeserializationState.SimpleDeserializationState() val fileLocalDeserializationState = DeserializationState.SimpleDeserializationState()
fun deserializeDeclaration(key: UniqIdKey): IrDeclaration { fun deserializeDeclaration(key: UniqId): IrDeclaration {
return deserializeDeclaration(loadTopLevelDeclarationProto(key), file) return deserializeDeclaration(loadTopLevelDeclarationProto(key), file)
} }
private fun loadTopLevelDeclarationProto(uniqIdKey: UniqIdKey): ProtoDeclaration { private fun loadTopLevelDeclarationProto(uniqId: UniqId): ProtoDeclaration {
val stream = reader(moduleDescriptor, fileIndex, uniqIdKey.uniqId).codedInputStream val stream = reader(moduleDescriptor, fileIndex, uniqId).codedInputStream
return ProtoDeclaration.parseFrom(stream, newInstance()) return ProtoDeclaration.parseFrom(stream, newInstance())
} }
@@ -276,26 +274,26 @@ abstract class KotlinIrLinker(
} }
} }
private fun isGlobalUniqID(uniqIdKey: UniqIdKey): Boolean { private fun isGlobalUniqID(uniqId: UniqId): Boolean {
return uniqIdKey in globalDeserializationState || return uniqId in globalDeserializationState ||
descriptorReferenceDeserializer.checkIfSpecialDescriptorId(uniqIdKey.uniqId.index) descriptorReferenceDeserializer.checkIfSpecialDescriptorId(uniqId.index)
} }
private fun getModuleForTopLevelId(key: UniqIdKey): IrModuleDeserializer { private fun getModuleForTopLevelId(key: UniqId): IrModuleDeserializer {
if (key in moduleReversedFileIndex) return this@IrModuleDeserializer if (key in moduleReversedFileIndex) return this@IrModuleDeserializer
return moduleDependencies.firstOrNull { key in it.moduleReversedFileIndex } ?: return moduleDependencies.firstOrNull { key in it.moduleReversedFileIndex } ?:
error("Deserializer for declaration $key is not found") error("Deserializer for declaration $key is not found")
} }
private fun getStateForID(key: UniqIdKey): DeserializationState { private fun getStateForID(key: UniqId): DeserializationState {
if (key.uniqId.isLocal) return fileLocalDeserializationState if (key.isLocal) return fileLocalDeserializationState
if (isGlobalUniqID(key)) return globalDeserializationState if (isGlobalUniqID(key)) return globalDeserializationState
return getModuleForTopLevelId(key).moduleDeserializationState return getModuleForTopLevelId(key).moduleDeserializationState
} }
private fun deserializeIrSymbolData(proto: ProtoSymbolData): IrSymbol { private fun deserializeIrSymbolData(proto: ProtoSymbolData): IrSymbol {
val key = proto.uniqId.uniqIdKey(moduleDescriptor) val key = proto.uniqId.uniqId()
val topLevelKey = proto.topLevelUniqId.uniqIdKey(moduleDescriptor) val topLevelKey = proto.topLevelUniqId.uniqId()
val topLevelDeserializationState = getStateForID(topLevelKey) val topLevelDeserializationState = getStateForID(topLevelKey)
@@ -306,7 +304,7 @@ abstract class KotlinIrLinker(
// If topLevel declaration is module-public and current declaration in not (e.g. value parameter) // If topLevel declaration is module-public and current declaration in not (e.g. value parameter)
// they should be proccesed via different tables // they should be proccesed via different tables
val deserializationState = val deserializationState =
if (topLevelKey.uniqId.isLocal xor key.uniqId.isLocal) getStateForID(key) else topLevelDeserializationState if (topLevelKey.isLocal xor key.isLocal) getStateForID(key) else topLevelDeserializationState
val symbol = deserializationState.deserializedSymbols.getOrPut(key) { val symbol = deserializationState.deserializedSymbols.getOrPut(key) {
val descriptor = if (proto.hasDescriptorReference()) { val descriptor = if (proto.hasDescriptorReference()) {
@@ -391,7 +389,7 @@ abstract class KotlinIrLinker(
} }
} }
fun deserializeFileTopLevelDeclaration(key: UniqIdKey) { fun deserializeFileTopLevelDeclaration(key: UniqId) {
fileLocalDeserializationState.addUniqID(key) fileLocalDeserializationState.addUniqID(key)
@@ -421,9 +419,9 @@ abstract class KotlinIrLinker(
fileToDeserializerMap[file] = fileDeserializer fileToDeserializerMap[file] = fileDeserializer
fileProto.declarationIdList.forEach { fileProto.declarationIdList.forEach {
val uniqIdKey = it.uniqIdKey(moduleDescriptor) val uniqId = it.uniqId()
assert(uniqIdKey.uniqId.isPublic) assert(uniqId.isPublic)
moduleReversedFileIndex.getOrPut(uniqIdKey) { fileDeserializer } moduleReversedFileIndex.getOrPut(uniqId) { fileDeserializer }
} }
when (deserializationStrategy) { when (deserializationStrategy) {
@@ -431,20 +429,20 @@ abstract class KotlinIrLinker(
fileProto.explicitlyExportedToCompilerList.forEach { fileProto.explicitlyExportedToCompilerList.forEach {
val symbolProto = fileDeserializer.loadSymbolData(it.index) val symbolProto = fileDeserializer.loadSymbolData(it.index)
val topLevelUniqId = symbolProto.topLevelUniqId val topLevelUniqId = symbolProto.topLevelUniqId
val uniqIdKey = topLevelUniqId.uniqIdKey (moduleDescriptor) val uniqId = topLevelUniqId.uniqId()
assert(uniqIdKey.uniqId.isPublic) assert(uniqId.isPublic)
// if (topLevelUniqId.isLocal) { // if (topLevelUniqId.isLocal) {
// fileDeserializer.fileLocalDeserializationState.addUniqID(uniqIdKey) // fileDeserializer.fileLocalDeserializationState.addUniqID(uniqId)
// } else { // } else {
moduleDeserializationState.addUniqID(uniqIdKey) moduleDeserializationState.addUniqID(uniqId)
// } // }
} }
} }
DeserializationStrategy.ALL -> { DeserializationStrategy.ALL -> {
fileProto.declarationIdList.forEach { fileProto.declarationIdList.forEach {
val uniqIdKey = it.uniqIdKey(moduleDescriptor) val uniqId = it.uniqId()
assert(uniqIdKey.uniqId.isPublic) assert(uniqId.isPublic)
moduleDeserializationState.addUniqID(uniqIdKey) moduleDeserializationState.addUniqID(uniqId)
} }
} }
else -> error("Unexpected deserialization strategy") else -> error("Unexpected deserialization strategy")
@@ -478,7 +476,7 @@ abstract class KotlinIrLinker(
} }
} }
fun addModuleReachableTopLevel(topLevelKey: UniqIdKey) { fun addModuleReachableTopLevel(topLevelKey: UniqId) {
moduleDeserializationState.reachableTopLevels.add(topLevelKey) moduleDeserializationState.reachableTopLevels.add(topLevelKey)
modulesWithReachableTopLevels.add(this) modulesWithReachableTopLevels.add(this)
} }
@@ -492,7 +490,7 @@ abstract class KotlinIrLinker(
var currentIndex = firstKnownBuiltinsIndex var currentIndex = firstKnownBuiltinsIndex
val globalDeserializedSymbols = globalDeserializationState.deserializedSymbols val globalDeserializedSymbols = globalDeserializationState.deserializedSymbols
builtIns.knownBuiltins.forEach { builtIns.knownBuiltins.forEach {
globalDeserializedSymbols[UniqIdKey(null, UniqId(currentIndex, isLocal = false))] = it globalDeserializedSymbols[UniqId(currentIndex, isLocal = false)] = it
assert(symbolTable.referenceSimpleFunction(it.descriptor) == it) assert(symbolTable.referenceSimpleFunction(it.descriptor) == it)
currentIndex++ currentIndex++
} }
@@ -538,9 +536,8 @@ abstract class KotlinIrLinker(
} }
val descriptorUniqId = topLevelDescriptor.getUniqId() val descriptorUniqId = topLevelDescriptor.getUniqId()
?: error("could not get descriptor uniq id for $topLevelDescriptor") ?: error("Could not get descriptor uniq id for $topLevelDescriptor")
val uniqId = UniqId(descriptorUniqId, isLocal = false) val topLevelKey = UniqId(descriptorUniqId, isLocal = false)
val topLevelKey = UniqIdKey(topLevelDescriptor.module, uniqId)
val moduleOfOrigin = topLevelDescriptor.module val moduleOfOrigin = topLevelDescriptor.module
@@ -20,17 +20,6 @@ data class UniqId(
val isPublic: Boolean get() = !isLocal val isPublic: Boolean get() = !isLocal
} }
// isLocal=true in UniqId is good while we dealing with a single current module.
// To disambiguate module local declarations of different modules we use UniqIdKey.
// It has moduleDescriptor specified for isLocal=true uniqIds.
// TODO: make sure UniqId is really uniq for any global declaration
data class UniqIdKey private constructor(val uniqId: UniqId, val moduleDescriptor: ModuleDescriptor?) {
constructor(moduleDescriptor: ModuleDescriptor?, uniqId: UniqId)
: this(uniqId, if (uniqId.isLocal) moduleDescriptor!! else null)
}
fun protoUniqId(uniqId: UniqId): ProtoUniqId = fun protoUniqId(uniqId: UniqId): ProtoUniqId =
ProtoUniqId.newBuilder() ProtoUniqId.newBuilder()
.setIndex(uniqId.index) .setIndex(uniqId.index)
@@ -38,8 +27,6 @@ fun protoUniqId(uniqId: UniqId): ProtoUniqId =
.build() .build()
fun ProtoUniqId.uniqId(): UniqId = UniqId(this.index, this.isLocal) fun ProtoUniqId.uniqId(): UniqId = UniqId(this.index, this.isLocal)
fun ProtoUniqId.uniqIdKey(moduleDescriptor: ModuleDescriptor) =
UniqIdKey(moduleDescriptor, this.uniqId())
fun <T, M : GeneratedMessageLite.ExtendableMessage<M>> M.tryGetExtension(extension: GeneratedMessageLite.GeneratedExtension<M, T>) = fun <T, M : GeneratedMessageLite.ExtendableMessage<M>> M.tryGetExtension(extension: GeneratedMessageLite.GeneratedExtension<M, T>) =
if (this.hasExtension(extension)) this.getExtension<T>(extension) else null if (this.hasExtension(extension)) this.getExtension<T>(extension) else null