JS: improve performance of suspend function calling suspen function when no suspension ever occur.

This commit is contained in:
Alexey Andreev
2017-01-23 14:50:58 +03:00
parent bf55744e64
commit 1a5e0e4b06
2 changed files with 13 additions and 18 deletions
@@ -177,11 +177,10 @@ class CoroutineFunctionTransformer(private val program: JsProgram, private val f
val instanceName = functionWithBody.scope.declareFreshName("instance")
functionWithBody.body.statements += JsAstUtils.newVar(instanceName, JsNameRef(context.metadata.facadeName, instantiation))
val invokeResume = JsInvocation(JsNameRef(context.metadata.resumeName, instanceName.makeRef()), JsLiteral.NULL).makeStmt()
val returnResult = JsReturn(JsNameRef(context.metadata.resultName, instanceName.makeRef()))
val invokeResume = JsReturn(JsInvocation(JsNameRef(context.metadata.doResumeName, instanceName.makeRef()), JsLiteral.NULL))
functionWithBody.body.statements += JsIf(
suspendedName.makeRef(), JsReturn(instanceName.makeRef()), JsBlock(invokeResume, returnResult))
suspendedName.makeRef(), JsReturn(instanceName.makeRef()), invokeResume)
}
private fun generateCoroutineBody(
+11 -15
View File
@@ -28,7 +28,7 @@ import kotlin.coroutines.intrinsics.*
public fun <R, T> (suspend R.() -> T).createCoroutine(
receiver: R,
completion: Continuation<T>
): Continuation<Unit> = this.asDynamic()(receiver, completion, true).facade
): Continuation<Unit> = this.asDynamic()(receiver, completion, true)
/**
* Starts coroutine with receiver type [R] and result type [T].
@@ -40,7 +40,8 @@ public fun <R, T> (suspend R.() -> T).startCoroutine(
receiver: R,
completion: Continuation<T>
) {
this.asDynamic()(receiver, completion)
val coroutine: Continuation<Any?> = this.asDynamic()(receiver, completion, true)
coroutine.resume(null)
}
/**
@@ -52,7 +53,7 @@ public fun <R, T> (suspend R.() -> T).startCoroutine(
@SinceKotlin("1.1")
public fun <T> (suspend () -> T).createCoroutine(
completion: Continuation<T>
): Continuation<Unit> = this.asDynamic()(completion, true).facade
): Continuation<Unit> = this.asDynamic()(completion, true)
/**
* Starts coroutine without receiver and with result type [T].
@@ -63,7 +64,8 @@ public fun <T> (suspend () -> T).createCoroutine(
public fun <T> (suspend () -> T).startCoroutine(
completion: Continuation<T>
) {
this.asDynamic()(completion)
val coroutine: Continuation<Any?> = this.asDynamic()(completion, true)
coroutine.resume(null)
}
/**
@@ -97,22 +99,16 @@ internal abstract class CoroutineImpl(private val resultContinuation: Continuati
override fun resume(data: Any?) {
result = data
try {
result = doResume()
if (result != SUSPENDED_MARKER) {
val data = result
result = SUSPENDED_MARKER
resultContinuation.resume(data)
}
}
catch (e: Throwable) {
resultContinuation.resumeWithException(e)
}
doResumeWrapper()
}
override fun resumeWithException(exception: Throwable) {
state = exceptionState
this.exception = exception
doResumeWrapper()
}
protected fun doResumeWrapper() {
try {
result = doResume()
if (result != SUSPENDED_MARKER) {