Hello everyone, I tried the reified feature of Kot...
# getting-started
p
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
    showValue<Int>(value)
}

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
e
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
-XX:+EliminateAutoBox
). so the impact of boxing may vary; measure before you worry too much about it
p
Thank you very much for the answer. I will try the flag and see how things go
i
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
e
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