Speed up interpreter's intrinsic check by introducing map of handlers
This commit is contained in:
committed by
TeamCityServer
parent
bc9b2fd78b
commit
a630273af2
+9
-11
@@ -11,20 +11,18 @@ import org.jetbrains.kotlin.ir.interpreter.IrInterpreterEnvironment
|
||||
import org.jetbrains.kotlin.ir.interpreter.fqName
|
||||
|
||||
internal object IntrinsicEvaluator {
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private val fqNameToHandler: Map<String, IntrinsicBase> = buildMap {
|
||||
listOf(
|
||||
EmptyArray, ArrayOf, ArrayOfNulls, ArrayConstructor, EnumValues, EnumValueOf,
|
||||
JsPrimitives, SourceLocation, AssertIntrinsic, DataClassArrayToString
|
||||
).forEach { intrinsic -> intrinsic.getListOfAcceptableFunctions().forEach { put(it, intrinsic) } }
|
||||
}
|
||||
|
||||
fun unwindInstructions(irFunction: IrFunction, environment: IrInterpreterEnvironment): List<Instruction>? {
|
||||
val fqName = irFunction.fqName
|
||||
return when {
|
||||
EmptyArray.canHandleFunctionWithName(fqName, irFunction.origin) -> EmptyArray.unwind(irFunction, environment)
|
||||
ArrayOf.canHandleFunctionWithName(fqName, irFunction.origin) -> ArrayOf.unwind(irFunction, environment)
|
||||
ArrayOfNulls.canHandleFunctionWithName(fqName, irFunction.origin) -> ArrayOfNulls.unwind(irFunction, environment)
|
||||
EnumValues.canHandleFunctionWithName(fqName, irFunction.origin) -> EnumValues.unwind(irFunction, environment)
|
||||
EnumValueOf.canHandleFunctionWithName(fqName, irFunction.origin) -> EnumValueOf.unwind(irFunction, environment)
|
||||
return fqNameToHandler[fqName]?.unwind(irFunction, environment) ?: when {
|
||||
EnumIntrinsics.canHandleFunctionWithName(fqName, irFunction.origin) -> EnumIntrinsics.unwind(irFunction, environment)
|
||||
JsPrimitives.canHandleFunctionWithName(fqName, irFunction.origin) -> JsPrimitives.unwind(irFunction, environment)
|
||||
ArrayConstructor.canHandleFunctionWithName(fqName, irFunction.origin) -> ArrayConstructor.unwind(irFunction, environment)
|
||||
SourceLocation.canHandleFunctionWithName(fqName, irFunction.origin) -> SourceLocation.unwind(irFunction, environment)
|
||||
AssertIntrinsic.canHandleFunctionWithName(fqName, irFunction.origin) -> AssertIntrinsic.unwind(irFunction, environment)
|
||||
DataClassArrayToString.canHandleFunctionWithName(fqName, irFunction.origin) -> DataClassArrayToString.unwind(irFunction, environment)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
+35
-22
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.types.Variance
|
||||
import java.util.*
|
||||
|
||||
internal sealed class IntrinsicBase {
|
||||
abstract fun canHandleFunctionWithName(fqName: String, origin: IrDeclarationOrigin): Boolean
|
||||
abstract fun getListOfAcceptableFunctions(): List<String>
|
||||
abstract fun evaluate(irFunction: IrFunction, environment: IrInterpreterEnvironment)
|
||||
open fun unwind(irFunction: IrFunction, environment: IrInterpreterEnvironment): List<Instruction> {
|
||||
return listOf(customEvaluateInstruction(irFunction, environment))
|
||||
@@ -38,8 +38,8 @@ internal sealed class IntrinsicBase {
|
||||
}
|
||||
|
||||
internal object EmptyArray : IntrinsicBase() {
|
||||
override fun canHandleFunctionWithName(fqName: String, origin: IrDeclarationOrigin): Boolean {
|
||||
return fqName in setOf("kotlin.emptyArray", "kotlin.ArrayIntrinsicsKt.emptyArray")
|
||||
override fun getListOfAcceptableFunctions(): List<String> {
|
||||
return listOf("kotlin.emptyArray", "kotlin.ArrayIntrinsicsKt.emptyArray")
|
||||
}
|
||||
|
||||
override fun evaluate(irFunction: IrFunction, environment: IrInterpreterEnvironment) {
|
||||
@@ -49,8 +49,11 @@ internal object EmptyArray : IntrinsicBase() {
|
||||
}
|
||||
|
||||
internal object ArrayOf : IntrinsicBase() {
|
||||
override fun canHandleFunctionWithName(fqName: String, origin: IrDeclarationOrigin): Boolean {
|
||||
return fqName == "kotlin.arrayOf" || fqName.matches("kotlin\\.(byte|char|short|int|long|float|double|boolean|)ArrayOf".toRegex())
|
||||
override fun getListOfAcceptableFunctions(): List<String> {
|
||||
return listOf(
|
||||
"kotlin.arrayOf", "kotlin.byteArrayOf", "kotlin.charArrayOf", "kotlin.shortArrayOf", "kotlin.intArrayOf",
|
||||
"kotlin.longArrayOf", "kotlin.floatArrayOf", "kotlin.doubleArrayOf", "kotlin.booleanArrayOf"
|
||||
)
|
||||
}
|
||||
|
||||
override fun evaluate(irFunction: IrFunction, environment: IrInterpreterEnvironment) {
|
||||
@@ -61,8 +64,8 @@ internal object ArrayOf : IntrinsicBase() {
|
||||
}
|
||||
|
||||
internal object ArrayOfNulls : IntrinsicBase() {
|
||||
override fun canHandleFunctionWithName(fqName: String, origin: IrDeclarationOrigin): Boolean {
|
||||
return fqName == "kotlin.arrayOfNulls"
|
||||
override fun getListOfAcceptableFunctions(): List<String> {
|
||||
return listOf("kotlin.arrayOfNulls")
|
||||
}
|
||||
|
||||
override fun evaluate(irFunction: IrFunction, environment: IrInterpreterEnvironment) {
|
||||
@@ -78,8 +81,8 @@ internal object ArrayOfNulls : IntrinsicBase() {
|
||||
}
|
||||
|
||||
internal object EnumValues : IntrinsicBase() {
|
||||
override fun canHandleFunctionWithName(fqName: String, origin: IrDeclarationOrigin): Boolean {
|
||||
return fqName == "kotlin.enumValues"
|
||||
override fun getListOfAcceptableFunctions(): List<String> {
|
||||
return listOf("kotlin.enumValues")
|
||||
}
|
||||
|
||||
private fun getEnumClass(irFunction: IrFunction, environment: IrInterpreterEnvironment): IrClass {
|
||||
@@ -108,8 +111,8 @@ internal object EnumValues : IntrinsicBase() {
|
||||
}
|
||||
|
||||
internal object EnumValueOf : IntrinsicBase() {
|
||||
override fun canHandleFunctionWithName(fqName: String, origin: IrDeclarationOrigin): Boolean {
|
||||
return fqName == "kotlin.enumValueOf"
|
||||
override fun getListOfAcceptableFunctions(): List<String> {
|
||||
return listOf("kotlin.enumValueOf")
|
||||
}
|
||||
|
||||
private fun getEnumClass(irFunction: IrFunction, environment: IrInterpreterEnvironment): IrClass {
|
||||
@@ -144,7 +147,13 @@ internal object EnumValueOf : IntrinsicBase() {
|
||||
}
|
||||
|
||||
internal object EnumIntrinsics : IntrinsicBase() {
|
||||
override fun canHandleFunctionWithName(fqName: String, origin: IrDeclarationOrigin): Boolean {
|
||||
override fun getListOfAcceptableFunctions(): List<String> {
|
||||
// functions that can be handled by this intrinsic cannot be described by single string
|
||||
// must call instead `canHandleFunctionWithName` method
|
||||
return listOf()
|
||||
}
|
||||
|
||||
fun canHandleFunctionWithName(fqName: String, origin: IrDeclarationOrigin): Boolean {
|
||||
if (origin == IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER) return true
|
||||
return fqName.startsWith("kotlin.Enum.")
|
||||
}
|
||||
@@ -188,8 +197,8 @@ internal object EnumIntrinsics : IntrinsicBase() {
|
||||
}
|
||||
|
||||
internal object JsPrimitives : IntrinsicBase() {
|
||||
override fun canHandleFunctionWithName(fqName: String, origin: IrDeclarationOrigin): Boolean {
|
||||
return fqName == "kotlin.Long.<init>" || fqName == "kotlin.Char.<init>"
|
||||
override fun getListOfAcceptableFunctions(): List<String> {
|
||||
return listOf("kotlin.Long.<init>", "kotlin.Char.<init>")
|
||||
}
|
||||
|
||||
override fun evaluate(irFunction: IrFunction, environment: IrInterpreterEnvironment) {
|
||||
@@ -208,8 +217,12 @@ internal object JsPrimitives : IntrinsicBase() {
|
||||
}
|
||||
|
||||
internal object ArrayConstructor : IntrinsicBase() {
|
||||
override fun canHandleFunctionWithName(fqName: String, origin: IrDeclarationOrigin): Boolean {
|
||||
return fqName.matches("kotlin\\.(Byte|Char|Short|Int|Long|Float|Double|Boolean|)Array\\.<init>".toRegex())
|
||||
override fun getListOfAcceptableFunctions(): List<String> {
|
||||
return listOf(
|
||||
"kotlin.Array.<init>",
|
||||
"kotlin.ByteArray.<init>", "kotlin.CharArray.<init>", "kotlin.ShortArray.<init>", "kotlin.IntArray.<init>",
|
||||
"kotlin.LongArray.<init>", "kotlin.FloatArray.<init>", "kotlin.DoubleArray.<init>", "kotlin.BooleanArray.<init>"
|
||||
)
|
||||
}
|
||||
|
||||
override fun unwind(irFunction: IrFunction, environment: IrInterpreterEnvironment): List<Instruction> {
|
||||
@@ -271,8 +284,8 @@ internal object ArrayConstructor : IntrinsicBase() {
|
||||
}
|
||||
|
||||
internal object SourceLocation : IntrinsicBase() {
|
||||
override fun canHandleFunctionWithName(fqName: String, origin: IrDeclarationOrigin): Boolean {
|
||||
return fqName == "kotlin.experimental.sourceLocation" || fqName == "kotlin.experimental.SourceLocationKt.sourceLocation"
|
||||
override fun getListOfAcceptableFunctions(): List<String> {
|
||||
return listOf("kotlin.experimental.sourceLocation", "kotlin.experimental.SourceLocationKt.sourceLocation")
|
||||
}
|
||||
|
||||
override fun evaluate(irFunction: IrFunction, environment: IrInterpreterEnvironment) {
|
||||
@@ -281,8 +294,8 @@ internal object SourceLocation : IntrinsicBase() {
|
||||
}
|
||||
|
||||
internal object AssertIntrinsic : IntrinsicBase() {
|
||||
override fun canHandleFunctionWithName(fqName: String, origin: IrDeclarationOrigin): Boolean {
|
||||
return fqName == "kotlin.PreconditionsKt.assert"
|
||||
override fun getListOfAcceptableFunctions(): List<String> {
|
||||
return listOf("kotlin.PreconditionsKt.assert")
|
||||
}
|
||||
|
||||
override fun unwind(irFunction: IrFunction, environment: IrInterpreterEnvironment): List<Instruction> {
|
||||
@@ -307,8 +320,8 @@ internal object AssertIntrinsic : IntrinsicBase() {
|
||||
}
|
||||
|
||||
internal object DataClassArrayToString : IntrinsicBase() {
|
||||
override fun canHandleFunctionWithName(fqName: String, origin: IrDeclarationOrigin): Boolean {
|
||||
return fqName == "kotlin.internal.ir.dataClassArrayMemberToString"
|
||||
override fun getListOfAcceptableFunctions(): List<String> {
|
||||
return listOf("kotlin.internal.ir.dataClassArrayMemberToString")
|
||||
}
|
||||
|
||||
private fun arrayToString(array: Any?): String {
|
||||
|
||||
+4
-10
@@ -108,15 +108,10 @@ internal class Wrapper(val value: Any, override val irClass: IrClass, environmen
|
||||
"Array.kotlin.collections.copyToArrayOfAny(Boolean)" to "kotlin.collections.CollectionsKt",
|
||||
)
|
||||
|
||||
private fun IrDeclarationWithName.getSignature(): String {
|
||||
private fun IrFunction.getSignature(): String {
|
||||
val fqName = this.fqName
|
||||
return when (this) {
|
||||
is IrFunction -> {
|
||||
val receiver = (dispatchReceiverParameter ?: extensionReceiverParameter)?.type?.getOnlyName()?.let { "$it." } ?: ""
|
||||
this.valueParameters.joinToString(prefix = "$receiver$fqName(", postfix = ")") { it.type.getOnlyName() }
|
||||
}
|
||||
else -> fqName
|
||||
}
|
||||
val receiver = (dispatchReceiverParameter ?: extensionReceiverParameter)?.type?.getOnlyName()?.let { "$it." } ?: ""
|
||||
return this.valueParameters.joinToString(prefix = "$receiver$fqName(", postfix = ")") { it.type.getOnlyName() }
|
||||
}
|
||||
|
||||
private fun IrFunction.getJvmClassName(): String? {
|
||||
@@ -124,10 +119,9 @@ internal class Wrapper(val value: Any, override val irClass: IrClass, environmen
|
||||
}
|
||||
|
||||
fun mustBeHandledWithWrapper(declaration: IrDeclarationWithName): Boolean {
|
||||
val fqName = declaration.fqName
|
||||
return when (declaration) {
|
||||
is IrFunction -> declaration.getSignature() in intrinsicFunctionToHandler
|
||||
else -> fqName in intrinsicClasses || fqName.startsWith("java")
|
||||
else -> declaration.fqName.let { it in intrinsicClasses || it.startsWith("java") }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user