From 13b04e63be44b56c380e510943d3dc34020ec8b0 Mon Sep 17 00:00:00 2001 From: pyos Date: Mon, 2 Mar 2020 15:06:32 +0100 Subject: [PATCH] JVM_IR: wrap inline class objects in unboxed refs --- .../kotlin/backend/jvm/JvmBackendContext.kt | 3 ++- .../jvm/descriptors/SharedVariablesManager.kt | 24 +++++++++++++++---- .../localInitializationLVT/inlineClass.kt | 3 --- .../localInitializationLVT/inlineClassVar.kt | 3 --- 4 files changed, 21 insertions(+), 12 deletions(-) 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 4fab46fb098..67c5d5acbce 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,6 @@ class JvmBackendContext( val methodSignatureMapper = MethodSignatureMapper(this) override val declarationFactory: JvmDeclarationFactory = JvmDeclarationFactory(methodSignatureMapper, state.languageVersionSettings) - override val sharedVariablesManager = JvmSharedVariablesManager(state.module, irBuiltIns) override val mapping: Mapping = DefaultMapping() @@ -77,6 +76,8 @@ class JvmBackendContext( override val ir = JvmIr(irModuleFragment, this.symbolTable) + override val sharedVariablesManager = JvmSharedVariablesManager(state.module, ir.symbols, irBuiltIns) + val irIntrinsics by lazy { IrIntrinsicMethods(irBuiltIns, ir.symbols) } private val localClassType = mutableMapOf() 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 2bec0cc11ea..99027db60ec 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 @@ -7,6 +7,8 @@ package org.jetbrains.kotlin.backend.jvm.descriptors import org.jetbrains.kotlin.backend.common.ir.SharedVariablesManager import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor +import org.jetbrains.kotlin.backend.jvm.JvmSymbols +import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor import org.jetbrains.kotlin.ir.IrStatement @@ -27,6 +29,7 @@ import org.jetbrains.kotlin.name.Name class JvmSharedVariablesManager( module: ModuleDescriptor, + val symbols: JvmSymbols, val irBuiltIns: IrBuiltIns ) : SharedVariablesManager { private val jvmInternalPackage = IrExternalPackageFragmentImpl( @@ -83,7 +86,7 @@ class JvmSharedVariablesManager( override fun declareSharedVariable(originalDeclaration: IrVariable): IrVariable { val valueType = originalDeclaration.type - val provider = getProvider(valueType) + val provider = getProvider(InlineClassAbi.unboxType(valueType) ?: valueType) val typeArguments = provider.refClass.typeParameters.map { valueType } val refType = provider.refClass.typeWith(typeArguments) val refConstructorCall = IrConstructorCallImpl.fromSymbolOwner(refType, provider.refConstructor.symbol).apply { @@ -116,18 +119,29 @@ class JvmSharedVariablesManager( } } + private fun unsafeCoerce(value: IrExpression, from: IrType, to: IrType): IrExpression = + IrCallImpl(value.startOffset, value.endOffset, to, symbols.unsafeCoerceIntrinsic).apply { + putTypeArgument(0, from) + putTypeArgument(1, to) + putValueArgument(0, value) + } + override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue): IrExpression = with(originalGet) { - val provider = getProvider(symbol.owner.type) + val unboxedType = InlineClassAbi.unboxType(symbol.owner.type) + val provider = getProvider(unboxedType ?: symbol.owner.type) val receiver = IrGetValueImpl(startOffset, endOffset, sharedVariableSymbol) - IrGetFieldImpl(startOffset, endOffset, provider.elementField.symbol, type, receiver, origin) + val unboxedRead = IrGetFieldImpl(startOffset, endOffset, provider.elementField.symbol, unboxedType ?: type, receiver, origin) + unboxedType?.let { unsafeCoerce(unboxedRead, it, symbol.owner.type) } ?: unboxedRead } override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetVariable): IrExpression = with(originalSet) { - val provider = getProvider(symbol.owner.type) + val unboxedType = InlineClassAbi.unboxType(symbol.owner.type) + val unboxedValue = unboxedType?.let { unsafeCoerce(value, symbol.owner.type, it) } ?: value + val provider = getProvider(unboxedType ?: symbol.owner.type) val receiver = IrGetValueImpl(startOffset, endOffset, sharedVariableSymbol) - IrSetFieldImpl(startOffset, endOffset, provider.elementField.symbol, receiver, value, type, origin) + IrSetFieldImpl(startOffset, endOffset, provider.elementField.symbol, receiver, unboxedValue, type, origin) } } diff --git a/compiler/testData/codegen/bytecodeText/localInitializationLVT/inlineClass.kt b/compiler/testData/codegen/bytecodeText/localInitializationLVT/inlineClass.kt index 4ca13901fb5..a7d839da942 100644 --- a/compiler/testData/codegen/bytecodeText/localInitializationLVT/inlineClass.kt +++ b/compiler/testData/codegen/bytecodeText/localInitializationLVT/inlineClass.kt @@ -1,6 +1,3 @@ -// IGNORE_BACKEND: JVM_IR -// TODO: JVM_IR uses ObjectRef instead of IntRef for the value - fun test(): UInt { val c: UInt run { diff --git a/compiler/testData/codegen/bytecodeText/localInitializationLVT/inlineClassVar.kt b/compiler/testData/codegen/bytecodeText/localInitializationLVT/inlineClassVar.kt index 60e26da1c20..a8e95e41261 100644 --- a/compiler/testData/codegen/bytecodeText/localInitializationLVT/inlineClassVar.kt +++ b/compiler/testData/codegen/bytecodeText/localInitializationLVT/inlineClassVar.kt @@ -1,6 +1,3 @@ -// IGNORE_BACKEND: JVM_IR -// TODO: JVM_IR uses ObjectRef instead of IntRef for the value - fun test(): UInt { var c: UInt run {