JVM_IR fix string concatenation performance issues

KT-50080 KT-50084 KT-50140
This commit is contained in:
Dmitry Petrov
2021-12-08 18:09:52 +03:00
committed by TeamCityServer
parent fa41e0f5a9
commit 3017397960
18 changed files with 451 additions and 34 deletions
@@ -0,0 +1,31 @@
// KOTLIN_CONFIGURATION_FLAGS: STRING_CONCAT=inline
// WITH_STDLIB
// IGNORE_BACKEND: WASM
// ^ wasm-function[2283]:0x218da: RuntimeError: wasm exception
import kotlin.test.assertEquals
fun <T : Boolean?> concatNBoolean(x: T) = "[[$x]]"
fun <T : Byte?> concatNByte(x: T) = "[[$x]]"
fun <T : Short?> concatNShort(x: T) = "[[$x]]"
fun <T : Int?> concatNInt(x: T) = "[[$x]]"
fun <T : Long?> concatNLong(x: T) = "[[$x]]"
fun <T : Float?> concatNFloat(x: T) = "[[$x]]"
fun <T : Double?> concatNDouble(x: T) = "[[$x]]"
fun box(): String {
assertEquals("[[true]]", concatNBoolean(true))
assertEquals("[[0]]", concatNByte(0.toByte()))
assertEquals("[[1]]", concatNShort(1.toShort()))
assertEquals("[[2]]", concatNInt(2))
assertEquals("[[3]]", concatNLong(3L))
assertEquals("[[4.4]]", concatNFloat(4.4f))
assertEquals("[[5.5]]", concatNFloat(5.5f))
return "OK"
}
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 7 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Ljava/lang/Object;\)Ljava/lang/StringBuilder;
@@ -0,0 +1,35 @@
// KOTLIN_CONFIGURATION_FLAGS: STRING_CONCAT=inline
// WITH_STDLIB
// IGNORE_BACKEND: WASM
// ^ wasm-function[2283]:0x218cc: RuntimeError: wasm exception
import kotlin.test.assertEquals
fun <T : Boolean> concatBoolean(x: T) = "[[$x]]"
fun <T : Byte> concatByte(x: T) = "[[$x]]"
fun <T : Short> concatShort(x: T) = "[[$x]]"
fun <T : Int> concatInt(x: T) = "[[$x]]"
fun <T : Long> concatLong(x: T) = "[[$x]]"
fun <T : Float> concatFloat(x: T) = "[[$x]]"
fun <T : Double> concatDouble(x: T) = "[[$x]]"
fun box(): String {
assertEquals("[[true]]", concatBoolean(true))
assertEquals("[[0]]", concatByte(0.toByte()))
assertEquals("[[1]]", concatShort(1.toShort()))
assertEquals("[[2]]", concatInt(2))
assertEquals("[[3]]", concatLong(3L))
assertEquals("[[4.4]]", concatFloat(4.4f))
assertEquals("[[5.5]]", concatFloat(5.5f))
return "OK"
}
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Z\)Ljava/lang/StringBuilder;
// 3 INVOKEVIRTUAL java/lang/StringBuilder\.append \(I\)Ljava/lang/StringBuilder;
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.append \(J\)Ljava/lang/StringBuilder;
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.append \(F\)Ljava/lang/StringBuilder;
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.append \(D\)Ljava/lang/StringBuilder;
@@ -0,0 +1,37 @@
// KOTLIN_CONFIGURATION_FLAGS: STRING_CONCAT=inline
// WITH_STDLIB
import kotlin.test.assertEquals
fun concatAny(x: Any) = "$x!!"
fun <T : String> concat1(x: T) = "[[$x]]"
fun <T : String?> concat2(x: T) = "[[$x]]"
fun <T : String> concat3(x: T?) = "[[$x]]"
fun <T : String> concat4(x: T) = x + "!!"
fun <T : String?> concat5(x: T) = x + "!!"
fun <T : String> concat6(x: T?) = x + "!!"
fun box(): String {
assertEquals("[[1]]", concat1("1"))
assertEquals("[[2]]", concat2("2"))
assertEquals("[[null]]", concat2(null))
assertEquals("[[3]]", concat3("3"))
assertEquals("[[null]]", concat3(null))
assertEquals("4!!", concat4("4"))
assertEquals("5!!", concat5("5"))
assertEquals("null!!", concat5("null"))
assertEquals("6!!", concat5("6"))
assertEquals("null!!", concat5("null"))
return "OK"
}
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Ljava/lang/Object;\)Ljava/lang/StringBuilder;
// ^ single instance of 'StringBuilder.append(Object)' from 'concatAny',
// keep it here to make sure there's no error in regexp.
// 16 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Ljava/lang/String;\)Ljava/lang/StringBuilder;
// ^ everything else is done with 'StringBuilder.append(String)'
// 17 INVOKEVIRTUAL java/lang/StringBuilder\.append
// ^ no other instances of StringBuidler.append(...)
@@ -0,0 +1,31 @@
// KOTLIN_CONFIGURATION_FLAGS: STRING_CONCAT=inline
// WITH_STDLIB
// IGNORE_BACKEND: WASM
// ^ wasm-function[2283]:0x218da: RuntimeError: wasm exception
import kotlin.test.assertEquals
fun <T : Boolean> concatNBoolean(x: T?) = "[[$x]]"
fun <T : Byte> concatNByte(x: T?) = "[[$x]]"
fun <T : Short> concatNShort(x: T?) = "[[$x]]"
fun <T : Int> concatNInt(x: T?) = "[[$x]]"
fun <T : Long> concatNLong(x: T?) = "[[$x]]"
fun <T : Float> concatNFloat(x: T?) = "[[$x]]"
fun <T : Double> concatNDouble(x: T?) = "[[$x]]"
fun box(): String {
assertEquals("[[true]]", concatNBoolean(true))
assertEquals("[[0]]", concatNByte(0.toByte()))
assertEquals("[[1]]", concatNShort(1.toShort()))
assertEquals("[[2]]", concatNInt(2))
assertEquals("[[3]]", concatNLong(3L))
assertEquals("[[4.4]]", concatNFloat(4.4f))
assertEquals("[[5.5]]", concatNFloat(5.5f))
return "OK"
}
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 7 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Ljava/lang/Object;\)Ljava/lang/StringBuilder;
+3
View File
@@ -0,0 +1,3 @@
fun <T : String> concat4(x: T) = x + "K"
fun box() = concat4("O")
@@ -5,5 +5,6 @@ fun foo(x: String?, y: Any?) = x + y
// JVM_IR_TEMPLATES
// 1 NEW java/lang/StringBuilder
// 2 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Ljava/lang/Object;\)Ljava/lang/StringBuilder;
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Ljava/lang/String;\)Ljava/lang/StringBuilder;
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Ljava/lang/Object;\)Ljava/lang/StringBuilder;
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.toString \(\)Ljava/lang/String;