Search code examples
kotlincompiler-constructionlanguage-design

What's the purpose of Kotlin's intrinsic `areEqual` method?


Let's say I have a

data class Eq(x: Int?)

This will generate an equals method that looks something like this

public boolean equals(Object other){
    if(this == other) return true;
    if(!(other instanceof Eq)) return false;
    Eq otherEq = (Eq) other;
    return Intrinsics.areEqual(this.x, otherEq.x);
}

Where intrinsic

public static boolean areEqual(Object first, Object second){
    return first == null ? second == null : first.equals(second);
}

And I don't quite understand the motivation behind that.

What's the benefit in keeping the static invocation as opposed to inlining its implementation?


Solution

  • Keeping the intrinsic as a static method rather than inlining it at each use site has a few advantages:

    • It does not blow up the resulting binaries. For most intrinsics, a method call is smaller in the bytecode than the inlined body would be. Inlining the intrinsic would therefore lead to growth of the resulting binaries size.

    • The intrinsic implementation is kept under control in the language evolution process and is consistent across all call sites. As the intrinsic is kept as a method, a newer runtime library might provide a better implementation that will be applied to all call sites at once, as opposed to different binaries having different versions inlined.

    As for inlining at compilation time for the sake of performance, in the JVM world, this is usually not feasible. The JVM bytecode is quite a high-level abstraction (a stack machine code, which is far from real hardware), and the JVM itself is good at inlining method calls during JIT-compilation, so the compilers usually don't run micro-optimizations and rely on the optimizations built into the JVM implementations.