Why AutoCloseable.use method is inlined?


#1

Hi !

Does anybody knows, why method below is inlined always?

public inline fun <T : AutoCloseable?, R> T.use(block: (T) -> R): R

We can create lambda for this case in heap (e.g. instead of method inlining - just do library call).
Why:

  1. Inline methods increase total byte code soze, e.g. increases application complexity from JVM side
  2. The same code is copy-pasted multiple time, so JIT could not understand, that optimization of it can be the same
  3. close method is called for case, when we are going to create new objects in heap. This means, that we can create one more object (e.g our function and closed variables) without any big affect (instead of collection iteration, etc.).
  4. Inline functions are not default for JVM, e.g. it is better to use them as less as possible
  5. If JVM really need to inline this method, it can do this by itself.

Do we have performance reasons for this function inlining? Do we have any other reasons to do this?


#2

You can implement a non-inline version of use and compare various performance tradeoffs versus inline version of it in terms of code size (both raw and zipped), performance, memory consumption, etc. It would do a great blog post and I’m sure many will share.


#3

I believe the method is inline to mimic what you would do in Java with the try-with-resources statement.


#4

I don’t think that JVM would inline lambda methods. Another reason is that with inline you can use return and it would be really weird not being able to call return inside use.


#5

The key reason why this is inline is to support non-local returns. In Java, if you put a return statement in a try-with-resources block, this will return out of the enclosing function. Since we offer use as a replacement for try-with-resources, it’s only natural to preserve this ability. And non-local returns are only supported for inline functions.