Hello everyone, I tried the reified feature of Kot...
# getting-started
Hello everyone, I tried the reified feature of Kotlin and was suprised, that my primitives becomes boxed. Wouldn't it make sense with inlined reified functions to have monomorphization as language feature? Here's a little example:
Copy code
fun main() {
    val value: Int = 2

inline fun <reified T> showValue(value: T) = println("$value")
The decompiled Java shows that the primitive int will be boxed into an Integer. And the function-signature has an Object as parameter-type. I think, although the reified function will be inlined, that the use of primitives, or whatever object for T, stays the same, because of inlining. Is this possible? Thank you
it would make sense, but difficult. currently inlining is done by copy-paste of bytecode from the inline function - which is only compiled once - into each caller. replacing a generic boxed type doesn't require changing any bytecode instructions, just some references. but (at least on JVM) primitives use a completely different set of instructions
if inline functions were changed to inline their AST, and were re-compiled at each call site, then primitive specialization should be possible. I don't think I've seen any proposals around that though
that said, since Java 9 the Hotspot JIT does include autobox elimination in C2 by default (can be controlled by
). so the impact of boxing may vary; measure before you worry too much about it
Thank you very much for the answer. I will try the flag and see how things go
Generally Kotlin has some optimizations that eliminate unnecessary boxing-unboxing pairs during inlining even when the inline function is not reified. I suggest to file a feature request for this case. https://kotl.in/issue
I suppose if you could teach the optimizer that aload+invokevirtual[Object.toString()] is equivalent to aload+invokevirtual[Integer.intValue()]+invokestatic[Integer.toString(i)] on Integer, then an existing box removal optimization could then replace invokestatic[Integer.valueOf(i)]+astore...aload+invokeVirtual[Integer.intValue()] with istore...iload? seems awfully specific to this case though