You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
kotlinx-coroutines-debug bundles repackaged byte-buddy (15,3 MB out of total 20,3 MB).
Considerable time is spent on loading the byte-buddy (anywhere from 300ms to 500ms in our runs).
It's used only to patch a single class kotlin.coroutines.jvm.internal.DebugProbesKt which is located in kotlin-stdlib.
It does not work on winarm64 at the moment (minor).
What should be instead?
A way to statically load the proper binary without dealing with byte-buddy.
Why?
Reduce the size of production jars.
Reduce the class loading time.
Possible solution
Replace stdlib's kotlin.coroutines.jvm.internal.DebugProbesKt with the following:
private val probesBridge get() = Class.forName("ProbesBridge Name TBD")
private val probeCoroutineCreatedMethod: Method? = runCatching {
probesBridge.getDeclaredMethod("probeCoroutineCreated", Continuation::class.java)
}.getOrNull()
private val probeCoroutineResumedMethod: Method? = runCatching {
probesBridge.getDeclaredMethod("probeCoroutineResumed", Continuation::class.java)
}.getOrNull()
private val probeCoroutineSuspended: Method? = runCatching {
probesBridge.getDeclaredMethod("probeCoroutineSuspended", Continuation::class.java)
}.getOrNull()
internal fun <T> probeCoroutineCreated(completion: Continuation<T>): Continuation<T> {
if (probeCoroutineCreatedMethod != null) {
return probeCoroutineCreatedMethod.invoke(null, completion) as Continuation<T>
}
return completion
}
internal fun probeCoroutineResumed(frame: Continuation<*>) {
probeCoroutineResumedMethod?.invoke(null, frame)
}
internal fun probeCoroutineSuspended(frame: Continuation<*>) {
probeCoroutineSuspended?.invoke(null, frame)
}
This approach is already used here.
JIT should not have any trouble inlining one of == null branches when ProbesBridge is present or absent.
ProbesBridge should set AgentInstallationType in its <clinit>.
ProbesBridge should start the cleaner thread in its <clinit> (questionable, but enables no-code setup by putting the debug jar into classpath).
(Optionally) Provide a separate minimal production-ready kotlinx-coroutines-debug-core JAR with probes. kotlinx.coroutines.debug.internal.DebugProbesImpl resides in kotlinx-coroutines-core-jvm, I think that it should be a part of that JAR instead.
Other solutions
Patch kotlin-stdlib jar statically, replace kotlin.coroutines.jvm.internal.DebugProbesKt during build time, publish a separate kotlin-stdlib artefact.
Patch kotlin-stdlib jar dynamically.
2.1. Put the jar before kotlin-stdlib in classpath, similar to Please provide artifact with DebugProbes for classpath patching instead of instrumentations. #3356.
2.2. Change IJ own class loader to load DebugProbesKt.bin or the proposed class when kotlin.coroutines.jvm.internal.DebugProbesKt is requested (somewhat equivalent to javaagent solution, also a hack).
DI probes into stdlib.
3.1. proposed solution, or
3.2. separate interface,ServiceLoader similar to Dispatchers.Main, no op implementation by default.
The text was updated successfully, but these errors were encountered:
-javaagent
is not a production-level solution for IJ, so IJ enables coroutine debugger dynamically at very early stage of application start up:What do we have now?
kotlinx-coroutines-debug
bundles repackagedbyte-buddy
(15,3 MB out of total 20,3 MB).byte-buddy
(anywhere from 300ms to 500ms in our runs).kotlin.coroutines.jvm.internal.DebugProbesKt
which is located inkotlin-stdlib
.What should be instead?
A way to statically load the proper binary without dealing with
byte-buddy
.Why?
Possible solution
Replace stdlib's
kotlin.coroutines.jvm.internal.DebugProbesKt
with the following:This approach is already used here.
JIT should not have any trouble inlining one of
== null
branches whenProbesBridge
is present or absent.ProbesBridge
should setAgentInstallationType
in its<clinit>
.ProbesBridge
should start the cleaner thread in its<clinit>
(questionable, but enables no-code setup by putting the debug jar into classpath).kotlinx-coroutines-debug-core
JAR with probes.kotlinx.coroutines.debug.internal.DebugProbesImpl
resides inkotlinx-coroutines-core-jvm
, I think that it should be a part of that JAR instead.Other solutions
kotlin-stdlib
jar statically, replacekotlin.coroutines.jvm.internal.DebugProbesKt
during build time, publish a separatekotlin-stdlib
artefact.kotlin-stdlib
jar dynamically.2.1. Put the jar before
kotlin-stdlib
in classpath, similar to Please provide artifact with DebugProbes for classpath patching instead of instrumentations. #3356.2.2. Change IJ own class loader to load
DebugProbesKt.bin
or the proposed class whenkotlin.coroutines.jvm.internal.DebugProbesKt
is requested (somewhat equivalent to javaagent solution, also a hack).3.1. proposed solution, or
3.2. separate interface,
ServiceLoader
similar toDispatchers.Main
, no op implementation by default.The text was updated successfully, but these errors were encountered: