Kotlin generates: CHECKCAST xx$Companion on every call


#1

Here is small sample:

class AA {
  companion object {
    fun func1() {}

    fun test() {
      func1()
      func1()
      func1()
      func1()
    }
  }
}

Kotlin generates each call of func1() like this:

    ALOAD 0
    CHECKCAST test/ktest/AA$Companion
    INVOKEVIRTUAL test/ktest/AA$Companion.func1 ()V

It checks type of this before every call.
Why?
Is there any reasons to generate type check of class companion on every function call?


#2

Bytecode generation by Kotlin is at this point not very optimized yet (even less than the bytecode by Oracle’s Java compiler). In general the JVM is quite good at optimizing this kind of silly code away, knowing it will always pass. There is no guarantee though and some things can’t be easily changed (functions on objects are always final, so if they don’t use the this pointer they can be generated static). Inline functions similarly are candidates for constant propagation and dead code elimination. The Kotlin team is limited however and probably doesn’t prioritise this.


#3

I fully understand what Kotlin developers are busy and bugs\features has much more priority instead optimization. Its ok.

I had two reasons to create this topic:

  1. To point out this, possible useless, code.

  2. To get an answer for my question: is there any reason to check this inside method at all?
    In shown case we are already inside some class function and, if we reach here, this is already pointed to the right class anyway. I didnt see any reasons to check it type again before to call other functions of the same class.


#4

No, there is no reason for the type check here; it’s generated due to the way the Kotlin bytecode generator is implemented. In a future version (1.2 most likely), we’ll switch to a different bytecode generator implementation that will not generate redundant bytecode.


#5

Thanks for cleaning this up for me.