[K/N][IR][codegen] Use LazyIr for cached libraries

It's not that simple because we still need inline functions bodies
and classes fields which aren't present in Lazy IR. To overcome this,
save additional binary info for a cached library and then use it when needed
This commit is contained in:
Igor Chevdar
2021-08-24 21:14:52 +05:00
parent f865238062
commit 0cece79856
31 changed files with 1042 additions and 140 deletions
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.DeserializableClass
import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.ir.util.isObject
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
@@ -79,7 +80,8 @@ class IrLazyClass(
private fun shouldBuildStub(descriptor: DeclarationDescriptor): Boolean =
descriptor !is DeclarationDescriptorWithVisibility ||
!DescriptorVisibilities.isPrivate(descriptor.visibility)
!DescriptorVisibilities.isPrivate(descriptor.visibility) ||
isObject && descriptor is ClassConstructorDescriptor
override var typeParameters: List<IrTypeParameter> by lazyVar(stubGenerator.lock) {
descriptor.declaredTypeParameters.mapTo(arrayListOf()) {
@@ -7,11 +7,15 @@ package org.jetbrains.kotlin.ir.declarations.lazy
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.TypeTranslator
@@ -20,6 +24,35 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
@OptIn(ObsoleteDescriptorBasedAPI::class)
class IrLazyValueParameter(
override val startOffset: Int,
override val endOffset: Int,
override var origin: IrDeclarationOrigin,
override val symbol: IrValueParameterSymbol,
override val descriptor: ValueParameterDescriptor,
override val name: Name,
override val index: Int,
override var type: IrType,
override var varargElementType: IrType?,
override val isCrossinline: Boolean,
override val isNoinline: Boolean,
override val isHidden: Boolean,
override val isAssignable: Boolean,
override val stubGenerator: DeclarationStubGenerator,
override val typeTranslator: TypeTranslator,
) : IrValueParameter(), IrLazyDeclarationBase {
override lateinit var parent: IrDeclarationParent
override var defaultValue: IrExpressionBody? = null
override var annotations: List<IrConstructorCall> by createLazyAnnotations()
init {
symbol.bind(this)
}
}
@OptIn(ObsoleteDescriptorBasedAPI::class)
class IrLazyConstructor(
override val startOffset: Int,
@@ -5,10 +5,7 @@
package org.jetbrains.kotlin.ir.declarations.lazy
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrLock
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
@@ -32,6 +29,16 @@ class IrLazySymbolTable(private val originalTable: SymbolTable) : ReferenceSymbo
}
}
override fun referenceTypeAlias(descriptor: TypeAliasDescriptor): IrTypeAliasSymbol {
synchronized(lock) {
return originalTable.referenceTypeAlias(descriptor).also {
if (!it.isBound) {
stubGenerator?.generateTypeAliasStub(descriptor)
}
}
}
}
override fun referenceConstructor(descriptor: ClassConstructorDescriptor): IrConstructorSymbol {
synchronized(lock) {
return originalTable.referenceConstructor(descriptor).also {
@@ -62,6 +69,16 @@ class IrLazySymbolTable(private val originalTable: SymbolTable) : ReferenceSymbo
}
}
override fun referenceProperty(descriptor: PropertyDescriptor): IrPropertySymbol {
synchronized(lock) {
return originalTable.referenceProperty(descriptor).also {
if (!it.isBound) {
stubGenerator?.generatePropertyStub(descriptor)
}
}
}
}
override fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol {
synchronized(lock) {
return originalTable.referenceTypeParameter(classifier).also {
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
import org.jetbrains.kotlin.ir.util.file
import org.jetbrains.kotlin.ir.util.fileOrNull
import org.jetbrains.kotlin.ir.util.transformInPlace
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -58,6 +58,5 @@ abstract class IrReturnableBlock : IrBlock(), IrSymbolOwner, IrReturnTarget {
abstract val inlineFunctionSymbol: IrFunctionSymbol?
}
@Suppress("unused") // Used in kotlin-native
val IrReturnableBlock.sourceFileSymbol: IrFileSymbol?
get() = inlineFunctionSymbol?.owner?.file?.symbol
get() = inlineFunctionSymbol?.owner?.fileOrNull?.symbol
@@ -66,7 +66,7 @@ fun buildFakeOverrideMember(superType: IrType, member: IrOverridableMember, claz
val typeParameters = extractTypeParameters(classifier.owner)
val superArguments = superType.arguments
assert(typeParameters.size == superArguments.size) {
require(typeParameters.size == superArguments.size) {
"typeParameters = $typeParameters size != typeArguments = $superArguments size "
}
@@ -76,7 +76,7 @@ fun buildFakeOverrideMember(superType: IrType, member: IrOverridableMember, claz
val tp = typeParameters[i]
val ta = superArguments[i]
require(ta is IrTypeProjection) { "Unexpected super type argument: ${ta.render()} @ $i" }
assert(ta.variance == Variance.INVARIANT) { "Unexpected variance in super type argument: ${ta.variance} @$i" }
require(ta.variance == Variance.INVARIANT) { "Unexpected variance in super type argument: ${ta.variance} @$i" }
substitutionMap[tp.symbol] = ta.type
}
@@ -414,7 +414,7 @@ class IrOverridingUtil(
fakeOverride.overriddenSymbols = effectiveOverridden.map { it.original.symbol }
assert(
require(
fakeOverride.overriddenSymbols.isNotEmpty()
) { "Overridden symbols should be set for " + CallableMemberDescriptor.Kind.FAKE_OVERRIDE }
@@ -465,26 +465,24 @@ class IrOverridingUtil(
val bReturnType = b.returnType
if (!isVisibilityMoreSpecific(a, b)) return false
if (a is IrSimpleFunction) {
assert(b is IrSimpleFunction) { "b is " + b.javaClass }
require(b is IrSimpleFunction) { "b is " + b.javaClass }
return isReturnTypeMoreSpecific(a, aReturnType, b, bReturnType)
}
if (a is IrProperty) {
assert(b is IrProperty) { "b is " + b.javaClass }
val pa = a
val pb = b as IrProperty
require(b is IrProperty) { "b is " + b.javaClass }
if (!isAccessorMoreSpecific(
pa.setter,
pb.setter
a.setter,
b.setter
)
) return false
return if (pa.isVar && pb.isVar) {
return if (a.isVar && b.isVar) {
createTypeCheckerState(
a.getter!!.typeParameters,
b.getter!!.typeParameters
).equalTypes(aReturnType, bReturnType)
} else {
// both vals or var vs val: val can't be more specific then var
!(!pa.isVar && pb.isVar) && isReturnTypeMoreSpecific(
!(!a.isVar && b.isVar) && isReturnTypeMoreSpecific(
a, aReturnType,
b, bReturnType
)
@@ -510,7 +508,7 @@ class IrOverridingUtil(
private fun selectMostSpecificMember(
overridables: Collection<IrOverridableMember>
): IrOverridableMember {
assert(!overridables.isEmpty()) { "Should have at least one overridable descriptor" }
require(!overridables.isEmpty()) { "Should have at least one overridable descriptor" }
if (overridables.size == 1) {
return overridables.first()
}
@@ -693,7 +691,7 @@ class IrOverridingUtil(
}
*/
assert(superValueParameters.size == subValueParameters.size)
require(superValueParameters.size == subValueParameters.size)
superValueParameters.forEachIndexed { index, parameter ->
if (!AbstractTypeChecker.equalTypes(
@@ -235,10 +235,9 @@ abstract class DeclarationStubGenerator(
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
internal fun generateValueParameterStub(descriptor: ValueParameterDescriptor): IrValueParameter = with(descriptor) {
symbolTable.irFactory.createValueParameter(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, computeOrigin(this), IrValueParameterSymbolImpl(this), name, index, type.toIrType(),
varargElementType?.toIrType(), isCrossinline, isNoinline, isHidden = false, isAssignable = false
).also { irValueParameter ->
IrLazyValueParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, computeOrigin(this), IrValueParameterSymbolImpl(this), this, name, index,
type.toIrType(), varargElementType?.toIrType(), isCrossinline, isNoinline, isHidden = false, isAssignable = false, this@DeclarationStubGenerator, typeTranslator)
.also { irValueParameter ->
if (descriptor.declaresDefaultValue()) {
irValueParameter.defaultValue = irValueParameter.createStubDefaultValue()
}
@@ -304,7 +303,7 @@ abstract class DeclarationStubGenerator(
}
internal fun generateOrGetScopedTypeParameterStub(descriptor: TypeParameterDescriptor): IrTypeParameter {
val referenced = symbolTable.referenceTypeParameter(descriptor)
val referenced = symbolTable.referenceScopedTypeParameter(descriptor)
if (referenced.isBound) {
return referenced.owner
}
@@ -40,6 +40,7 @@ interface ReferenceSymbolTable {
fun referenceValueParameter(descriptor: ParameterDescriptor): IrValueParameterSymbol
fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol
fun referenceScopedTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol
fun referenceVariable(descriptor: VariableDescriptor): IrVariableSymbol
fun referenceTypeAlias(descriptor: TypeAliasDescriptor): IrTypeAliasSymbol
@@ -1030,6 +1031,11 @@ open class SymbolTable(
createTypeParameterSymbol(classifier)
}
override fun referenceScopedTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol =
scopedTypeParameterSymbolTable.referenced(classifier) {
createTypeParameterSymbol(classifier)
}
override fun referenceGlobalTypeParameterFromLinker(sig: IdSignature): IrTypeParameterSymbol {
return globalTypeParameterSymbolTable.referenced(sig, false) {
if (sig.isPubliclyVisible) IrTypeParameterPublicSymbolImpl(sig) else IrTypeParameterSymbolImpl()