Support new strategy for suspend inline functions
The main idea is to leave all the inline functions as is, without state machines (but keeping suspend-calls markers) and determine whether we need a state machine from the bytecode after inlining into a non-inline function #KT-17585 In Progress #KT-16603 In Progress #KT-16448 Fixed
This commit is contained in:
+31
@@ -0,0 +1,31 @@
|
||||
// IGNORE_BACKEND: JS
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
import helpers.*
|
||||
// CHECK_BYTECODE_LISTING
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
inline suspend fun suspendThere(v: String): String = suspendCoroutineOrReturn { x ->
|
||||
x.resume(v)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
// There's no state machine in the suspendHere, since it's inline
|
||||
inline suspend fun suspendHere(): String = suspendThere("O") + suspendThere("K")
|
||||
// There should be a state machine for mainSuspend as it has two suspend non-tail calls inlined
|
||||
suspend fun mainSuspend() = suspendHere()
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = ""
|
||||
|
||||
builder {
|
||||
result = mainSuspend()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
@kotlin.Metadata
|
||||
final class InlineWithStateMachineKt$box$1 {
|
||||
synthetic final field $result: kotlin.jvm.internal.Ref$ObjectRef
|
||||
field L$0: java.lang.Object
|
||||
inner class InlineWithStateMachineKt$box$1
|
||||
method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.coroutines.experimental.Continuation): void
|
||||
public final @org.jetbrains.annotations.NotNull method create(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): kotlin.coroutines.experimental.Continuation
|
||||
public final @org.jetbrains.annotations.Nullable method doResume(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): java.lang.Object
|
||||
public final @org.jetbrains.annotations.Nullable method invoke(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public synthetic method invoke(p0: java.lang.Object): java.lang.Object
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
final class InlineWithStateMachineKt$mainSuspend$1 {
|
||||
field L$0: java.lang.Object
|
||||
field L$1: java.lang.Object
|
||||
inner class InlineWithStateMachineKt$mainSuspend$1
|
||||
method <init>(p0: kotlin.coroutines.experimental.Continuation): void
|
||||
public final @org.jetbrains.annotations.Nullable method doResume(): java.lang.Object
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class InlineWithStateMachineKt {
|
||||
inner class InlineWithStateMachineKt$box$1
|
||||
inner class InlineWithStateMachineKt$mainSuspend$1
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
|
||||
public final static @org.jetbrains.annotations.Nullable method mainSuspend(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.Nullable method suspendHere(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.Nullable method suspendThere(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
}
|
||||
Vendored
+38
@@ -0,0 +1,38 @@
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
import helpers.*
|
||||
// CHECK_BYTECODE_LISTING
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
inline suspend fun suspendThere(v: String): String = suspendCoroutineOrReturn { x ->
|
||||
x.resume(v)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun suspendHere(): String = suspendThere("O")
|
||||
|
||||
// There is a kind of redundant state machine generated for complexSuspend:
|
||||
// it's basically has the only suspend call just before return, but there is
|
||||
// a redundant CHECKCAST String in the run's lambda, so we have to insert the state machine.
|
||||
// TODO: Think of avoiding such redundant casts
|
||||
suspend fun complexSuspend(): String {
|
||||
return run {
|
||||
suspendThere("K")
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = ""
|
||||
|
||||
builder {
|
||||
result = suspendHere() + complexSuspend()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
@kotlin.Metadata
|
||||
final class InlineWithoutStateMachineKt$box$1 {
|
||||
synthetic final field $result: kotlin.jvm.internal.Ref$ObjectRef
|
||||
field L$0: java.lang.Object
|
||||
field L$1: java.lang.Object
|
||||
inner class InlineWithoutStateMachineKt$box$1
|
||||
method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.coroutines.experimental.Continuation): void
|
||||
public final @org.jetbrains.annotations.NotNull method create(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): kotlin.coroutines.experimental.Continuation
|
||||
public final @org.jetbrains.annotations.Nullable method doResume(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): java.lang.Object
|
||||
public final @org.jetbrains.annotations.Nullable method invoke(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public synthetic method invoke(p0: java.lang.Object): java.lang.Object
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
final class InlineWithoutStateMachineKt$complexSuspend$1 {
|
||||
field L$0: java.lang.Object
|
||||
field L$1: java.lang.Object
|
||||
inner class InlineWithoutStateMachineKt$complexSuspend$1
|
||||
method <init>(p0: kotlin.coroutines.experimental.Continuation): void
|
||||
public final @org.jetbrains.annotations.Nullable method doResume(): java.lang.Object
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class InlineWithoutStateMachineKt {
|
||||
inner class InlineWithoutStateMachineKt$box$1
|
||||
inner class InlineWithoutStateMachineKt$complexSuspend$1
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
|
||||
public final static @org.jetbrains.annotations.Nullable method complexSuspend(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.Nullable method suspendHere(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.Nullable method suspendThere(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// CHECK_BYTECODE_LISTING
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
suspend fun suspendThere(v: String): String = suspendCoroutineOrReturn { x ->
|
||||
x.resume(v)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun suspendHere(): String = suspendThere("OK")
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = ""
|
||||
|
||||
builder {
|
||||
result = suspendHere()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
@kotlin.Metadata
|
||||
final class SimpleKt$box$1 {
|
||||
synthetic final field $result: kotlin.jvm.internal.Ref$ObjectRef
|
||||
field L$0: java.lang.Object
|
||||
inner class SimpleKt$box$1
|
||||
method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.coroutines.experimental.Continuation): void
|
||||
public final @org.jetbrains.annotations.NotNull method create(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): kotlin.coroutines.experimental.Continuation
|
||||
public final @org.jetbrains.annotations.Nullable method doResume(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): java.lang.Object
|
||||
public final @org.jetbrains.annotations.Nullable method invoke(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public synthetic method invoke(p0: java.lang.Object): java.lang.Object
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class SimpleKt {
|
||||
inner class SimpleKt$box$1
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
|
||||
public final static @org.jetbrains.annotations.Nullable method suspendHere(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.Nullable method suspendThere(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
}
|
||||
@@ -1,17 +1,19 @@
|
||||
@kotlin.Metadata
|
||||
final class Controller$multipleSuspensions$1 {
|
||||
field L$0: java.lang.Object
|
||||
synthetic final field this$0: Controller
|
||||
inner class Controller$multipleSuspensions$1
|
||||
method <init>(p0: Controller, p1: kotlin.coroutines.experimental.Continuation): void
|
||||
public final @org.jetbrains.annotations.Nullable method doResume(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): java.lang.Object
|
||||
public final @org.jetbrains.annotations.Nullable method doResume(): java.lang.Object
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
final class Controller$nonTailCall$1 {
|
||||
field L$0: java.lang.Object
|
||||
synthetic final field this$0: Controller
|
||||
inner class Controller$nonTailCall$1
|
||||
method <init>(p0: Controller, p1: kotlin.coroutines.experimental.Continuation): void
|
||||
public final @org.jetbrains.annotations.Nullable method doResume(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): java.lang.Object
|
||||
public final @org.jetbrains.annotations.Nullable method doResume(): java.lang.Object
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
@@ -28,9 +30,9 @@ public final class Controller {
|
||||
@kotlin.Metadata
|
||||
final class CoroutineFieldsKt$box$1 {
|
||||
synthetic final field $result: kotlin.jvm.internal.Ref$ObjectRef
|
||||
private field J$0: long
|
||||
private field L$0: java.lang.Object
|
||||
private field L$1: java.lang.Object
|
||||
field J$0: long
|
||||
field L$0: java.lang.Object
|
||||
field L$1: java.lang.Object
|
||||
private field p$: Controller
|
||||
inner class CoroutineFieldsKt$box$1
|
||||
method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.coroutines.experimental.Continuation): void
|
||||
|
||||
Reference in New Issue
Block a user