JVM: streamline handling of tail-call suspend functions

Just see if every suspend call is followed only by safe instructions or
returns, then insert a suspension point check if there isn't a direct
return.

The first part of this is equivalent to the old implementation, just
refactored. The second part generates strictly more checks; see, for
example, the fixed test, in which the previous implementation failed to
insert a check before a CHECKCAST.

^KT-51818 Fixed
This commit is contained in:
pyos
2022-04-08 12:31:07 +02:00
committed by teamcity
parent 97fc97e63d
commit a07e21d913
7 changed files with 124 additions and 202 deletions
@@ -0,0 +1,29 @@
// TARGET_BACKEND: JVM
// FULL_JDK
// WITH_STDLIB
// WITH_COROUTINES
// CHECK_TAIL_CALL_OPTIMIZATION
import helpers.*
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
suspend fun suspendFun(x: String): String = suspendCoroutineUninterceptedOrReturn {
TailCallOptimizationChecker.saveStackTrace(it)
COROUTINE_SUSPENDED
}
suspend fun myFunWithTailCall(x: String) {
x.let { suspendFun(it) }
}
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
builder {
myFunWithTailCall("...")
}
TailCallOptimizationChecker.checkNoStateMachineIn("myFunWithTailCall")
return "OK"
}