From 6dde567be4bf9a3a5ef4d55980b55d2a965fd9b5 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Tue, 31 Jan 2017 18:24:33 +0300 Subject: [PATCH] Optimize startCoroutine impls, move them to common stdlib Do not wrap initial continuation for startCoroutine in SafeContinuation This changes leaves only internal declarations and intrinsics as platform dependent parts of the coroutine library, the rest parts (public API) is implemented through them in common module --- js/js.libraries/src/core/coroutines.kt | 32 ++----------- .../stdlib/common/src/kotlin/CoroutinesH.kt | 37 +++++--------- .../experimental/CoroutinesLibrary.kt | 29 ++++++++++- .../experimental/CoroutinesLibraryJvm.kt | 48 +++++-------------- 4 files changed, 55 insertions(+), 91 deletions(-) diff --git a/js/js.libraries/src/core/coroutines.kt b/js/js.libraries/src/core/coroutines.kt index 0eda0d91e2a..24b044be17b 100644 --- a/js/js.libraries/src/core/coroutines.kt +++ b/js/js.libraries/src/core/coroutines.kt @@ -18,38 +18,14 @@ package kotlin.coroutines.experimental import kotlin.coroutines.experimental.intrinsics.* -/** - * Creates coroutine with receiver type [R] and result type [T]. - * This function creates a new, fresh instance of suspendable computation every time it is invoked. - * To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance. - * The [completion] continuation is invoked when coroutine completes with result of exception. - */ -@SinceKotlin("1.1") -public fun (suspend R.() -> T).createCoroutine( +internal fun (suspend R.() -> T).createCoroutineInternal( receiver: R, completion: Continuation -): Continuation = - SafeContinuation( - this.asDynamic()(receiver, completion, true), - COROUTINE_SUSPENDED - ) +): Continuation = this.asDynamic()(receiver, completion, true) -/** - * Creates coroutine without receiver and with result type [T]. - * This function creates a new, fresh instance of suspendable computation every time it is invoked. - * To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance. - * The [completion] continuation is invoked when coroutine completes with result of exception. - */ -@SinceKotlin("1.1") -public fun (suspend () -> T).createCoroutine( +internal fun (suspend () -> T).createCoroutineInternal( completion: Continuation -): Continuation = - SafeContinuation( - this.asDynamic()(completion, true), - COROUTINE_SUSPENDED - ) - -// ------- internal stuff ------- +): Continuation = this.asDynamic()(completion, true) @JsName("CoroutineImpl") internal abstract class CoroutineImpl(private val resultContinuation: Continuation) : Continuation { diff --git a/libraries/stdlib/common/src/kotlin/CoroutinesH.kt b/libraries/stdlib/common/src/kotlin/CoroutinesH.kt index de81587163c..1d5f9c77919 100644 --- a/libraries/stdlib/common/src/kotlin/CoroutinesH.kt +++ b/libraries/stdlib/common/src/kotlin/CoroutinesH.kt @@ -1,31 +1,5 @@ package kotlin.coroutines.experimental - -/** - * Creates coroutine with receiver type [R] and result type [T]. - * This function creates a new, fresh instance of suspendable computation every time it is invoked. - * To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance. - * The [completion] continuation is invoked when coroutine completes with result of exception. - * An optional [dispatcher] may be specified to customise dispatch of continuations between suspension points inside the coroutine. - */ -@SinceKotlin("1.1") -public header fun (suspend R.() -> T).createCoroutine( - receiver: R, - completion: Continuation -): Continuation - -/** - * Creates coroutine without receiver and with result type [T]. - * This function creates a new, fresh instance of suspendable computation every time it is invoked. - * To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance. - * The [completion] continuation is invoked when coroutine completes with result of exception. - * An optional [dispatcher] may be specified to customise dispatch of continuations between suspension points inside the coroutine. - */ -@SinceKotlin("1.1") -public header fun (suspend () -> T).createCoroutine( - completion: Continuation -): Continuation - @PublishedApi internal header class SafeContinuation : Continuation { internal constructor(delegate: Continuation, initialResult: Any?) @@ -40,3 +14,14 @@ internal header class SafeContinuation : Continuation { override fun resume(value: T): Unit override fun resumeWithException(exception: Throwable): Unit } + +@SinceKotlin("1.1") +internal header fun (suspend () -> T).createCoroutineInternal( + completion: Continuation +): Continuation + +@SinceKotlin("1.1") +internal header fun (suspend R.() -> T).createCoroutineInternal( + receiver: R, + completion: Continuation +): Continuation diff --git a/libraries/stdlib/src/kotlin/coroutines/experimental/CoroutinesLibrary.kt b/libraries/stdlib/src/kotlin/coroutines/experimental/CoroutinesLibrary.kt index 31b2b1c70e3..85ae99515fb 100644 --- a/libraries/stdlib/src/kotlin/coroutines/experimental/CoroutinesLibrary.kt +++ b/libraries/stdlib/src/kotlin/coroutines/experimental/CoroutinesLibrary.kt @@ -31,7 +31,7 @@ public fun (suspend R.() -> T).startCoroutine( receiver: R, completion: Continuation ) { - createCoroutine(receiver, completion).resume(Unit) + createCoroutineInternal(receiver, completion).resume(Unit) } /** @@ -44,9 +44,34 @@ public fun (suspend R.() -> T).startCoroutine( public fun (suspend () -> T).startCoroutine( completion: Continuation ) { - createCoroutine(completion).resume(Unit) + createCoroutineInternal(completion).resume(Unit) } +/** + * Creates coroutine with receiver type [R] and result type [T]. + * This function creates a new, fresh instance of suspendable computation every time it is invoked. + * To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance. + * The [completion] continuation is invoked when coroutine completes with result or exception. + */ +@SinceKotlin("1.1") +@Suppress("UNCHECKED_CAST") +public fun (suspend R.() -> T).createCoroutine( + receiver: R, + completion: Continuation +): Continuation = SafeContinuation(createCoroutineInternal(receiver, completion), COROUTINE_SUSPENDED) + +/** + * Creates coroutine without receiver and with result type [T]. + * This function creates a new, fresh instance of suspendable computation every time it is invoked. + * To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance. + * The [completion] continuation is invoked when coroutine completes with result or exception. + */ +@SinceKotlin("1.1") +@Suppress("UNCHECKED_CAST") +public fun (suspend () -> T).createCoroutine( + completion: Continuation +): Continuation = SafeContinuation(createCoroutineInternal(completion), COROUTINE_SUSPENDED) + /** * Obtains the current continuation instance inside suspend functions and suspends * currently running coroutine. diff --git a/libraries/stdlib/src/kotlin/coroutines/experimental/CoroutinesLibraryJvm.kt b/libraries/stdlib/src/kotlin/coroutines/experimental/CoroutinesLibraryJvm.kt index 42e4b23a081..239abd5b645 100644 --- a/libraries/stdlib/src/kotlin/coroutines/experimental/CoroutinesLibraryJvm.kt +++ b/libraries/stdlib/src/kotlin/coroutines/experimental/CoroutinesLibraryJvm.kt @@ -18,54 +18,32 @@ @file:kotlin.jvm.JvmVersion package kotlin.coroutines.experimental -import kotlin.coroutines.experimental.intrinsics.COROUTINE_SUSPENDED import kotlin.coroutines.experimental.jvm.internal.CoroutineImpl import kotlin.coroutines.experimental.jvm.internal.interceptContinuationIfNeeded -/** - * Creates coroutine with receiver type [R] and result type [T]. - * This function creates a new, fresh instance of suspendable computation every time it is invoked. - * To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance. - * The [completion] continuation is invoked when coroutine completes with result or exception. - */ @SinceKotlin("1.1") -@Suppress("UNCHECKED_CAST") -public fun (suspend R.() -> T).createCoroutine( +internal fun (suspend () -> T).createCoroutineInternal( + completion: Continuation +): Continuation = + if (this !is CoroutineImpl) + buildContinuationByInvokeCall(completion) { + (this as Function1, Any?>).invoke(completion) + } + else + (this.create(completion) as CoroutineImpl).facade + +@SinceKotlin("1.1") +internal fun (suspend R.() -> T).createCoroutineInternal( receiver: R, completion: Continuation ): Continuation = - SafeContinuation( if (this !is CoroutineImpl) buildContinuationByInvokeCall(completion) { (this as Function2, Any?>).invoke(receiver, completion) } else - ((this as CoroutineImpl).create(receiver, completion) as CoroutineImpl).facade, - COROUTINE_SUSPENDED - ) + ((this as CoroutineImpl).create(receiver, completion) as CoroutineImpl).facade -/** - * Creates coroutine without receiver and with result type [T]. - * This function creates a new, fresh instance of suspendable computation every time it is invoked. - * To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance. - * The [completion] continuation is invoked when coroutine completes with result or exception. - */ -@SinceKotlin("1.1") -@Suppress("UNCHECKED_CAST") -public fun (suspend () -> T).createCoroutine( - completion: Continuation -): Continuation = - SafeContinuation( - if (this !is CoroutineImpl) - buildContinuationByInvokeCall(completion) { - (this as Function1, Any?>).invoke(completion) - } - else - ((this as CoroutineImpl).create(completion) as CoroutineImpl).facade, - COROUTINE_SUSPENDED - ) - -// INTERNAL DECLARATIONS private inline fun buildContinuationByInvokeCall( completion: Continuation,