# Bytecode behind coroutines in Kotlin

A simple suspend function, and its bytecode.

The new thing in Kotlin 1.1 is coroutines. As we know from the documentation, it is the suspend keyword that was added to the language. The rest is implemented as libraries.

Let’s take a look at the bytecode side of this feature.

# An Empty Suspend function

I have the following code snippet:

Let’s take a look to the bytecode from this method. For the experiment, I use Kotlin 1.1.1 with IntelliJ IDEA 2017.1. Results may depend on version. I use javap -c to generate those dumps

The interface Continuation is declared in the Kotlin standard library, see documentation. It contains context and methods to complete continuation: resume and resumeWithException.

# A Trivial Suspend function

Here a() and c() are calls to ordinary Java methods, which were declared in Kotlin without the suspend keyword.

As we see from this code, there is nothing special done to the method. The only return value and additional parameter were added.

# A suspend function with a suspend call

In this example, we call b3() suspend function from itself. Here a() and c() are calls to ordinary Java methods, which were declared in Kotlin without suspend keyword. The generated code now looks way different.

Instead of having the method in-place, it now generates an inner class for the state-machine to implement the suspend.

The class streams4/ZKt$b3$1 is generated as follows

The implementation of b3() function is moved to a state machine anonymous object. The main method of the inner object does a switch over states of the state machine. The b3() function is split by every suspend function call. On the example below, we have only 2 states. This is up to helper functions to assert the machine is always in a correct state.

On every suspend function call, Kotlin creates an object to encapsulate the state of the state machine, that is created to implement the continuations on top of JVM.

# Conclusion

Coroutines in Kotlin are awesome, easy and powerful constructs that give us the power to fight the complexity (by the cost of an extra abstraction level). I’m looking forward to using coroutines to simplify asynchronous code in my apps.