diff --git a/libraries/stdlib/jvm/src/kotlin/coroutines/jvm/internal/ContinuationImpl.kt b/libraries/stdlib/jvm/src/kotlin/coroutines/jvm/internal/ContinuationImpl.kt index 3482f5bf136..3c7f0ea18e2 100644 --- a/libraries/stdlib/jvm/src/kotlin/coroutines/jvm/internal/ContinuationImpl.kt +++ b/libraries/stdlib/jvm/src/kotlin/coroutines/jvm/internal/ContinuationImpl.kt @@ -19,12 +19,13 @@ internal abstract class BaseContinuationImpl( ) : Continuation, CoroutineStackFrame, Serializable { // This implementation is final. This fact is used to unroll resumeWith recursion. public final override fun resumeWith(result: Result) { - // Invoke "resume" debug probe only once, even if previous frames are "resumed" in the loop below, too - probeCoroutineResumed(this) // This loop unrolls recursion in current.resumeWith(param) to make saner and shorter stack traces on resume var current = this var param = result while (true) { + // Invoke "resume" debug probe on every resumed continuation, so that a debugging library infrastructure + // can precisely track what part of suspended callstack was already resumed + probeCoroutineResumed(current) with(current) { val completion = completion!! // fail fast when trying to resume continuation without completion val outcome: Result = diff --git a/libraries/stdlib/jvm/src/kotlin/coroutines/jvm/internal/DebugProbes.kt b/libraries/stdlib/jvm/src/kotlin/coroutines/jvm/internal/DebugProbes.kt index 21a5f27eb35..9977cc6e79d 100644 --- a/libraries/stdlib/jvm/src/kotlin/coroutines/jvm/internal/DebugProbes.kt +++ b/libraries/stdlib/jvm/src/kotlin/coroutines/jvm/internal/DebugProbes.kt @@ -21,10 +21,13 @@ import kotlin.coroutines.intrinsics.* * +-------+ probeCoroutineCreated +-----------+ * | START | ---------------------->| SUSPENDED | * +-------+ +-----------+ - * probeCoroutineResumed | ^ probeCoroutineSuspended - * V | - * +------------+ completion invoked +-----------+ - * | RUNNING | ------------------->| COMPLETED | + * | ^ + * probeCoroutineResumed | | probeCoroutineSuspended + * +-------+ | + * | | | + * | V | + * | +------------+ completion invoked +-----------+ + * +-- | RUNNING | ------------------->| COMPLETED | * +------------+ +-----------+ * ``` * @@ -48,6 +51,9 @@ internal fun probeCoroutineCreated(completion: Continuation): Continuatio * This probe is invoked when coroutine is resumed using [Continuation.resumeWith]. * * This probe is invoked from stdlib implementation of [BaseContinuationImpl.resumeWith] function. + * Note, this probe can be invoked multiple times when coroutine is running. Every time the coroutine + * resumes a part its callstack that was previously stored in the heap, this probe is invoked + * with the references to the newly resumed [frame]. * * Coroutines machinery implementation guarantees that the actual [frame] instance extends * [BaseContinuationImpl] class, despite the fact that the declared type of [frame]