From 12ba1b002cb8ce4f46812c86ebac8c0a12383c24 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Fri, 4 May 2018 11:28:56 +0200 Subject: [PATCH] Refactor SharedVariablesManager: get rid of descriptors in API --- .../descriptors/SharedVariablesManager.kt | 13 +++-- .../common/lower/SharedVariablesLowering.kt | 56 +++++++++---------- .../ir/backend/js/JsSharedVariablesManager.kt | 23 ++++---- .../jvm/descriptors/SharedVariablesManager.kt | 46 +++++++++------ 4 files changed, 75 insertions(+), 63 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/SharedVariablesManager.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/SharedVariablesManager.kt index 05b0c0b5384..5f92f7aa2d5 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/SharedVariablesManager.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/SharedVariablesManager.kt @@ -16,16 +16,19 @@ package org.jetbrains.kotlin.backend.common.descriptors -import org.jetbrains.kotlin.descriptors.VariableDescriptor import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrGetValue import org.jetbrains.kotlin.ir.expressions.IrSetVariable +import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol interface SharedVariablesManager { - fun createSharedVariableDescriptor(variableDescriptor: VariableDescriptor): VariableDescriptor - fun defineSharedValue(sharedVariableDescriptor: VariableDescriptor, originalDeclaration: IrVariable): IrStatement - fun getSharedValue(sharedVariableDescriptor: VariableDescriptor, originalGet: IrGetValue): IrExpression - fun setSharedValue(sharedVariableDescriptor: VariableDescriptor, originalSet: IrSetVariable): IrExpression + fun declareSharedVariable(originalDeclaration: IrVariable): IrVariable + + fun defineSharedValue(originalDeclaration: IrVariable, sharedVariableDeclaration: IrVariable): IrStatement + + fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue): IrExpression + + fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetVariable): IrExpression } \ No newline at end of file diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt index c3996d208c7..32eb1dbfe19 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt @@ -18,9 +18,6 @@ package org.jetbrains.kotlin.backend.common.lower import org.jetbrains.kotlin.backend.common.BackendContext import org.jetbrains.kotlin.backend.common.FunctionLoweringPass -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.ValueDescriptor -import org.jetbrains.kotlin.descriptors.VariableDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.IrDeclaration @@ -30,6 +27,9 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrGetValue import org.jetbrains.kotlin.ir.expressions.IrSetVariable import org.jetbrains.kotlin.ir.expressions.IrValueAccessExpression +import org.jetbrains.kotlin.ir.symbols.IrValueSymbol +import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol +import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.visitors.* import java.util.* @@ -39,7 +39,7 @@ class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPas } private inner class SharedVariablesTransformer(val irFunction: IrFunction) { - val sharedVariables = HashSet() + private val sharedVariables = HashSet() fun lowerSharedVariables() { collectSharedVariables() @@ -51,10 +51,10 @@ class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPas private fun collectSharedVariables() { irFunction.acceptVoid(object : IrElementVisitorVoid { val declarationsStack = ArrayDeque() - val currentDeclaration: DeclarationDescriptor - get() = declarationsStack.peek().descriptor + val currentDeclaration: IrDeclaration + get() = declarationsStack.peek() - val relevantVars = HashSet() + val relevantVars = HashSet() override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) @@ -69,37 +69,35 @@ class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPas override fun visitVariable(declaration: IrVariable) { declaration.acceptChildrenVoid(this) - val variableDescriptor = declaration.descriptor - if (variableDescriptor.isVar) { - relevantVars.add(variableDescriptor) + if (declaration.isVar) { + relevantVars.add(declaration) } } override fun visitVariableAccess(expression: IrValueAccessExpression) { expression.acceptChildrenVoid(this) - val descriptor = expression.descriptor - if (descriptor in relevantVars && descriptor.containingDeclaration != currentDeclaration) { - sharedVariables.add(descriptor) + val value = expression.symbol.owner + if (value in relevantVars && (value as IrVariable).parent != currentDeclaration) { + sharedVariables.add(value) } } }) } private fun rewriteSharedVariables() { - val transformedDescriptors = HashMap() + val transformedDescriptors = HashMap() irFunction.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitVariable(declaration: IrVariable): IrStatement { declaration.transformChildrenVoid(this) - val oldDescriptor = declaration.descriptor - if (oldDescriptor !in sharedVariables) return declaration + if (declaration !in sharedVariables) return declaration - val newDescriptor = context.sharedVariablesManager.createSharedVariableDescriptor(oldDescriptor) - transformedDescriptors[oldDescriptor] = newDescriptor + val newDeclaration = context.sharedVariablesManager.declareSharedVariable(declaration) + transformedDescriptors[declaration.symbol] = newDeclaration.symbol - return context.sharedVariablesManager.defineSharedValue(newDescriptor, declaration) + return context.sharedVariablesManager.defineSharedValue(declaration, newDeclaration) } }) @@ -107,26 +105,26 @@ class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPas override fun visitGetValue(expression: IrGetValue): IrExpression { expression.transformChildrenVoid(this) - val newDescriptor = getTransformedDescriptor(expression.descriptor) ?: return expression + val newDeclaration = getTransformedSymbol(expression.symbol) ?: return expression - return context.sharedVariablesManager.getSharedValue(newDescriptor, expression) + return context.sharedVariablesManager.getSharedValue(newDeclaration, expression) } override fun visitSetVariable(expression: IrSetVariable): IrExpression { expression.transformChildrenVoid(this) - val newDescriptor = getTransformedDescriptor(expression.descriptor) ?: return expression + val newDeclaration = getTransformedSymbol(expression.symbol) ?: return expression - return context.sharedVariablesManager.setSharedValue(newDescriptor, expression) + return context.sharedVariablesManager.setSharedValue(newDeclaration, expression) } - private fun getTransformedDescriptor(oldDescriptor: ValueDescriptor): VariableDescriptor? = - transformedDescriptors.getOrElse(oldDescriptor) { - assert(oldDescriptor !in sharedVariables) { - "Shared variable is not transformed: $oldDescriptor" - } - null + private fun getTransformedSymbol(oldSymbol: IrValueSymbol): IrVariableSymbol? = + transformedDescriptors.getOrElse(oldSymbol) { + assert(oldSymbol.owner !in sharedVariables) { + "Shared variable is not transformed: ${oldSymbol.owner.dump()}" } + null + } }) } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt index d76110e9df3..5b70247c7c0 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsSharedVariablesManager.kt @@ -21,9 +21,8 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrGetValue import org.jetbrains.kotlin.ir.expressions.IrSetVariable import org.jetbrains.kotlin.ir.expressions.impl.* -import org.jetbrains.kotlin.ir.symbols.IrValueSymbol +import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl -import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -34,14 +33,14 @@ import org.jetbrains.kotlin.types.Variance class JsSharedVariablesManager(val builtIns: KotlinBuiltIns, val jsInterinalPackage: PackageFragmentDescriptor) : SharedVariablesManager { - override fun createSharedVariableDescriptor(variableDescriptor: VariableDescriptor): VariableDescriptor = - LocalVariableDescriptor( + override fun declareSharedVariable(originalDeclaration: IrVariable): IrVariable { + val variableDescriptor = originalDeclaration.descriptor + val sharedVariableDescriptor = LocalVariableDescriptor( variableDescriptor.containingDeclaration, variableDescriptor.annotations, variableDescriptor.name, getSharedVariableType(variableDescriptor.type), false, false, variableDescriptor.isLateInit, variableDescriptor.source ) - override fun defineSharedValue(sharedVariableDescriptor: VariableDescriptor, originalDeclaration: IrVariable): IrStatement { val valueType = originalDeclaration.descriptor.type val boxConstructor = closureBoxConstructorTypeDescriptor val boxConstructorSymbol = closureBoxConstructorTypeSymbol @@ -71,26 +70,28 @@ class JsSharedVariablesManager(val builtIns: KotlinBuiltIns, val jsInterinalPack ) } - override fun getSharedValue(sharedVariableDescriptor: VariableDescriptor, originalGet: IrGetValue): IrExpression = + override fun defineSharedValue(originalDeclaration: IrVariable, sharedVariableDeclaration: IrVariable) = sharedVariableDeclaration + + override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue): IrExpression = IrGetFieldImpl( originalGet.startOffset, originalGet.endOffset, closureBoxFieldSymbol, IrGetValueImpl( originalGet.startOffset, originalGet.endOffset, - symbolForDescriptor(sharedVariableDescriptor) + sharedVariableSymbol ), originalGet.origin ) - override fun setSharedValue(sharedVariableDescriptor: VariableDescriptor, originalSet: IrSetVariable): IrExpression = + override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetVariable): IrExpression = IrSetFieldImpl( originalSet.startOffset, originalSet.endOffset, closureBoxFieldSymbol, IrGetValueImpl( originalSet.startOffset, originalSet.endOffset, - symbolForDescriptor(sharedVariableDescriptor) + sharedVariableSymbol ), originalSet.value, originalSet.origin @@ -191,8 +192,4 @@ class JsSharedVariablesManager(val builtIns: KotlinBuiltIns, val jsInterinalPack private fun getSharedVariableType(type: KotlinType) = getRefType(type) - private val variableSymbols = mutableMapOf() - - private fun symbolForDescriptor(sharedVariableDescriptor: VariableDescriptor): IrValueSymbol = - variableSymbols.getOrPut(sharedVariableDescriptor, { IrVariableSymbolImpl(sharedVariableDescriptor) }) } 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 e36bfb7476a..5a9a8ffa2e9 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 @@ -16,7 +16,9 @@ package org.jetbrains.kotlin.backend.jvm.descriptors -import org.jetbrains.kotlin.backend.common.descriptors.* +import org.jetbrains.kotlin.backend.common.descriptors.KnownClassDescriptor +import org.jetbrains.kotlin.backend.common.descriptors.KnownPackageFragmentDescriptor +import org.jetbrains.kotlin.backend.common.descriptors.SharedVariablesManager import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.descriptors.* @@ -42,9 +44,6 @@ class JvmSharedVariablesManager(val builtIns: KotlinBuiltIns) : SharedVariablesM private val refNamespaceClass = KnownClassDescriptor.createClass(Name.identifier("Ref"), kotlinJvmInternalPackage, listOf(builtIns.anyType)) - //TODO: avoid tracking symbols - private val sharedVariableDescriptorToSymbol = mutableMapOf() - private class PrimitiveRefDescriptorsProvider(type: KotlinType, refClass: ClassDescriptor) { val refType: KotlinType = refClass.defaultType @@ -128,14 +127,14 @@ class JvmSharedVariablesManager(val builtIns: KotlinBuiltIns) : SharedVariablesM private val objectRefDescriptorsProvider = ObjectRefDescriptorsProvider() - override fun createSharedVariableDescriptor(variableDescriptor: VariableDescriptor): VariableDescriptor = - LocalVariableDescriptor( + override fun declareSharedVariable(originalDeclaration: IrVariable): IrVariable { + val variableDescriptor = originalDeclaration.descriptor + val sharedVariableDescriptor = LocalVariableDescriptor( variableDescriptor.containingDeclaration, variableDescriptor.annotations, variableDescriptor.name, getSharedVariableType(variableDescriptor.type), false, false, variableDescriptor.isLateInit, variableDescriptor.source ) - override fun defineSharedValue(sharedVariableDescriptor: VariableDescriptor, originalDeclaration: IrVariable): IrStatement { val valueType = originalDeclaration.descriptor.type val primitiveRefDescriptorsProvider = primitiveRefDescriptorProviders[getPrimitiveType(valueType)] @@ -146,22 +145,29 @@ class JvmSharedVariablesManager(val builtIns: KotlinBuiltIns) : SharedVariablesM if (primitiveRefDescriptorsProvider != null) null else mapOf(objectRefDescriptorsProvider.constructorTypeParameter to valueType) - val elementPropertyDescriptor = - primitiveRefDescriptorsProvider?.elementField ?: objectRefDescriptorsProvider.genericElementField val refConstructorCall = IrCallImpl( originalDeclaration.startOffset, originalDeclaration.endOffset, refConstructor, refConstructorTypeArguments ) - val sharedVariableDeclaration = IrVariableImpl( + return IrVariableImpl( originalDeclaration.startOffset, originalDeclaration.endOffset, originalDeclaration.origin, sharedVariableDescriptor, refConstructorCall ) + } - sharedVariableDescriptorToSymbol[sharedVariableDescriptor] = sharedVariableDeclaration.symbol - + override fun defineSharedValue( + originalDeclaration: IrVariable, + sharedVariableDeclaration: IrVariable + ): IrStatement { val initializer = originalDeclaration.initializer ?: return sharedVariableDeclaration + val valueType = originalDeclaration.descriptor.type + val primitiveRefDescriptorsProvider = primitiveRefDescriptorProviders[getPrimitiveType(valueType)] + + val elementPropertyDescriptor = + primitiveRefDescriptorsProvider?.elementField ?: objectRefDescriptorsProvider.genericElementField + val sharedVariableInitialization = IrSetFieldImpl( initializer.startOffset, initializer.endOffset, elementPropertyDescriptor, @@ -181,19 +187,27 @@ class JvmSharedVariablesManager(val builtIns: KotlinBuiltIns) : SharedVariablesM return primitiveRefDescriptorsProvider?.elementField ?: objectRefDescriptorsProvider.genericElementField } - override fun getSharedValue(sharedVariableDescriptor: VariableDescriptor, originalGet: IrGetValue): IrExpression = + override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue): IrExpression = IrGetFieldImpl( originalGet.startOffset, originalGet.endOffset, getElementFieldDescriptor(originalGet.descriptor.type), - IrGetValueImpl(originalGet.startOffset, originalGet.endOffset, sharedVariableDescriptorToSymbol[sharedVariableDescriptor]!!), + IrGetValueImpl( + originalGet.startOffset, + originalGet.endOffset, + sharedVariableSymbol + ), originalGet.origin ) - override fun setSharedValue(sharedVariableDescriptor: VariableDescriptor, originalSet: IrSetVariable): IrExpression = + override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetVariable): IrExpression = IrSetFieldImpl( originalSet.startOffset, originalSet.endOffset, getElementFieldDescriptor(originalSet.descriptor.type), - IrGetValueImpl(originalSet.startOffset, originalSet.endOffset, sharedVariableDescriptorToSymbol[sharedVariableDescriptor]!!), + IrGetValueImpl( + originalSet.startOffset, + originalSet.endOffset, + sharedVariableSymbol + ), originalSet.value, originalSet.origin )