JVM_IR: optimize delegation by property references

E.g. a statement like

    var x by ::y

is semantically equivalent to

    var x
      get() = y
      set(value) { y = value }

and thus does not need a full property reference object, or even a field
if the receiver is not bound.

 #KT-39054 Fixed
 #KT-47102 Fixed
This commit is contained in:
pyos
2021-06-16 13:22:32 +02:00
committed by Alexander Udalov
parent 66e052b9b3
commit e49410e07b
17 changed files with 286 additions and 2 deletions
@@ -1,4 +1,3 @@
// WITH_REFLECT
// WITH_RUNTIME
class C(val x: String)
@@ -0,0 +1,13 @@
// WITH_RUNTIME
// IGNORE_BACKEND: JS
class C(var x: String)
var x = "fail"
var y by ::x
var z by C("fail")::x
fun box(): String {
y = "O"
z = "K"
return y + z
}
@@ -0,0 +1,26 @@
// TARGET_BACKEND: JVM
// v-- fir2ir produces an IrFunctionReference of type KProperty0 instead of an IrPropertyReference
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_REFLECT
// WITH_RUNTIME
// FILE: J.java
public interface J<T> {
public T getValue();
}
// FILE: box.kt
class Impl(val x: String) : J<String> {
override fun getValue() = x
}
val j1: J<String> = Impl("O")
// Note that taking a reference to `J<T>::value` is not permitted by the frontend
// in any context except as a direct argument to `by`; e.g. `val x by run { j1::value }`
// would produce an error.
val x by j1::value
fun box(): String {
val j2: J<String> = Impl("K")
val y by j2::value
return x + y
}
@@ -0,0 +1,38 @@
// WITH_RUNTIME
class C(var x: Int) {
val y by C::x
var ym by C::x
val z by ::x
var zm by ::x
}
class D(val c: C) {
val y by c::x
var ym by c::x
val C.z by C::x
var C.zm by C::x
}
var x = 1
val y by ::x
var ym by ::x
val z by C(1)::x
var zm by C(1)::x
fun local() {
val y by ::x
var ym by ::x
val z by C(1)::x
var zm by C(1)::x
}
// 0 \$\$delegatedProperties
// 0 kotlin/jvm/internal/PropertyReference[0-2]Impl\.\<init\>
// JVM_IR_TEMPLATES
// Optimized all to direct accesses:
// 0 kotlin/jvm/internal/MutablePropertyReference[0-2]Impl\.\<init\>
// JVM_TEMPLATES
// Not optimized:
// 16 kotlin/jvm/internal/MutablePropertyReference[0-2]Impl\.\<init\>