JVM_IR: extract cached fields into a separate class
This commit is contained in:
committed by
TeamCityServer
parent
50068607b9
commit
a328ebc889
@@ -67,7 +67,7 @@ class JvmBackendContext(
|
|||||||
val methodSignatureMapper = MethodSignatureMapper(this)
|
val methodSignatureMapper = MethodSignatureMapper(this)
|
||||||
|
|
||||||
internal val innerClassesSupport = JvmInnerClassesSupport(irFactory)
|
internal val innerClassesSupport = JvmInnerClassesSupport(irFactory)
|
||||||
internal val cachedDeclarations = JvmCachedDeclarations(this, state.languageVersionSettings)
|
internal val cachedDeclarations = JvmCachedDeclarations(this, CachedFieldsForObjectInstances(irFactory, state.languageVersionSettings))
|
||||||
|
|
||||||
override val mapping: Mapping = DefaultMapping()
|
override val mapping: Mapping = DefaultMapping()
|
||||||
|
|
||||||
|
|||||||
+61
-46
@@ -32,10 +32,9 @@ import java.util.concurrent.ConcurrentHashMap
|
|||||||
|
|
||||||
class JvmCachedDeclarations(
|
class JvmCachedDeclarations(
|
||||||
private val context: JvmBackendContext,
|
private val context: JvmBackendContext,
|
||||||
private val languageVersionSettings: LanguageVersionSettings
|
val fieldsForObjectInstances: CachedFieldsForObjectInstances,
|
||||||
) {
|
) {
|
||||||
private val singletonFieldDeclarations = ConcurrentHashMap<IrSymbolOwner, IrField>()
|
private val singletonFieldDeclarations = ConcurrentHashMap<IrSymbolOwner, IrField>()
|
||||||
private val interfaceCompanionFieldDeclarations = ConcurrentHashMap<IrSymbolOwner, IrField>()
|
|
||||||
private val staticBackingFields = ConcurrentHashMap<IrProperty, IrField>()
|
private val staticBackingFields = ConcurrentHashMap<IrProperty, IrField>()
|
||||||
private val staticCompanionDeclarations = ConcurrentHashMap<IrSimpleFunction, Pair<IrSimpleFunction, IrSimpleFunction>>()
|
private val staticCompanionDeclarations = ConcurrentHashMap<IrSimpleFunction, Pair<IrSimpleFunction, IrSimpleFunction>>()
|
||||||
|
|
||||||
@@ -58,50 +57,9 @@ class JvmCachedDeclarations(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFieldForObjectInstance(singleton: IrClass): IrField =
|
fun getFieldForObjectInstance(singleton: IrClass): IrField = fieldsForObjectInstances.getFieldForObjectInstance(singleton)
|
||||||
singletonFieldDeclarations.getOrPut(singleton) {
|
|
||||||
val originalVisibility = singleton.visibility
|
|
||||||
val isNotMappedCompanion = singleton.isCompanion && !singleton.isMappedIntrinsicCompanionObject()
|
|
||||||
val useProperVisibilityForCompanion =
|
|
||||||
languageVersionSettings.supportsFeature(LanguageFeature.ProperVisibilityForCompanionObjectInstanceField)
|
|
||||||
&& singleton.isCompanion
|
|
||||||
&& !singleton.parentAsClass.isInterface
|
|
||||||
context.irFactory.buildField {
|
|
||||||
name = if (isNotMappedCompanion) singleton.name else Name.identifier(JvmAbi.INSTANCE_FIELD)
|
|
||||||
type = singleton.defaultType
|
|
||||||
origin = IrDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE
|
|
||||||
isFinal = true
|
|
||||||
isStatic = true
|
|
||||||
visibility = when {
|
|
||||||
!useProperVisibilityForCompanion -> DescriptorVisibilities.PUBLIC
|
|
||||||
originalVisibility == DescriptorVisibilities.PROTECTED -> JavaDescriptorVisibilities.PROTECTED_STATIC_VISIBILITY
|
|
||||||
else -> originalVisibility
|
|
||||||
}
|
|
||||||
|
|
||||||
}.apply {
|
fun getPrivateFieldForObjectInstance(singleton: IrClass): IrField = fieldsForObjectInstances.getPrivateFieldForObjectInstance(singleton)
|
||||||
parent = if (isNotMappedCompanion) singleton.parent else singleton
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun IrClass.isMappedIntrinsicCompanionObject() =
|
|
||||||
isCompanion && classId?.let { CompanionObjectMapping.isMappedIntrinsicCompanionObjectClassId(it) } == true
|
|
||||||
|
|
||||||
fun getPrivateFieldForObjectInstance(singleton: IrClass): IrField =
|
|
||||||
if (singleton.isCompanion && singleton.parentAsClass.isJvmInterface)
|
|
||||||
interfaceCompanionFieldDeclarations.getOrPut(singleton) {
|
|
||||||
context.irFactory.buildField {
|
|
||||||
name = Name.identifier("\$\$INSTANCE")
|
|
||||||
type = singleton.defaultType
|
|
||||||
origin = JvmLoweredDeclarationOrigin.INTERFACE_COMPANION_PRIVATE_INSTANCE
|
|
||||||
isFinal = true
|
|
||||||
isStatic = true
|
|
||||||
visibility = JavaDescriptorVisibilities.PACKAGE_VISIBILITY
|
|
||||||
}.apply {
|
|
||||||
parent = singleton
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
getFieldForObjectInstance(singleton)
|
|
||||||
|
|
||||||
fun getStaticBackingField(irProperty: IrProperty): IrField? {
|
fun getStaticBackingField(irProperty: IrProperty): IrField? {
|
||||||
// Only fields defined directly in objects should be made static.
|
// Only fields defined directly in objects should be made static.
|
||||||
@@ -136,7 +94,7 @@ class JvmCachedDeclarations(
|
|||||||
}
|
}
|
||||||
|
|
||||||
initializer = oldField.initializer?.patchDeclarationParents(this)
|
initializer = oldField.initializer?.patchDeclarationParents(this)
|
||||||
oldField.replaceThisByStaticReference(this@JvmCachedDeclarations, oldParent, oldParent.thisReceiver!!)
|
oldField.replaceThisByStaticReference(fieldsForObjectInstances, oldParent, oldParent.thisReceiver!!)
|
||||||
origin = if (irProperty.parentAsClass.isCompanion) JvmLoweredDeclarationOrigin.COMPANION_PROPERTY_BACKING_FIELD else origin
|
origin = if (irProperty.parentAsClass.isCompanion) JvmLoweredDeclarationOrigin.COMPANION_PROPERTY_BACKING_FIELD else origin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,3 +273,60 @@ class JvmCachedDeclarations(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This class keeps track of singleton fields for instances of object classes.
|
||||||
|
*/
|
||||||
|
class CachedFieldsForObjectInstances(
|
||||||
|
private val irFactory: IrFactory,
|
||||||
|
private val languageVersionSettings: LanguageVersionSettings,
|
||||||
|
) {
|
||||||
|
private val singletonFieldDeclarations = ConcurrentHashMap<IrSymbolOwner, IrField>()
|
||||||
|
private val interfaceCompanionFieldDeclarations = ConcurrentHashMap<IrSymbolOwner, IrField>()
|
||||||
|
|
||||||
|
fun getFieldForObjectInstance(singleton: IrClass): IrField =
|
||||||
|
singletonFieldDeclarations.getOrPut(singleton) {
|
||||||
|
val originalVisibility = singleton.visibility
|
||||||
|
val isNotMappedCompanion = singleton.isCompanion && !singleton.isMappedIntrinsicCompanionObject()
|
||||||
|
val useProperVisibilityForCompanion =
|
||||||
|
languageVersionSettings.supportsFeature(LanguageFeature.ProperVisibilityForCompanionObjectInstanceField)
|
||||||
|
&& singleton.isCompanion
|
||||||
|
&& !singleton.parentAsClass.isInterface
|
||||||
|
irFactory.buildField {
|
||||||
|
name = if (isNotMappedCompanion) singleton.name else Name.identifier(JvmAbi.INSTANCE_FIELD)
|
||||||
|
type = singleton.defaultType
|
||||||
|
origin = IrDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE
|
||||||
|
isFinal = true
|
||||||
|
isStatic = true
|
||||||
|
visibility = when {
|
||||||
|
!useProperVisibilityForCompanion -> DescriptorVisibilities.PUBLIC
|
||||||
|
originalVisibility == DescriptorVisibilities.PROTECTED -> JavaDescriptorVisibilities.PROTECTED_STATIC_VISIBILITY
|
||||||
|
else -> originalVisibility
|
||||||
|
}
|
||||||
|
|
||||||
|
}.apply {
|
||||||
|
parent = if (isNotMappedCompanion) singleton.parent else singleton
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrClass.isMappedIntrinsicCompanionObject() =
|
||||||
|
isCompanion && classId?.let { CompanionObjectMapping.isMappedIntrinsicCompanionObjectClassId(it) } == true
|
||||||
|
|
||||||
|
fun getPrivateFieldForObjectInstance(singleton: IrClass): IrField =
|
||||||
|
if (singleton.isCompanion && singleton.parentAsClass.isJvmInterface)
|
||||||
|
interfaceCompanionFieldDeclarations.getOrPut(singleton) {
|
||||||
|
irFactory.buildField {
|
||||||
|
name = Name.identifier("\$\$INSTANCE")
|
||||||
|
type = singleton.defaultType
|
||||||
|
origin = JvmLoweredDeclarationOrigin.INTERFACE_COMPANION_PRIVATE_INSTANCE
|
||||||
|
isFinal = true
|
||||||
|
isStatic = true
|
||||||
|
visibility = JavaDescriptorVisibilities.PACKAGE_VISIBILITY
|
||||||
|
}.apply {
|
||||||
|
parent = singleton
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
getFieldForObjectInstance(singleton)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.ir
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||||
import org.jetbrains.kotlin.backend.common.lower.IrLoweringContext
|
import org.jetbrains.kotlin.backend.common.lower.IrLoweringContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.*
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmCachedDeclarations
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmSymbols
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineOnly
|
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineOnly
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.representativeUpperBound
|
import org.jetbrains.kotlin.backend.jvm.codegen.representativeUpperBound
|
||||||
@@ -232,7 +229,7 @@ fun IrExpression.isSmartcastFromHigherThanNullable(context: JvmBackendContext):
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun IrElement.replaceThisByStaticReference(
|
fun IrElement.replaceThisByStaticReference(
|
||||||
cachedDeclarations: JvmCachedDeclarations,
|
cachedFields: CachedFieldsForObjectInstances,
|
||||||
irClass: IrClass,
|
irClass: IrClass,
|
||||||
oldThisReceiverParameter: IrValueParameter
|
oldThisReceiverParameter: IrValueParameter
|
||||||
) {
|
) {
|
||||||
@@ -242,7 +239,7 @@ fun IrElement.replaceThisByStaticReference(
|
|||||||
IrGetFieldImpl(
|
IrGetFieldImpl(
|
||||||
expression.startOffset,
|
expression.startOffset,
|
||||||
expression.endOffset,
|
expression.endOffset,
|
||||||
cachedDeclarations.getPrivateFieldForObjectInstance(irClass).symbol,
|
cachedFields.getPrivateFieldForObjectInstance(irClass).symbol,
|
||||||
irClass.defaultType
|
irClass.defaultType
|
||||||
)
|
)
|
||||||
} else super.visitGetValue(expression)
|
} else super.visitGetValue(expression)
|
||||||
|
|||||||
+3
-1
@@ -87,7 +87,9 @@ private class SingletonObjectJvmStaticTransformer(val context: JvmBackendContext
|
|||||||
// dispatch receiver parameter is already null for synthetic property annotation methods
|
// dispatch receiver parameter is already null for synthetic property annotation methods
|
||||||
function.dispatchReceiverParameter?.let { oldDispatchReceiverParameter ->
|
function.dispatchReceiverParameter?.let { oldDispatchReceiverParameter ->
|
||||||
function.dispatchReceiverParameter = null
|
function.dispatchReceiverParameter = null
|
||||||
function.replaceThisByStaticReference(context.cachedDeclarations, declaration, oldDispatchReceiverParameter)
|
function.replaceThisByStaticReference(
|
||||||
|
context.cachedDeclarations.fieldsForObjectInstances, declaration, oldDispatchReceiverParameter
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ private class MoveOrCopyCompanionObjectFieldsLowering(val context: JvmBackendCon
|
|||||||
IrAnonymousInitializerImpl(startOffset, endOffset, origin, newSymbol, isStatic = true).apply {
|
IrAnonymousInitializerImpl(startOffset, endOffset, origin, newSymbol, isStatic = true).apply {
|
||||||
parent = newParent
|
parent = newParent
|
||||||
body = this@with.body.patchDeclarationParents(newParent)
|
body = this@with.body.patchDeclarationParents(newParent)
|
||||||
replaceThisByStaticReference(context.cachedDeclarations, oldParent, oldParent.thisReceiver!!)
|
replaceThisByStaticReference(context.cachedDeclarations.fieldsForObjectInstances, oldParent, oldParent.thisReceiver!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user