[IR] Reduce memory pollution during by mangler
- Make some ObjCInterop utils garbage-free (cherry picked from commit 6388b9ca72c7f96f85df32cde4b53a262467333e)
This commit is contained in:
committed by
Vasily Levchenko
parent
7680722f23
commit
2c1e9a9e2d
+25
-12
@@ -14,8 +14,10 @@ import org.jetbrains.kotlin.backend.konan.descriptors.getStringValueOrNull
|
|||||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
import org.jetbrains.kotlin.backend.konan.ir.*
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||||
|
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -28,6 +30,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.types.typeUtil.supertypes
|
import org.jetbrains.kotlin.types.typeUtil.supertypes
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||||
|
|
||||||
internal val interopPackageName = InteropFqNames.packageName
|
internal val interopPackageName = InteropFqNames.packageName
|
||||||
internal val objCObjectFqName = interopPackageName.child(Name.identifier("ObjCObject"))
|
internal val objCObjectFqName = interopPackageName.child(Name.identifier("ObjCObject"))
|
||||||
@@ -40,17 +43,20 @@ private val objCFactoryFqName = interopPackageName.child(Name.identifier("ObjCFa
|
|||||||
private val objcnamesForwardDeclarationsPackageName = Name.identifier("objcnames")
|
private val objcnamesForwardDeclarationsPackageName = Name.identifier("objcnames")
|
||||||
|
|
||||||
fun ClassDescriptor.isObjCClass(): Boolean =
|
fun ClassDescriptor.isObjCClass(): Boolean =
|
||||||
this.getAllSuperClassifiers().any { it.fqNameSafe == objCObjectFqName } && // TODO: this is not cheap. Cache me!
|
this.containingDeclaration.fqNameSafe != interopPackageName &&
|
||||||
this.containingDeclaration.fqNameSafe != interopPackageName
|
this.getAllSuperClassifiers().any { it.fqNameSafe == objCObjectFqName } // TODO: this is not cheap. Cache me!
|
||||||
|
|
||||||
fun KotlinType.isObjCObjectType(): Boolean =
|
fun KotlinType.isObjCObjectType(): Boolean =
|
||||||
(this.supertypes() + this).any { TypeUtils.getClassDescriptor(it)?.fqNameSafe == objCObjectFqName }
|
(this.supertypes() + this).any { TypeUtils.getClassDescriptor(it)?.fqNameSafe == objCObjectFqName }
|
||||||
|
|
||||||
private fun IrClass.getAllSuperClassifiers(): List<IrClass> =
|
private fun IrClass.selfOrAnySuperClass(pred: (IrClass) -> Boolean): Boolean {
|
||||||
listOf(this) + this.superTypes.flatMap { (it.classifierOrFail.owner as IrClass).getAllSuperClassifiers() }
|
if (pred(this)) return true
|
||||||
|
|
||||||
internal fun IrClass.isObjCClass() = this.getAllSuperClassifiers().any { it.fqNameForIrSerialization == objCObjectFqName } &&
|
return superTypes.any { it.classOrNull!!.owner.selfOrAnySuperClass(pred) }
|
||||||
this.parent.fqNameForIrSerialization != interopPackageName
|
}
|
||||||
|
|
||||||
|
internal fun IrClass.isObjCClass() = this.parent.fqNameForIrSerialization != interopPackageName &&
|
||||||
|
selfOrAnySuperClass { it.fqNameForIrSerialization == objCObjectFqName }
|
||||||
|
|
||||||
fun ClassDescriptor.isExternalObjCClass(): Boolean = this.isObjCClass() &&
|
fun ClassDescriptor.isExternalObjCClass(): Boolean = this.isObjCClass() &&
|
||||||
this.parentsWithSelf.filterIsInstance<ClassDescriptor>().any {
|
this.parentsWithSelf.filterIsInstance<ClassDescriptor>().any {
|
||||||
@@ -68,7 +74,7 @@ fun ClassDescriptor.isObjCMetaClass(): Boolean = this.getAllSuperClassifiers().a
|
|||||||
it.fqNameSafe == objCClassFqName
|
it.fqNameSafe == objCClassFqName
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IrClass.isObjCMetaClass(): Boolean = this.getAllSuperClassifiers().any {
|
fun IrClass.isObjCMetaClass(): Boolean = selfOrAnySuperClass {
|
||||||
it.fqNameForIrSerialization == objCClassFqName
|
it.fqNameForIrSerialization == objCClassFqName
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +148,7 @@ private fun FunctionDescriptor.getObjCMethodInfo(onlyExternal: Boolean): ObjCMet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.overriddenDescriptors.asSequence().mapNotNull { it.getObjCMethodInfo(onlyExternal) }.firstOrNull()
|
return overriddenDescriptors.firstNotNullResult { it.getObjCMethodInfo(onlyExternal) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -157,7 +163,7 @@ private fun IrSimpleFunction.getObjCMethodInfo(onlyExternal: Boolean): ObjCMetho
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.overriddenSymbols.mapNotNull { it.owner.getObjCMethodInfo(onlyExternal) }.firstOrNull()
|
return overriddenSymbols.firstNotNullResult { it.owner.getObjCMethodInfo(onlyExternal) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FunctionDescriptor.getExternalObjCMethodInfo(): ObjCMethodInfo? = this.getObjCMethodInfo(onlyExternal = true)
|
fun FunctionDescriptor.getExternalObjCMethodInfo(): ObjCMethodInfo? = this.getObjCMethodInfo(onlyExternal = true)
|
||||||
@@ -268,9 +274,16 @@ fun IrConstructor.getObjCInitMethod(): IrSimpleFunction? {
|
|||||||
fun ConstructorDescriptor.getObjCInitMethod(): FunctionDescriptor? {
|
fun ConstructorDescriptor.getObjCInitMethod(): FunctionDescriptor? {
|
||||||
return this.annotations.findAnnotation(objCConstructorFqName)?.let {
|
return this.annotations.findAnnotation(objCConstructorFqName)?.let {
|
||||||
val initSelector = it.getAnnotationStringValue("initSelector")
|
val initSelector = it.getAnnotationStringValue("initSelector")
|
||||||
this.constructedClass.unsubstitutedMemberScope.getContributedDescriptors().asSequence()
|
val memberScope = constructedClass.unsubstitutedMemberScope
|
||||||
.filterIsInstance<FunctionDescriptor>()
|
val functionNames = memberScope.getFunctionNames()
|
||||||
.single { it.getExternalObjCMethodInfo()?.selector == initSelector }
|
for (name in functionNames) {
|
||||||
|
val functions = memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND)
|
||||||
|
for (function in functions) {
|
||||||
|
val objectInfo = function.getExternalObjCMethodInfo() ?: continue
|
||||||
|
if (objectInfo.selector == initSelector) return function
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error("Cannot find ObjInitMethod for $this")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user