From 68745ec43f198791918ec4b8b1c118ee6067e109 Mon Sep 17 00:00:00 2001 From: pyos Date: Mon, 2 Mar 2020 14:51:59 +0100 Subject: [PATCH] JVM_IR: refactor JvmSharedVariablesManager --- .../kotlin/backend/common/ir/IrUtils.kt | 3 - .../kotlin/backend/jvm/JvmBackendContext.kt | 2 +- .../jvm/descriptors/SharedVariablesManager.kt | 238 +++++------------- 3 files changed, 66 insertions(+), 177 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt index 47c3bbdf03c..12e6bd7c42b 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt @@ -407,9 +407,6 @@ fun IrClass.createImplicitParameterDeclarationWithWrappedDescriptor() { thisReceiverDescriptor.bind(valueParameter) valueParameter.parent = this } - - assert(typeParameters.isEmpty()) - assert(descriptor.declaredTypeParameters.isEmpty()) } @Suppress("UNCHECKED_CAST") diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index d3088a299c4..4fab46fb098 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -69,7 +69,7 @@ class JvmBackendContext( val methodSignatureMapper = MethodSignatureMapper(this) override val declarationFactory: JvmDeclarationFactory = JvmDeclarationFactory(methodSignatureMapper, state.languageVersionSettings) - override val sharedVariablesManager = JvmSharedVariablesManager(state.module, builtIns, irBuiltIns) + override val sharedVariablesManager = JvmSharedVariablesManager(state.module, irBuiltIns) override val mapping: Mapping = DefaultMapping() diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SharedVariablesManager.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SharedVariablesManager.kt index 1dcb4b27d68..2bec0cc11ea 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SharedVariablesManager.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SharedVariablesManager.kt @@ -6,45 +6,27 @@ package org.jetbrains.kotlin.backend.jvm.descriptors import org.jetbrains.kotlin.backend.common.ir.SharedVariablesManager -import org.jetbrains.kotlin.backend.common.ir.addChild -import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET -import org.jetbrains.kotlin.ir.builders.declarations.buildClass -import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor -import org.jetbrains.kotlin.ir.builders.declarations.buildField -import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter +import org.jetbrains.kotlin.ir.builders.declarations.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl -import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns -import org.jetbrains.kotlin.ir.descriptors.WrappedTypeParameterDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedVariableDescriptor import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* -import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl -import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl import org.jetbrains.kotlin.ir.types.* -import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl -import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection -import org.jetbrains.kotlin.ir.util.defaultType -import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.types.Variance - -private val SHARED_VARIABLE_ORIGIN = object : IrDeclarationOriginImpl("SHARED_VARIABLE_ORIGIN") {} -private val SHARED_VARIABLE_CONSTRUCTOR_CALL_ORIGIN = object : IrStatementOriginImpl("SHARED_VARIABLE_CONSTRUCTOR_CALL") {} class JvmSharedVariablesManager( module: ModuleDescriptor, - val builtIns: KotlinBuiltIns, val irBuiltIns: IrBuiltIns ) : SharedVariablesManager { private val jvmInternalPackage = IrExternalPackageFragmentImpl( @@ -53,106 +35,44 @@ class JvmSharedVariablesManager( ) ) - private val refNamespaceClass = buildClass { + private val refNamespaceClass = jvmInternalPackage.addClass { name = Name.identifier("Ref") - }.apply { - parent = jvmInternalPackage - jvmInternalPackage.addChild(this) - superTypes += irBuiltIns.anyType } - private abstract class RefProvider { - abstract val elementType: IrType - abstract val refClass: IrClass - abstract fun getRefType(valueType: IrType): IrSimpleType - - // Have to initialize fields lazily in order to refer to refClass. - val refConstructor: IrConstructor by lazy { - buildConstructor { - origin = SHARED_VARIABLE_ORIGIN - returnType = refClass.defaultType - }.apply { - parent = refClass - refClass.addMember(this) - } + private class RefProvider(val refClass: IrClass, elementType: IrType) { + val refConstructor = refClass.addConstructor { + origin = IrDeclarationOrigin.IR_BUILTINS_STUB } - val elementField: IrField by lazy { - buildField { - origin = SHARED_VARIABLE_ORIGIN - name = Name.identifier("element") - type = elementType - }.apply { - parent = refClass - refClass.addMember(this) - } + val elementField = refClass.addField { + origin = IrDeclarationOrigin.IR_BUILTINS_STUB + name = Name.identifier("element") + type = elementType } } - private inner class PrimitiveRefProvider(override val elementType: IrType) : RefProvider() { - override val refClass = buildClass { - origin = SHARED_VARIABLE_ORIGIN - name = Name.identifier(elementType.classOrNull!!.owner.name.asString() + "Ref") - }.apply { - parent = refNamespaceClass - refNamespaceClass.addMember(this) - superTypes += irBuiltIns.anyType - thisReceiver = buildValueParameter { - type = IrSimpleTypeImpl(symbol, hasQuestionMark = false, arguments = emptyList(), annotations = emptyList()) - name = Name.identifier("$this") - }.also { - it.parent = this - } - } - - override fun getRefType(valueType: IrType) = refClass.defaultType - } - private val primitiveRefProviders = irBuiltIns.primitiveIrTypes.associate { primitiveType -> - primitiveType.classifierOrFail to PrimitiveRefProvider(primitiveType) + val refClass = refNamespaceClass.addClass { + origin = IrDeclarationOrigin.IR_BUILTINS_STUB + name = Name.identifier(primitiveType.classOrNull!!.owner.name.asString() + "Ref") + }.apply { + createImplicitParameterDeclarationWithWrappedDescriptor() + } + primitiveType.classifierOrFail to RefProvider(refClass, primitiveType) } - private val objectRefProvider = object : RefProvider() { - override val refClass = buildClass { - origin = SHARED_VARIABLE_ORIGIN + private val objectRefProvider = run { + val refClass = refNamespaceClass.addClass { + origin = IrDeclarationOrigin.IR_BUILTINS_STUB name = Name.identifier("ObjectRef") }.apply { - val irClass = this - typeParameters += - IrTypeParameterImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - SHARED_VARIABLE_ORIGIN, - IrTypeParameterSymbolImpl(WrappedTypeParameterDescriptor()), - Name.identifier("T"), - index = 0, - variance = Variance.INVARIANT, - isReified = false - ).apply { - (descriptor as WrappedTypeParameterDescriptor).bind(this) - parent = irClass - superTypes.add(irBuiltIns.anyNType) - } - parent = refNamespaceClass - refNamespaceClass.addMember(this) - superTypes += irBuiltIns.anyType - thisReceiver = buildValueParameter { - type = IrSimpleTypeImpl( - symbol, - hasQuestionMark = false, - arguments = listOf( - makeTypeProjection(typeParameters[0].defaultType, Variance.INVARIANT) - ), - annotations = emptyList() - ) - name = Name.identifier("$this") - }.also { - it.parent = this + addTypeParameter { + name = Name.identifier("T") + superTypes.add(irBuiltIns.anyNType) } + createImplicitParameterDeclarationWithWrappedDescriptor() } - - override val elementType = refClass.typeParameters[0].defaultType - - override fun getRefType(valueType: IrType) = refClass.typeWith(valueType) + RefProvider(refClass, refClass.typeParameters[0].defaultType) } private fun getProvider(valueType: IrType): RefProvider = @@ -161,85 +81,57 @@ class JvmSharedVariablesManager( else objectRefProvider - private fun getElementFieldSymbol(valueType: IrType): IrFieldSymbol { - return getProvider(valueType).elementField.symbol - } - override fun declareSharedVariable(originalDeclaration: IrVariable): IrVariable { val valueType = originalDeclaration.type val provider = getProvider(valueType) - val refType = provider.getRefType(valueType) - val refConstructor = provider.refConstructor - - val refConstructorCall = IrConstructorCallImpl.fromSymbolOwner( - refType, - refConstructor.symbol, - SHARED_VARIABLE_CONSTRUCTOR_CALL_ORIGIN - ).apply { - List(refConstructor.parentAsClass.typeParameters.size) { i -> - putTypeArgument(i, valueType) - } + val typeArguments = provider.refClass.typeParameters.map { valueType } + val refType = provider.refClass.typeWith(typeArguments) + val refConstructorCall = IrConstructorCallImpl.fromSymbolOwner(refType, provider.refConstructor.symbol).apply { + typeArguments.forEachIndexed(::putTypeArgument) } - - return IrVariableImpl( - originalDeclaration.startOffset, originalDeclaration.endOffset, originalDeclaration.origin, - IrVariableSymbolImpl(WrappedVariableDescriptor()), - originalDeclaration.name, - refType, - originalDeclaration.isVar, - originalDeclaration.isConst, - isLateinit = false - ).apply { - (descriptor as WrappedVariableDescriptor).bind(this) - initializer = refConstructorCall - parent = originalDeclaration.parent + return with(originalDeclaration) { + IrVariableImpl( + startOffset, endOffset, origin, IrVariableSymbolImpl(WrappedVariableDescriptor()), name, refType, + isVar = false, // writes are remapped to field stores + isConst = false, // const vals could not possibly require ref wrappers + isLateinit = false + ).apply { + (descriptor as WrappedVariableDescriptor).bind(this) + initializer = refConstructorCall + } } } - override fun defineSharedValue( - originalDeclaration: IrVariable, - sharedVariableDeclaration: IrVariable - ): IrStatement { + override fun defineSharedValue(originalDeclaration: IrVariable, sharedVariableDeclaration: IrVariable): IrStatement { val initializer = originalDeclaration.initializer ?: return sharedVariableDeclaration - - val valueType = originalDeclaration.type - - val sharedVariableInitialization = IrSetFieldImpl( - initializer.startOffset, initializer.endOffset, - getElementFieldSymbol(valueType), - IrGetValueImpl(initializer.startOffset, initializer.endOffset, sharedVariableDeclaration.symbol), - initializer, - irBuiltIns.unitType - ) - - return IrCompositeImpl( - originalDeclaration.startOffset, originalDeclaration.endOffset, irBuiltIns.unitType, null, - listOf(sharedVariableDeclaration, sharedVariableInitialization) - ) + val initializationStatement = with(initializer) { + IrSetVariableImpl(startOffset, endOffset, irBuiltIns.unitType, originalDeclaration.symbol, this, null) + } + val sharedVariableInitialization = setSharedValue(sharedVariableDeclaration.symbol, initializationStatement) + return with(originalDeclaration) { + IrCompositeImpl( + startOffset, endOffset, irBuiltIns.unitType, null, + listOf(sharedVariableDeclaration, sharedVariableInitialization) + ) + } } override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue): IrExpression = - IrTypeOperatorCallImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - originalGet.type, - IrTypeOperator.IMPLICIT_CAST, - originalGet.type, - IrGetFieldImpl( - originalGet.startOffset, originalGet.endOffset, - getElementFieldSymbol(originalGet.symbol.owner.type), - originalGet.type, - IrGetValueImpl(originalGet.startOffset, originalGet.endOffset, sharedVariableSymbol), - originalGet.origin - ) - ) + with(originalGet) { + val provider = getProvider(symbol.owner.type) + val receiver = IrGetValueImpl(startOffset, endOffset, sharedVariableSymbol) + IrGetFieldImpl(startOffset, endOffset, provider.elementField.symbol, type, receiver, origin) + } override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetVariable): IrExpression = - IrSetFieldImpl( - originalSet.startOffset, originalSet.endOffset, - getElementFieldSymbol(originalSet.symbol.owner.type), - IrGetValueImpl(originalSet.startOffset, originalSet.endOffset, sharedVariableSymbol), - originalSet.value, - originalSet.type, - originalSet.origin - ) + with(originalSet) { + val provider = getProvider(symbol.owner.type) + val receiver = IrGetValueImpl(startOffset, endOffset, sharedVariableSymbol) + IrSetFieldImpl(startOffset, endOffset, provider.elementField.symbol, receiver, value, type, origin) + } +} + +private inline fun IrDeclarationContainer.addClass(builder: IrClassBuilder.() -> Unit) = buildClass(builder).also { + it.parent = this + declarations += it }