JVM IR: support value classes only when feature is enabled
Remove NeedsToVisit because it doesn't really help with performance, and it significantly increases code complexity.
This commit is contained in:
committed by
Space Team
parent
2dee47a8c1
commit
12bbdebed2
+2
@@ -176,6 +176,8 @@ fun unboxedTypeOfInlineClass(boxedType: Type, state: GenerationState): Type? {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getMultiFieldValueClassUnboxInfo(boxedType: Type, state: GenerationState): MultiFieldValueClassUnboxInfo? {
|
fun getMultiFieldValueClassUnboxInfo(boxedType: Type, state: GenerationState): MultiFieldValueClassUnboxInfo? {
|
||||||
|
if (!state.config.supportMultiFieldValueClasses) return null
|
||||||
|
|
||||||
val descriptor =
|
val descriptor =
|
||||||
state.jvmBackendClassResolver.resolveToClassDescriptors(boxedType).singleOrNull()?.takeIf { it.isMultiFieldValueClass() }
|
state.jvmBackendClassResolver.resolveToClassDescriptors(boxedType).singleOrNull()?.takeIf { it.isMultiFieldValueClass() }
|
||||||
?: return null
|
?: return null
|
||||||
|
|||||||
+1
-1
@@ -297,7 +297,7 @@ private fun AbstractInsnNode.isInlineClassUnboxing(state: GenerationState) =
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun AbstractInsnNode.isMultiFieldValueClassUnboxing(state: GenerationState) =
|
private fun AbstractInsnNode.isMultiFieldValueClassUnboxing(state: GenerationState) =
|
||||||
isMethodInsnWith(Opcodes.INVOKEVIRTUAL) {
|
state.config.supportMultiFieldValueClasses && isMethodInsnWith(Opcodes.INVOKEVIRTUAL) {
|
||||||
isMultiFieldValueClassUnboxingMethodDescriptor(state)
|
isMultiFieldValueClassUnboxingMethodDescriptor(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,4 +100,6 @@ class JvmBackendConfig(configuration: CompilerConfiguration) {
|
|||||||
val noNewJavaAnnotationTargets: Boolean = configuration.getBoolean(JVMConfigurationKeys.NO_NEW_JAVA_ANNOTATION_TARGETS)
|
val noNewJavaAnnotationTargets: Boolean = configuration.getBoolean(JVMConfigurationKeys.NO_NEW_JAVA_ANNOTATION_TARGETS)
|
||||||
|
|
||||||
val oldInnerClassesLogic: Boolean = configuration.getBoolean(JVMConfigurationKeys.OLD_INNER_CLASSES_LOGIC)
|
val oldInnerClassesLogic: Boolean = configuration.getBoolean(JVMConfigurationKeys.OLD_INNER_CLASSES_LOGIC)
|
||||||
|
|
||||||
|
val supportMultiFieldValueClasses: Boolean = languageVersionSettings.supportsFeature(LanguageFeature.ValueClasses)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -176,7 +176,9 @@ object FirAnnotationChecker : FirBasicDeclarationChecker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (check(actualTargets.defaultTargets) || check(actualTargets.canBeSubstituted) || checkWithUseSiteTargets()) {
|
if (check(actualTargets.defaultTargets) || check(actualTargets.canBeSubstituted) || checkWithUseSiteTargets()) {
|
||||||
checkMultiFieldValueClassAnnotationRestrictions(declaration, annotation, context, reporter)
|
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ValueClasses)) {
|
||||||
|
checkMultiFieldValueClassAnnotationRestrictions(declaration, annotation, context, reporter)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ open class ScopeWithIr(val scope: Scope, val irElement: IrElement)
|
|||||||
|
|
||||||
abstract class IrElementTransformerVoidWithContext : IrElementTransformerVoid() {
|
abstract class IrElementTransformerVoidWithContext : IrElementTransformerVoid() {
|
||||||
|
|
||||||
protected open val scopeStack = mutableListOf<ScopeWithIr>()
|
private val scopeStack = mutableListOf<ScopeWithIr>()
|
||||||
|
|
||||||
protected open fun createScope(declaration: IrSymbolOwner): ScopeWithIr =
|
protected open fun createScope(declaration: IrSymbolOwner): ScopeWithIr =
|
||||||
ScopeWithIr(Scope(declaration.symbol), declaration)
|
ScopeWithIr(Scope(declaration.symbol), declaration)
|
||||||
|
|||||||
@@ -380,7 +380,8 @@ private val jvmFilePhases = listOf(
|
|||||||
forLoopsPhase,
|
forLoopsPhase,
|
||||||
collectionStubMethodLowering,
|
collectionStubMethodLowering,
|
||||||
singleAbstractMethodPhase,
|
singleAbstractMethodPhase,
|
||||||
jvmValueClassPhase,
|
jvmMultiFieldValueClassPhase,
|
||||||
|
jvmInlineClassPhase,
|
||||||
tailrecPhase,
|
tailrecPhase,
|
||||||
// makePatchParentsPhase(),
|
// makePatchParentsPhase(),
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -113,7 +113,7 @@ internal val bridgePhase = makeIrFilePhase(
|
|||||||
::BridgeLowering,
|
::BridgeLowering,
|
||||||
name = "Bridge",
|
name = "Bridge",
|
||||||
description = "Generate bridges",
|
description = "Generate bridges",
|
||||||
prerequisite = setOf(jvmValueClassPhase, inheritedDefaultMethodsOnClassesPhase)
|
prerequisite = setOf(jvmInlineClassPhase, inheritedDefaultMethodsOnClassesPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
internal class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
internal class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||||
|
|||||||
+14
-4
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
|||||||
import org.jetbrains.kotlin.backend.common.ScopeWithIr
|
import org.jetbrains.kotlin.backend.common.ScopeWithIr
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.loops.forLoopsPhase
|
||||||
|
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||||
import org.jetbrains.kotlin.backend.jvm.*
|
import org.jetbrains.kotlin.backend.jvm.*
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
@@ -29,6 +31,17 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.JVM_INLINE_ANNOTATION_FQ_NAME
|
import org.jetbrains.kotlin.resolve.JVM_INLINE_ANNOTATION_FQ_NAME
|
||||||
|
|
||||||
|
val jvmInlineClassPhase = makeIrFilePhase(
|
||||||
|
::JvmInlineClassLowering,
|
||||||
|
name = "InlineClasses",
|
||||||
|
description = "Lower inline classes",
|
||||||
|
// forLoopsPhase may produce UInt and ULong which are inline classes.
|
||||||
|
// Standard library replacements are done on the not mangled names for UInt and ULong classes.
|
||||||
|
// Collection stubs may require mangling by value class rules.
|
||||||
|
// SAM wrappers may require mangling for fun interfaces with value class parameters
|
||||||
|
prerequisite = setOf(forLoopsPhase, jvmBuiltInsPhase, collectionStubMethodLowering, singleAbstractMethodPhase),
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds new constructors, box, and unbox functions to inline classes as well as replacement
|
* Adds new constructors, box, and unbox functions to inline classes as well as replacement
|
||||||
* functions and bridges to avoid clashes between overloaded function. Changes call with
|
* functions and bridges to avoid clashes between overloaded function. Changes call with
|
||||||
@@ -37,10 +50,7 @@ import org.jetbrains.kotlin.resolve.JVM_INLINE_ANNOTATION_FQ_NAME
|
|||||||
* We do not unfold inline class types here. Instead, the type mapper will lower inline class
|
* We do not unfold inline class types here. Instead, the type mapper will lower inline class
|
||||||
* types to the types of their underlying field.
|
* types to the types of their underlying field.
|
||||||
*/
|
*/
|
||||||
internal class JvmInlineClassLowering(
|
internal class JvmInlineClassLowering(context: JvmBackendContext) : JvmValueClassAbstractLowering(context) {
|
||||||
context: JvmBackendContext,
|
|
||||||
scopeStack: MutableList<ScopeWithIr>,
|
|
||||||
) : JvmValueClassAbstractLowering(context, scopeStack) {
|
|
||||||
override val replacements: MemoizedValueClassAbstractReplacements
|
override val replacements: MemoizedValueClassAbstractReplacements
|
||||||
get() = context.inlineClassReplacements
|
get() = context.inlineClassReplacements
|
||||||
|
|
||||||
|
|||||||
+15
-5
@@ -5,9 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm.lower
|
package org.jetbrains.kotlin.backend.jvm.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.ScopeWithIr
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.ir.inline
|
import org.jetbrains.kotlin.backend.common.ir.inline
|
||||||
import org.jetbrains.kotlin.backend.common.lower.irCatch
|
import org.jetbrains.kotlin.backend.common.lower.irCatch
|
||||||
|
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||||
import org.jetbrains.kotlin.backend.common.pop
|
import org.jetbrains.kotlin.backend.common.pop
|
||||||
import org.jetbrains.kotlin.backend.common.push
|
import org.jetbrains.kotlin.backend.common.push
|
||||||
import org.jetbrains.kotlin.backend.jvm.*
|
import org.jetbrains.kotlin.backend.jvm.*
|
||||||
@@ -17,6 +18,7 @@ import org.jetbrains.kotlin.backend.jvm.MemoizedMultiFieldValueClassReplacements
|
|||||||
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
|
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.BlockOrBody.Block
|
import org.jetbrains.kotlin.backend.jvm.lower.BlockOrBody.Block
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
@@ -39,10 +41,18 @@ import org.jetbrains.kotlin.ir.visitors.*
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
|
||||||
internal class JvmMultiFieldValueClassLowering(
|
val jvmMultiFieldValueClassPhase = makeIrFilePhase(
|
||||||
context: JvmBackendContext,
|
{ c: JvmBackendContext ->
|
||||||
scopeStack: MutableList<ScopeWithIr>,
|
if (c.config.supportMultiFieldValueClasses)
|
||||||
) : JvmValueClassAbstractLowering(context, scopeStack) {
|
JvmMultiFieldValueClassLowering(c)
|
||||||
|
else
|
||||||
|
FileLoweringPass.Empty
|
||||||
|
},
|
||||||
|
name = "MultiFieldValueClasses",
|
||||||
|
description = "Lower multi-field value classes",
|
||||||
|
)
|
||||||
|
|
||||||
|
internal class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmValueClassAbstractLowering(context) {
|
||||||
|
|
||||||
private sealed class MfvcNodeInstanceAccessor {
|
private sealed class MfvcNodeInstanceAccessor {
|
||||||
abstract val instance: MfvcNodeInstance
|
abstract val instance: MfvcNodeInstance
|
||||||
|
|||||||
-1
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
|
|
||||||
internal abstract class JvmValueClassAbstractLowering(
|
internal abstract class JvmValueClassAbstractLowering(
|
||||||
val context: JvmBackendContext,
|
val context: JvmBackendContext,
|
||||||
override val scopeStack: MutableList<ScopeWithIr>,
|
|
||||||
) : FileLoweringPass, IrElementTransformerVoidWithContext() {
|
) : FileLoweringPass, IrElementTransformerVoidWithContext() {
|
||||||
abstract val replacements: MemoizedValueClassAbstractReplacements
|
abstract val replacements: MemoizedValueClassAbstractReplacements
|
||||||
|
|
||||||
|
|||||||
-225
@@ -1,225 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm.lower
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
|
||||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
|
||||||
import org.jetbrains.kotlin.backend.common.ScopeWithIr
|
|
||||||
import org.jetbrains.kotlin.backend.common.lower.loops.forLoopsPhase
|
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.MemoizedValueClassLoweringDispatcherSharedData.Access.Body
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.MemoizedValueClassLoweringDispatcherSharedData.Access.Header
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
|
||||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
|
||||||
import org.jetbrains.kotlin.ir.types.typeOrNull
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
|
||||||
|
|
||||||
val jvmValueClassPhase = makeIrFilePhase(
|
|
||||||
::JvmValueClassLoweringDispatcher,
|
|
||||||
name = "Value Classes",
|
|
||||||
description = "Lower value classes",
|
|
||||||
// forLoopsPhase may produce UInt and ULong which are inline classes.
|
|
||||||
// Standard library replacements are done on the not mangled names for UInt and ULong classes.
|
|
||||||
// Collection stubs may require mangling by value class rules.
|
|
||||||
// SAM wrappers may require mangling for fun interfaces with value class parameters
|
|
||||||
prerequisite = setOf(forLoopsPhase, jvmBuiltInsPhase, collectionStubMethodLowering, singleAbstractMethodPhase),
|
|
||||||
)
|
|
||||||
|
|
||||||
internal class JvmValueClassLoweringDispatcher(private val context: JvmBackendContext) : IrElementTransformerVoidWithContext(),
|
|
||||||
FileLoweringPass {
|
|
||||||
override val scopeStack: MutableList<ScopeWithIr> = mutableListOf()
|
|
||||||
private val inlineClassLowering: JvmInlineClassLowering = JvmInlineClassLowering(context, scopeStack)
|
|
||||||
private val multiFieldValueClassLowering: JvmMultiFieldValueClassLowering = JvmMultiFieldValueClassLowering(context, scopeStack)
|
|
||||||
|
|
||||||
|
|
||||||
override fun lower(irFile: IrFile) = withinScope(irFile) {
|
|
||||||
irFile.transformChildrenVoid()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitClassNew(declaration: IrClass): IrClass = if (declaration.requiresHandling()) {
|
|
||||||
declaration
|
|
||||||
.let(multiFieldValueClassLowering::visitClassNew)
|
|
||||||
.let(inlineClassLowering::visitClassNew)
|
|
||||||
} else {
|
|
||||||
declaration
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun IrElement.requiresHandling(): Boolean {
|
|
||||||
val visitor = NeedsToVisit(context)
|
|
||||||
accept(visitor, null)
|
|
||||||
return visitor.result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class NeedsToVisit(private val context: JvmBackendContext) : IrElementVisitorVoid {
|
|
||||||
var result = false
|
|
||||||
private val replacements = context.valueClassLoweringDispatcherSharedData
|
|
||||||
private val visitedParameters = mutableSetOf<IrSymbol>()
|
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) {
|
|
||||||
if (!result) element.acceptChildrenVoid(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun IrElement.acceptAndGetResult(): Boolean {
|
|
||||||
acceptVoid(this@NeedsToVisit)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private val IrClass.needsHandling: Boolean
|
|
||||||
get() = isValue || typeParameters.any { it.acceptAndGetResult() }
|
|
||||||
private val IrType.needsHandling: Boolean
|
|
||||||
get() = classifierOrNull?.isBound == true && erasedUpperBound.needsHandling || this is IrSimpleType && arguments.any { it.typeOrNull?.needsHandling == true }
|
|
||||||
|
|
||||||
override fun visitClass(declaration: IrClass) {
|
|
||||||
visitClassHeader(declaration)
|
|
||||||
if (result) return
|
|
||||||
visitClassBody(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun visitClassBody(declaration: IrClass) {
|
|
||||||
if (result) return
|
|
||||||
result = replacements.classResults.getOrPut(Body to declaration) {
|
|
||||||
declaration.declarations.any { it.acceptAndGetResult() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun visitClassHeader(declaration: IrClass) {
|
|
||||||
if (result) return
|
|
||||||
result = replacements.classResults.getOrPut(Header to declaration) {
|
|
||||||
declaration.needsHandling ||
|
|
||||||
declaration.typeParameters.any { it.acceptAndGetResult() } ||
|
|
||||||
declaration.superTypes.mapNotNull { (it.classifierOrNull as? IrClassSymbol)?.owner }.any { visitClassHeader(it); result }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFunction(declaration: IrFunction) = visitFunction(declaration, withBody = true)
|
|
||||||
|
|
||||||
private fun visitFunctionHeader(declaration: IrFunction) {
|
|
||||||
if (result) return
|
|
||||||
result = replacements.functionResults.getOrPut(Header to declaration) {
|
|
||||||
declaration.parent.let { it is IrClass && it.needsHandling } ||
|
|
||||||
declaration.typeParameters.any { it.acceptAndGetResult() } ||
|
|
||||||
declaration.dispatchReceiverParameter?.acceptAndGetResult() == true ||
|
|
||||||
declaration.extensionReceiverParameter?.acceptAndGetResult() == true ||
|
|
||||||
declaration.valueParameters.any { it.acceptAndGetResult() } ||
|
|
||||||
declaration.returnType.needsHandling ||
|
|
||||||
(declaration as? IrSimpleFunction)?.overriddenSymbols?.any { visitFunction(it.owner, withBody = false); result } == true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun visitFunction(declaration: IrFunction, withBody: Boolean) {
|
|
||||||
visitFunctionHeader(declaration)
|
|
||||||
if (result) return
|
|
||||||
if(withBody) visitFunctionBody(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun visitFunctionBody(declaration: IrFunction) {
|
|
||||||
if (result) return
|
|
||||||
result = replacements.functionResults.getOrPut(Body to declaration) {
|
|
||||||
declaration.body?.acceptAndGetResult() == true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitValueParameter(declaration: IrValueParameter) {
|
|
||||||
if (result || !visitedParameters.add(declaration.symbol)) return
|
|
||||||
result = declaration.type.needsHandling
|
|
||||||
if (result) return
|
|
||||||
super.visitValueParameter(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitTypeParameter(declaration: IrTypeParameter) {
|
|
||||||
if (result || !visitedParameters.add(declaration.symbol)) return
|
|
||||||
result = declaration.superTypes.any { it.needsHandling }
|
|
||||||
if (result) return
|
|
||||||
super.visitTypeParameter(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFunctionReference(expression: IrFunctionReference) {
|
|
||||||
if (result) return
|
|
||||||
visitFunction(expression.symbol.owner, withBody = false)
|
|
||||||
if (result) return
|
|
||||||
super.visitFunctionReference(expression)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFunctionAccess(expression: IrFunctionAccessExpression) {
|
|
||||||
if (result) return
|
|
||||||
visitFunction(expression.symbol.owner, withBody = false)
|
|
||||||
if (result) return
|
|
||||||
super.visitFunctionAccess(expression)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitField(declaration: IrField) = visitField(declaration, withBody = true)
|
|
||||||
|
|
||||||
private fun visitFieldHeader(declaration: IrField) {
|
|
||||||
if (result) return
|
|
||||||
result = replacements.fieldResults.getOrPut(Header to declaration) {
|
|
||||||
declaration.type.needsHandling
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun visitFieldBody(declaration: IrField) {
|
|
||||||
if (result) return
|
|
||||||
result = replacements.fieldResults.getOrPut(Body to declaration) {
|
|
||||||
super.visitField(declaration)
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun visitField(declaration: IrField, withBody: Boolean) {
|
|
||||||
visitFieldHeader(declaration)
|
|
||||||
if (withBody) visitFieldBody(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFieldAccess(expression: IrFieldAccessExpression) {
|
|
||||||
if (result) return
|
|
||||||
visitField(expression.symbol.owner, withBody = false)
|
|
||||||
if (result) return
|
|
||||||
super.visitFieldAccess(expression)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitVariable(declaration: IrVariable) {
|
|
||||||
if (result) return
|
|
||||||
result = declaration.type.needsHandling
|
|
||||||
if (result) return
|
|
||||||
super.visitVariable(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun visitStringConcatenation(expression: IrStringConcatenation) {
|
|
||||||
if (result) return
|
|
||||||
result = expression.arguments.any { it.type.needsHandling }
|
|
||||||
if (result) return
|
|
||||||
super.visitStringConcatenation(expression)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall) {
|
|
||||||
if (result) return
|
|
||||||
if (expression.symbol == context.irBuiltIns.eqeqSymbol) {
|
|
||||||
for (it in 0 until expression.valueArgumentsCount) {
|
|
||||||
result = expression.getValueArgument(it)?.type?.needsHandling ?: false
|
|
||||||
if (result) return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
super.visitCall(expression)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitExpression(expression: IrExpression) {
|
|
||||||
if (result) return
|
|
||||||
result = expression.type.needsHandling
|
|
||||||
if (result) return
|
|
||||||
super.visitExpression(expression)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -185,8 +185,6 @@ class JvmBackendContext(
|
|||||||
|
|
||||||
val multiFieldValueClassReplacements = MemoizedMultiFieldValueClassReplacements(irFactory, this)
|
val multiFieldValueClassReplacements = MemoizedMultiFieldValueClassReplacements(irFactory, this)
|
||||||
|
|
||||||
val valueClassLoweringDispatcherSharedData = MemoizedValueClassLoweringDispatcherSharedData()
|
|
||||||
|
|
||||||
val continuationClassesVarsCountByType: MutableMap<IrAttributeContainer, Map<Type, Int>> = hashMapOf()
|
val continuationClassesVarsCountByType: MutableMap<IrAttributeContainer, Map<Type, Int>> = hashMapOf()
|
||||||
|
|
||||||
val inlineMethodGenerationLock = Any()
|
val inlineMethodGenerationLock = Any()
|
||||||
|
|||||||
-20
@@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
|
||||||
import java.util.concurrent.ConcurrentMap
|
|
||||||
|
|
||||||
class MemoizedValueClassLoweringDispatcherSharedData {
|
|
||||||
enum class Access { Header, Body }
|
|
||||||
|
|
||||||
val functionResults: ConcurrentMap<Pair<Access, IrFunction>, Boolean> = ConcurrentHashMap()
|
|
||||||
val classResults: ConcurrentMap<Pair<Access, IrClass>, Boolean> = ConcurrentHashMap()
|
|
||||||
val fieldResults: ConcurrentMap<Pair<Access, IrField>, Boolean> = ConcurrentHashMap()
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user