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)
|
||||
|
||||
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()
|
||||
|
||||
|
||||
+61
-46
@@ -32,10 +32,9 @@ import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class JvmCachedDeclarations(
|
||||
private val context: JvmBackendContext,
|
||||
private val languageVersionSettings: LanguageVersionSettings
|
||||
val fieldsForObjectInstances: CachedFieldsForObjectInstances,
|
||||
) {
|
||||
private val singletonFieldDeclarations = ConcurrentHashMap<IrSymbolOwner, IrField>()
|
||||
private val interfaceCompanionFieldDeclarations = ConcurrentHashMap<IrSymbolOwner, IrField>()
|
||||
private val staticBackingFields = ConcurrentHashMap<IrProperty, IrField>()
|
||||
private val staticCompanionDeclarations = ConcurrentHashMap<IrSimpleFunction, Pair<IrSimpleFunction, IrSimpleFunction>>()
|
||||
|
||||
@@ -58,50 +57,9 @@ class JvmCachedDeclarations(
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
}
|
||||
fun getFieldForObjectInstance(singleton: IrClass): IrField = fieldsForObjectInstances.getFieldForObjectInstance(singleton)
|
||||
|
||||
}.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) {
|
||||
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 getPrivateFieldForObjectInstance(singleton: IrClass): IrField = fieldsForObjectInstances.getPrivateFieldForObjectInstance(singleton)
|
||||
|
||||
fun getStaticBackingField(irProperty: IrProperty): IrField? {
|
||||
// Only fields defined directly in objects should be made static.
|
||||
@@ -136,7 +94,7 @@ class JvmCachedDeclarations(
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -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.lower.IrLoweringContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
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.*
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineOnly
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.representativeUpperBound
|
||||
@@ -232,7 +229,7 @@ fun IrExpression.isSmartcastFromHigherThanNullable(context: JvmBackendContext):
|
||||
}
|
||||
|
||||
fun IrElement.replaceThisByStaticReference(
|
||||
cachedDeclarations: JvmCachedDeclarations,
|
||||
cachedFields: CachedFieldsForObjectInstances,
|
||||
irClass: IrClass,
|
||||
oldThisReceiverParameter: IrValueParameter
|
||||
) {
|
||||
@@ -242,7 +239,7 @@ fun IrElement.replaceThisByStaticReference(
|
||||
IrGetFieldImpl(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
cachedDeclarations.getPrivateFieldForObjectInstance(irClass).symbol,
|
||||
cachedFields.getPrivateFieldForObjectInstance(irClass).symbol,
|
||||
irClass.defaultType
|
||||
)
|
||||
} 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
|
||||
function.dispatchReceiverParameter?.let { oldDispatchReceiverParameter ->
|
||||
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 {
|
||||
parent = 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