Kotlin's inline classes (and Scala's AnyVal classes) are syntax sugar for static methods. The object itself is erased completely whenever possible (just like primitive values).
case class Foo(x: Int) extends AnyVal {
def square: Int = x * x
}
val bar: Foo = Foo(5)
println(bar.square) // => 25
Compiles down to (the moral equivalent of)
object Foo {
def square(x: Int): Int = x * x
}
val bar: Int = 5
println(Foo.square(bar)) // => 25
If the inner value (x, in this case) can be stack-allocated or stored in registers then `Foo(x): Foo` will as well. `Foo(x): Bar` (where Bar is a supertype of Foo) will be autoboxed, but that also applies to primitive types (`5: Any` becomes a java.lang.Integer in memory).
Which is guaranteed to be always stack-allocated or stored in registers, again you cannot retrofit semantics, specially when passing those classes to binary libraries.
You're correct that the Scala version isn't ABI-compatible. But Scala doesn't care about ABI between minor releases anyway, so that probably wouldn't stop them from changing it to align with Java.
There is also precedence for this, Scala 2.12 changed the encoding of lambdas from anonymous classes to Java 8's invokedynamic.