mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-24 09:20:53 +07:00
[kotlin] Optimize coroutine panel loading time
(cherry picked from commit 29a9c965fef723c6c283662eab1542cabe5d32cb) IJ-MR-13882 GitOrigin-RevId: ad3ce16c002f0922959d0a27c23ee4e3c2e2ce27
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d2e08cb3b4
commit
daf8b99c0d
@@ -27,5 +27,6 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.core.ui" />
|
||||
<orderEntry type="module" module-name="intellij.platform.ide.util.io" />
|
||||
<orderEntry type="module" module-name="intellij.platform.smRunner" />
|
||||
<orderEntry type="library" name="gson" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -0,0 +1,127 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.kotlin.idea.debugger.coroutine
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.sun.jdi.ArrayReference
|
||||
import com.sun.jdi.ObjectReference
|
||||
import com.sun.jdi.StringReference
|
||||
import com.sun.jdi.ThreadReference
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.data.CoroutineInfoData
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.data.CoroutineStackTraceProvider
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.data.LazyCoroutineInfoData
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.CoroutineInfoProvider
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.mirror.DebugProbesImpl
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.mirror.MirrorOfCoroutineContext
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.util.logger
|
||||
import org.jetbrains.kotlin.idea.debugger.evaluate.DefaultExecutionContext
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class CoroutinesInfoFromJsonAndReferencesProvider(
|
||||
private val executionContext: DefaultExecutionContext,
|
||||
private val debugProbesImpl: DebugProbesImpl
|
||||
) : CoroutineInfoProvider {
|
||||
private val stackTraceProvider = CoroutineStackTraceProvider(executionContext)
|
||||
|
||||
override fun dumpCoroutinesInfo(): List<CoroutineInfoData> {
|
||||
val array = debugProbesImpl.dumpCoroutinesInfoAsJsonAndReferences(executionContext)
|
||||
?: return emptyList()
|
||||
|
||||
if (array.length() != 4) {
|
||||
error("The result array of 'dumpCoroutinesInfoAsJSONAndReferences' should be of size 4")
|
||||
}
|
||||
|
||||
val coroutinesInfoAsJsonString = array.getValue(0).safeAs<StringReference>()?.value()
|
||||
?: error("The first element of the result array must be a string")
|
||||
val lastObservedThreadRefs = array.getValue(1).safeAs<ArrayReference>()?.toTypedList<ThreadReference?>()
|
||||
?: error("The second element of the result array must be an array")
|
||||
val lastObservedFrameRefs = array.getValue(2).safeAs<ArrayReference>()?.toTypedList<ObjectReference>()
|
||||
?: error("The third element of the result array must be an array")
|
||||
val coroutineInfoRefs = array.getValue(3).safeAs<ArrayReference>()?.toTypedList<ObjectReference>()
|
||||
?: error("The fourth element of the result array must be an array")
|
||||
val coroutinesInfo = Gson().fromJson(coroutinesInfoAsJsonString, Array<CoroutineInfoPack>::class.java)
|
||||
|
||||
if (coroutineInfoRefs.size != lastObservedFrameRefs.size ||
|
||||
lastObservedFrameRefs.size != coroutinesInfo.size ||
|
||||
coroutinesInfo.size != lastObservedThreadRefs.size) {
|
||||
error("Arrays must have equal sizes")
|
||||
}
|
||||
|
||||
return calculateCoroutineInfoData(coroutinesInfo, coroutineInfoRefs, lastObservedThreadRefs, lastObservedFrameRefs)
|
||||
}
|
||||
|
||||
private fun calculateCoroutineInfoData(
|
||||
coroutineInfos: Array<CoroutineInfoPack>,
|
||||
coroutineInfoRefs: List<ObjectReference>,
|
||||
lastObservedThreadRefs: List<ThreadReference?>,
|
||||
lastObservedFrameRefs: List<ObjectReference>
|
||||
): List<CoroutineInfoData> {
|
||||
val result = mutableListOf<LazyCoroutineInfoData>()
|
||||
for ((i, info) in coroutineInfos.withIndex()) {
|
||||
result.add(
|
||||
getLazyCoroutineInfoData(
|
||||
info,
|
||||
coroutineInfoRefs[i],
|
||||
lastObservedThreadRefs[i],
|
||||
lastObservedFrameRefs[i],
|
||||
stackTraceProvider
|
||||
)
|
||||
)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun getLazyCoroutineInfoData(
|
||||
info: CoroutineInfoPack,
|
||||
coroutineInfosRef: ObjectReference,
|
||||
lastObservedThreadRef: ThreadReference?,
|
||||
lastObservedFrameRef: ObjectReference?,
|
||||
stackTraceProvider: CoroutineStackTraceProvider
|
||||
): LazyCoroutineInfoData {
|
||||
val coroutineContextMirror = MirrorOfCoroutineContext(
|
||||
info.name,
|
||||
info.id,
|
||||
info.dispatcher
|
||||
)
|
||||
val coroutineInfoMirror = debugProbesImpl.getCoroutineInfo(
|
||||
coroutineInfosRef,
|
||||
executionContext,
|
||||
coroutineContextMirror,
|
||||
info.sequenceNumber,
|
||||
info.state,
|
||||
lastObservedThreadRef,
|
||||
lastObservedFrameRef
|
||||
)
|
||||
|
||||
return LazyCoroutineInfoData(coroutineInfoMirror, stackTraceProvider)
|
||||
}
|
||||
|
||||
private data class CoroutineInfoPack(
|
||||
val name: String?,
|
||||
val id: Long?,
|
||||
val dispatcher: String?,
|
||||
val sequenceNumber: Long?,
|
||||
val state: String?
|
||||
)
|
||||
|
||||
companion object {
|
||||
fun instance(executionContext: DefaultExecutionContext, debugProbesImpl: DebugProbesImpl): CoroutinesInfoFromJsonAndReferencesProvider? {
|
||||
if (debugProbesImpl.canDumpCoroutinesInfoAsJsonAndReferences()) {
|
||||
return CoroutinesInfoFromJsonAndReferencesProvider(executionContext, debugProbesImpl)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
val log by logger
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <reified T> ArrayReference.toTypedList(): List<T> {
|
||||
val result = mutableListOf<T>()
|
||||
for (value in values) {
|
||||
if (value !is T) {
|
||||
error("Value has type ${value::class.java}, but ${T::class.java} was expected")
|
||||
}
|
||||
result.add(value)
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -30,10 +30,9 @@ abstract class CoroutineInfoData(val descriptor: CoroutineDescriptor) {
|
||||
}
|
||||
|
||||
class LazyCoroutineInfoData(
|
||||
descriptor: CoroutineDescriptor,
|
||||
private val mirror: MirrorOfCoroutineInfo,
|
||||
private val stackTraceProvider: CoroutineStackTraceProvider
|
||||
) : CoroutineInfoData(descriptor) {
|
||||
) : CoroutineInfoData(CoroutineDescriptor.instance(mirror)) {
|
||||
val stackFrames: CoroutineStackTraceProvider.CoroutineStackFrames? by lazy {
|
||||
stackTraceProvider.findStackFrames(mirror)
|
||||
}
|
||||
|
||||
@@ -4,14 +4,14 @@ package org.jetbrains.kotlin.idea.debugger.coroutine.proxy
|
||||
import com.intellij.debugger.engine.DebuggerManagerThreadImpl
|
||||
import com.intellij.debugger.engine.SuspendContextImpl
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.CoroutinesInfoFromJsonAndReferencesProvider
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.data.CoroutineInfoCache
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.mirror.DebugProbesImpl
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.util.executionContext
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.util.logger
|
||||
import org.jetbrains.kotlin.idea.debugger.evaluate.DefaultExecutionContext
|
||||
|
||||
class CoroutineDebugProbesProxy(val suspendContext: SuspendContextImpl) {
|
||||
private val log by logger
|
||||
|
||||
/**
|
||||
* Invokes DebugProbes from debugged process's classpath and returns states of coroutines
|
||||
* Should be invoked on debugger manager thread
|
||||
@@ -33,12 +33,20 @@ class CoroutineDebugProbesProxy(val suspendContext: SuspendContextImpl) {
|
||||
}
|
||||
|
||||
private fun findProvider(executionContext: DefaultExecutionContext): CoroutineInfoProvider? {
|
||||
val agentProxy = CoroutineLibraryAgent2Proxy.instance(executionContext)
|
||||
if (agentProxy != null)
|
||||
return agentProxy
|
||||
if (standaloneCoroutineDebuggerEnabled())
|
||||
return CoroutineNoLibraryProxy(executionContext)
|
||||
return null
|
||||
val debugProbesImpl = DebugProbesImpl.instance(executionContext)
|
||||
return when {
|
||||
debugProbesImpl != null && debugProbesImpl.isInstalled ->
|
||||
CoroutinesInfoFromJsonAndReferencesProvider.instance(executionContext, debugProbesImpl) ?:
|
||||
CoroutineLibraryAgent2Proxy(executionContext, debugProbesImpl)
|
||||
standaloneCoroutineDebuggerEnabled() ->
|
||||
CoroutineNoLibraryProxy(executionContext)
|
||||
else ->
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val log by logger
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,47 +2,25 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.debugger.coroutine.proxy
|
||||
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.data.CoroutineDescriptor
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.data.CoroutineInfoData
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.data.CoroutineStackTraceProvider
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.data.LazyCoroutineInfoData
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.mirror.DebugProbesImpl
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.util.logger
|
||||
import org.jetbrains.kotlin.idea.debugger.evaluate.DefaultExecutionContext
|
||||
|
||||
class CoroutineLibraryAgent2Proxy(private val executionContext: DefaultExecutionContext) : CoroutineInfoProvider {
|
||||
private val debugProbesImpl = DebugProbesImpl.instance(executionContext)
|
||||
class CoroutineLibraryAgent2Proxy(
|
||||
private val executionContext: DefaultExecutionContext,
|
||||
private val debugProbesImpl: DebugProbesImpl
|
||||
) : CoroutineInfoProvider {
|
||||
private val stackTraceProvider = CoroutineStackTraceProvider(executionContext)
|
||||
|
||||
override fun dumpCoroutinesInfo(): List<CoroutineInfoData> {
|
||||
val result = debugProbesImpl?.dumpCoroutinesInfo(executionContext) ?: emptyList()
|
||||
val result = debugProbesImpl.dumpCoroutinesInfo(executionContext)
|
||||
return result.map {
|
||||
LazyCoroutineInfoData(
|
||||
CoroutineDescriptor.instance(it),
|
||||
it,
|
||||
stackTraceProvider
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun isInstalled(): Boolean {
|
||||
return try {
|
||||
debugProbesImpl?.isInstalled ?: false
|
||||
} catch (e: Exception) {
|
||||
log.error("Exception happened while checking agent status.", e)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun instance(executionContext: DefaultExecutionContext): CoroutineLibraryAgent2Proxy? {
|
||||
val agentProxy = CoroutineLibraryAgent2Proxy(executionContext)
|
||||
return if (agentProxy.isInstalled())
|
||||
agentProxy
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
val log by logger
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.debugger.coroutine.proxy.mirror
|
||||
|
||||
import com.sun.jdi.BooleanValue
|
||||
import com.sun.jdi.LongValue
|
||||
import com.sun.jdi.ObjectReference
|
||||
import com.sun.jdi.ThreadReference
|
||||
import com.sun.jdi.*
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.util.isSubTypeOrSame
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.util.logger
|
||||
import org.jetbrains.kotlin.idea.debugger.evaluate.DefaultExecutionContext
|
||||
@@ -26,6 +23,7 @@ class DebugProbesImpl private constructor(context: DefaultExecutionContext) :
|
||||
|
||||
private val enhanceStackTraceWithThreadDumpMethod by MethodMirrorDelegate("enhanceStackTraceWithThreadDump", javaLangListMirror)
|
||||
private val dumpMethod by MethodMirrorDelegate("dumpCoroutinesInfo", javaLangListMirror, "()Ljava/util/List;")
|
||||
private val dumpCoroutinesInfoAsJsonAndReferences by MethodDelegate<ArrayReference>("dumpCoroutinesInfoAsJsonAndReferences", "()[Ljava/lang/Object;")
|
||||
|
||||
val isInstalled: Boolean by lazy { isInstalled(context) }
|
||||
|
||||
@@ -34,8 +32,8 @@ class DebugProbesImpl private constructor(context: DefaultExecutionContext) :
|
||||
|
||||
fun isInstalled(context: DefaultExecutionContext): Boolean =
|
||||
isInstalledInDebugMethod.value(instance, context)?.booleanValue() ?:
|
||||
isInstalledInCoreMethod.value(instance, context)?.booleanValue()
|
||||
?: throw IllegalStateException("isInstalledMethod not found")
|
||||
isInstalledInCoreMethod.value(instance, context)?.booleanValue() ?:
|
||||
false
|
||||
|
||||
fun enhanceStackTraceWithThreadDump(
|
||||
context: DefaultExecutionContext,
|
||||
@@ -54,6 +52,32 @@ class DebugProbesImpl private constructor(context: DefaultExecutionContext) :
|
||||
return referenceList.values.mapNotNull { coroutineInfo.mirror(it, context) }
|
||||
}
|
||||
|
||||
fun canDumpCoroutinesInfoAsJsonAndReferences() =
|
||||
dumpCoroutinesInfoAsJsonAndReferences.method != null
|
||||
|
||||
fun dumpCoroutinesInfoAsJsonAndReferences(executionContext: DefaultExecutionContext) =
|
||||
dumpCoroutinesInfoAsJsonAndReferences.value(instance, executionContext)
|
||||
|
||||
fun getCoroutineInfo(
|
||||
value: ObjectReference,
|
||||
context: DefaultExecutionContext,
|
||||
coroutineContext: MirrorOfCoroutineContext,
|
||||
sequenceNumber: Long?,
|
||||
state: String?,
|
||||
lastObservedThread: ThreadReference?,
|
||||
lastObservedFrame: ObjectReference?
|
||||
): MirrorOfCoroutineInfo {
|
||||
return coroutineInfo.fetchMirror(
|
||||
value,
|
||||
context,
|
||||
coroutineContext,
|
||||
sequenceNumber,
|
||||
state,
|
||||
lastObservedThread,
|
||||
lastObservedFrame
|
||||
)
|
||||
}
|
||||
|
||||
fun getCoroutineInfo(value: ObjectReference?, context: DefaultExecutionContext): MirrorOfCoroutineInfo? {
|
||||
val coroutineOwner = debugProbesCoroutineOwner.mirror(value, context)
|
||||
return coroutineOwner?.coroutineInfo
|
||||
@@ -119,9 +143,8 @@ class DebugCoroutineInfoImpl(context: DefaultExecutionContext) :
|
||||
}
|
||||
|
||||
return MirrorOfCoroutineInfo(
|
||||
value,
|
||||
sequenceNumber.value(value)?.longValue(),
|
||||
coroutineContext,
|
||||
sequenceNumber.value(value)?.longValue(),
|
||||
state,
|
||||
lastObservedThread.value(value),
|
||||
lastObservedFrame.mirror(value, context)?.reference,
|
||||
@@ -140,7 +163,7 @@ class CoroutineInfo private constructor(
|
||||
private val contextFieldRef by FieldMirrorDelegate("context", CoroutineContext(context))
|
||||
private val sequenceNumberField by FieldDelegate<LongValue>("sequenceNumber")
|
||||
private val creationStackTraceMethod by MethodMirrorDelegate("getCreationStackTrace", JavaUtilAbstractCollection(context))
|
||||
private val stateMethod by MethodMirrorDelegate<ObjectReference, String>("getState", JavaLangObjectToString(context))
|
||||
private val stateMethod by MethodDelegate<StringReference>("getState", "()Ljava/lang/String;")
|
||||
private val lastObservedStackTraceMethod by MethodDelegate<ObjectReference>("lastObservedStackTrace")
|
||||
|
||||
private val lastObservedFrameField by FieldDelegate<ObjectReference>("lastObservedFrame")
|
||||
@@ -162,32 +185,54 @@ class CoroutineInfo private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun fetchMirror(
|
||||
value: ObjectReference,
|
||||
context: DefaultExecutionContext,
|
||||
coroutineContext: MirrorOfCoroutineContext,
|
||||
sequenceNumber: Long?,
|
||||
state: String?,
|
||||
lastObservedThread: ThreadReference?,
|
||||
lastObservedFrame: ObjectReference?
|
||||
): MirrorOfCoroutineInfo {
|
||||
return MirrorOfCoroutineInfo(
|
||||
coroutineContext,
|
||||
sequenceNumber,
|
||||
state,
|
||||
lastObservedThread,
|
||||
lastObservedFrame,
|
||||
getEnhancedStackTraceProvider(value, context),
|
||||
getCreationStackTraceProvider(value, context)
|
||||
)
|
||||
}
|
||||
|
||||
override fun fetchMirror(value: ObjectReference, context: DefaultExecutionContext): MirrorOfCoroutineInfo {
|
||||
val state = stateMethod.mirror(value, context)
|
||||
val state = stateMethod.value(value, context)
|
||||
val coroutineContext = contextFieldRef.mirror(value, context)
|
||||
val sequenceNumber = sequenceNumberField.value(value)?.longValue()
|
||||
val enhancedStackTraceProvider = {
|
||||
return MirrorOfCoroutineInfo(
|
||||
coroutineContext,
|
||||
sequenceNumber,
|
||||
state?.value(),
|
||||
lastObservedThreadField.value(value),
|
||||
lastObservedFrameField.value(value),
|
||||
getEnhancedStackTraceProvider(value, context),
|
||||
getCreationStackTraceProvider(value, context)
|
||||
)
|
||||
}
|
||||
|
||||
private fun getCreationStackTraceProvider(value: ObjectReference, context: DefaultExecutionContext) =
|
||||
StackTraceMirrorProvider {
|
||||
val creationStackTraceMirror = creationStackTraceMethod.mirror(value, context)
|
||||
creationStackTraceMirror?.values?.mapNotNull { stackTraceElement.mirror(it, context) }
|
||||
}
|
||||
|
||||
private fun getEnhancedStackTraceProvider(value: ObjectReference, context: DefaultExecutionContext) =
|
||||
StackTraceMirrorProvider {
|
||||
val lastObservedStackTrace = lastObservedStackTraceMethod.value(value, context)
|
||||
if (lastObservedStackTrace != null)
|
||||
debugProbesImplMirror.enhanceStackTraceWithThreadDump(context, value, lastObservedStackTrace)
|
||||
else
|
||||
emptyList()
|
||||
}
|
||||
val creationStackTraceProvider = {
|
||||
val creationStackTraceMirror = creationStackTraceMethod.mirror(value, context)
|
||||
creationStackTraceMirror?.values?.mapNotNull { stackTraceElement.mirror(it, context) }
|
||||
}
|
||||
|
||||
return MirrorOfCoroutineInfo(
|
||||
value,
|
||||
sequenceNumber,
|
||||
coroutineContext,
|
||||
state,
|
||||
lastObservedThreadField.value(value),
|
||||
lastObservedFrameField.value(value),
|
||||
enhancedStackTraceProvider,
|
||||
creationStackTraceProvider
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,16 +11,14 @@ class CoroutineContext(context: DefaultExecutionContext) :
|
||||
BaseMirror<ObjectReference, MirrorOfCoroutineContext>("kotlin.coroutines.CombinedContext", context) {
|
||||
private val coroutineNameRef = CoroutineName(context)
|
||||
private val coroutineIdRef = CoroutineId(context)
|
||||
private val jobRef = Job(context)
|
||||
private val dispatcherRef = CoroutineDispatcher(context)
|
||||
private val getContextElement by MethodDelegate<ObjectReference>("get")
|
||||
|
||||
override fun fetchMirror(value: ObjectReference, context: DefaultExecutionContext): MirrorOfCoroutineContext? {
|
||||
override fun fetchMirror(value: ObjectReference, context: DefaultExecutionContext): MirrorOfCoroutineContext {
|
||||
val coroutineName = getElementValue(value, context, coroutineNameRef)
|
||||
val coroutineId = getElementValue(value, context, coroutineIdRef)
|
||||
val job = getElementValue(value, context, jobRef)
|
||||
val dispatcher = getElementValue(value, context, dispatcherRef)
|
||||
return MirrorOfCoroutineContext(value, coroutineName, coroutineId, dispatcher, job)
|
||||
return MirrorOfCoroutineContext(coroutineName, coroutineId, dispatcher)
|
||||
}
|
||||
|
||||
private fun <T> getElementValue(value: ObjectReference, context: DefaultExecutionContext, keyProvider: ContextKey<T>): T? {
|
||||
@@ -56,16 +54,6 @@ class CoroutineId(context: DefaultExecutionContext) : ContextKey<Long>("kotlinx.
|
||||
override fun key() = key.staticValue()
|
||||
}
|
||||
|
||||
class Job(context: DefaultExecutionContext) : ContextKey<ObjectReference>("kotlinx.coroutines.Job\$Key", context) {
|
||||
private val key by FieldDelegate<ObjectReference>("\$\$INSTANCE")
|
||||
|
||||
override fun fetchMirror(value: ObjectReference, context: DefaultExecutionContext): ObjectReference? {
|
||||
return value
|
||||
}
|
||||
|
||||
override fun key() = key.staticValue()
|
||||
}
|
||||
|
||||
class CoroutineDispatcher(context: DefaultExecutionContext) : ContextKey<String>("kotlinx.coroutines.CoroutineDispatcher", context) {
|
||||
private val key by FieldDelegate<ObjectReference>("Key")
|
||||
private val jlm = JavaLangObjectToString(context)
|
||||
|
||||
@@ -11,11 +11,9 @@ data class MirrorOfStandaloneCoroutine(
|
||||
)
|
||||
|
||||
data class MirrorOfCoroutineContext(
|
||||
val that: ObjectReference,
|
||||
val name: String?,
|
||||
val id: Long?,
|
||||
val dispatcher: String?,
|
||||
val job: ObjectReference?
|
||||
)
|
||||
|
||||
data class MirrorOfCoroutineOwner(val that: ObjectReference, val coroutineInfo: MirrorOfCoroutineInfo?)
|
||||
@@ -25,9 +23,8 @@ data class MirrorOfDebugProbesImpl(val that: ObjectReference, val instance: Obje
|
||||
data class MirrorOfWeakReference(val that: ObjectReference, val reference: ObjectReference?)
|
||||
|
||||
data class MirrorOfCoroutineInfo(
|
||||
val that: ObjectReference,
|
||||
val sequenceNumber: Long?,
|
||||
val context: MirrorOfCoroutineContext?,
|
||||
val sequenceNumber: Long?,
|
||||
val state: String?,
|
||||
val lastObservedThread: ThreadReference?,
|
||||
val lastObservedFrame: ObjectReference?,
|
||||
|
||||
Reference in New Issue
Block a user