KT-14258 Optimize accesses to properties defined into companion
- Use direct access to property defined into companion object when it is possible rather than always use an accessor to access the property. - Use direct access will speedup runtime performance. - Avoid to generate useless accessors for companion properties. Fix of https://youtrack.jetbrains.com/issue/KT-14258
This commit is contained in:
committed by
Alexander Udalov
parent
fd244be9ca
commit
d0ed0c4049
@@ -0,0 +1,16 @@
|
||||
// Checks that methods 'access$getMy$p', 'access$getMy$cp' and 'getMy' are not generated and
|
||||
// that backed field 'my' is directly used through a 'getstatic'
|
||||
|
||||
class My {
|
||||
companion object {
|
||||
private val my: String = "OK"
|
||||
}
|
||||
|
||||
fun getMyValue() = my
|
||||
}
|
||||
|
||||
// 1 GETSTATIC My.my
|
||||
// 1 PUTSTATIC My.my
|
||||
// 0 INVOKESTATIC My\$Companion.access\$getMy\$p
|
||||
// 0 INVOKESTATIC My.access\$getMy\$cp
|
||||
// 0 INVOKESPECIAL My\$Companion.getMy
|
||||
@@ -0,0 +1,20 @@
|
||||
// Checks that methods 'access$getMy$p' and 'getMy' are not generated and
|
||||
// that backed field 'my' is accessed through 'access$getMy$cp'
|
||||
|
||||
class My {
|
||||
companion object {
|
||||
private val my: String = "OK"
|
||||
|
||||
fun test(): String {
|
||||
// accessor is required because field is move to Foo
|
||||
return my
|
||||
}
|
||||
}
|
||||
|
||||
fun getMyValue() = test()
|
||||
}
|
||||
|
||||
// 1 GETSTATIC My.my
|
||||
// 0 INVOKESTATIC My\$Companion.access\$getMy\$p
|
||||
// 1 INVOKESTATIC My.access\$getMy\$cp
|
||||
// 0 INVOKESPECIAL My\$Companion.getMy
|
||||
@@ -0,0 +1,28 @@
|
||||
// Checks that accessor methods are always used due to the overriding of the default setter of 'my' property.
|
||||
|
||||
class My {
|
||||
companion object {
|
||||
private var my: String = "OK"
|
||||
set(value) { field = value }
|
||||
}
|
||||
|
||||
fun getMyValue(): String {
|
||||
// INVOKESTATIC My$Companion.access$setMy$p
|
||||
my = "Overriden value"
|
||||
// GETSTATIC My.my
|
||||
return my
|
||||
}
|
||||
|
||||
// PUTSTATIC My.my into clinit
|
||||
// PUTSTATIC My.my into 'access$setMy$cp'
|
||||
// GETSTATIC My.my into 'access$getMy$cp'
|
||||
}
|
||||
|
||||
// 2 GETSTATIC My.my
|
||||
// 2 PUTSTATIC My.my
|
||||
// 0 INVOKESTATIC My\$Companion.access\$getMy\$p
|
||||
// 1 INVOKESTATIC My\$Companion.access\$setMy\$p
|
||||
// 1 INVOKESTATIC My.access\$setMy\$cp
|
||||
// 1 INVOKESTATIC My.access\$getMy\$cp
|
||||
// 1 INVOKESPECIAL My\$Companion.getMy
|
||||
// 1 INVOKESPECIAL My\$Companion.setMy
|
||||
@@ -0,0 +1,23 @@
|
||||
// Checks that accessor 'I$Companion.access$getBar\$p' is always used because the property is kept
|
||||
// into the companion object.
|
||||
|
||||
interface I {
|
||||
companion object {
|
||||
private var bar = "Companion Field from I"
|
||||
}
|
||||
|
||||
fun test(): String {
|
||||
// INVOKESTATIC I$Companion.access$setBar$p
|
||||
bar = "New value"
|
||||
// INVOKESTATIC I$Companion.access$getBar$p
|
||||
return bar
|
||||
}
|
||||
}
|
||||
|
||||
// 1 GETSTATIC I\$Companion.bar
|
||||
// 2 PUTSTATIC I\$Companion.bar
|
||||
// 1 INVOKESTATIC I\$Companion.access\$getBar\$p
|
||||
// 1 INVOKESTATIC I\$Companion.access\$setBar\$p
|
||||
// 0 INVOKESTATIC I\$Companion.access\$setBar\$cp
|
||||
// 0 INVOKESPECIAL I\$Companion.getBar
|
||||
// 0 INVOKESPECIAL I\$Companion.setBar
|
||||
@@ -0,0 +1,19 @@
|
||||
// Checks that accessor are not used because property can be accessed directly.
|
||||
|
||||
interface I {
|
||||
companion object {
|
||||
private var bar = "Companion Field from I"
|
||||
|
||||
fun test(): String {
|
||||
bar = "New value"
|
||||
return bar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 1 GETSTATIC I\$Companion.bar
|
||||
// 2 PUTSTATIC I\$Companion.bar
|
||||
// 0 INVOKESTATIC I\$Companion.access\$getBar\$p
|
||||
// 0 INVOKESTATIC I\$Companion.access\$setBar\$cp
|
||||
// 0 INVOKESPECIAL I\$Companion.getBar
|
||||
// 0 INVOKESPECIAL I\$Companion.setBar
|
||||
+5
-1
@@ -9,9 +9,13 @@ class Foo {
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
// Access to the property use getstatic on the backed field
|
||||
LOCAL_PRIVATE
|
||||
// Access to the property requires an invokestatic
|
||||
OUTER_PRIVATE
|
||||
}
|
||||
}
|
||||
|
||||
// 2 INVOKESTATIC
|
||||
// 1 INVOKESTATIC
|
||||
// 1 PUTSTATIC
|
||||
// 2 GETSTATIC
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
class A {
|
||||
companion object {
|
||||
private var r: Int = 1;
|
||||
}
|
||||
}
|
||||
// A and companion object constructor call
|
||||
// 3 ALOAD 0
|
||||
// 1 synthetic access\$getR
|
||||
Reference in New Issue
Block a user