mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
[coroutines-debugger] Fix the slow Coroutine View: obtain jobs and parents of coroutines with a Helper method.
Build the coroutine hierarchy in CoroutineView, from a job and the first parent of each coroutine. IDEA-335303 GitOrigin-RevId: 7fe634a291364438229cfae7680894fba25b07c6
This commit is contained in:
committed by
intellij-monorepo-bot
parent
cc2d37d9cc
commit
10472a2795
@@ -11,6 +11,10 @@ public final class CoroutinesDebugHelper {
|
||||
private static final String COROUTINE_OWNER_CLASS = "CoroutineOwner";
|
||||
private static final String DEBUG_METADATA_FQN = "kotlin.coroutines.jvm.internal.DebugMetadataKt";
|
||||
private static final String BASE_CONTINUATION_FQN = "kotlin.coroutines.jvm.internal.BaseContinuationImpl";
|
||||
private static final String DEBUG_COROUTINE_INFO_FQN = "kotlinx.coroutines.debug.internal.DebugCoroutineInfo";
|
||||
private static final String COROUTINE_CONTEXT_FQN = "kotlin.coroutines.CoroutineContext";
|
||||
private static final String COROUTINE_JOB_FQN = "kotlinx.coroutines.Job";
|
||||
private static final String COROUTINE_CONTEXT_KEY_FQN = "kotlin.coroutines.CoroutineContext$Key";
|
||||
|
||||
public static long[] getCoroutinesRunningOnCurrentThread(Object debugProbes, Thread currentThread) throws ReflectiveOperationException {
|
||||
List<Long> coroutinesIds = new ArrayList<>();
|
||||
@@ -140,12 +144,62 @@ public final class CoroutinesDebugHelper {
|
||||
return current.getClass().getSimpleName().contains(COROUTINE_OWNER_CLASS);
|
||||
}
|
||||
|
||||
public static Object[] dumpCoroutinesInfoAsJsonAndReferences() throws ReflectiveOperationException {
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
Class<?> debugProbesImplClass = classLoader.loadClass("kotlinx.coroutines.debug.internal.DebugProbesImpl");
|
||||
Object debugProbesImplInstance = debugProbesImplClass.getField("INSTANCE").get(null);
|
||||
Object[] infos = (Object[])invoke(debugProbesImplInstance, "dumpCoroutinesInfoAsJsonAndReferences");
|
||||
return infos;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes the array of {@link kotlinx.coroutines.debug.internal.DebugCoroutineInfo} instances
|
||||
* and for each coroutine requests it's job, and it's first parent.
|
||||
*
|
||||
* @return an array of Strings of size (debugCoroutineInfos.size * 2), where
|
||||
* (2 * i)-th element is a String representation of the job and
|
||||
* (2 * i + 1)-th element is a String representation of the parent of the i-th coroutine from debugCoroutineInfos array.
|
||||
*/
|
||||
public static String[] getJobsAndParentsForCoroutines(Object ... debugCoroutineInfos) throws ReflectiveOperationException {
|
||||
if (debugCoroutineInfos.length == 0) return new String[]{};
|
||||
String[] jobsWithParents = new String[debugCoroutineInfos.length * 2];
|
||||
ClassLoader loader = debugCoroutineInfos[0].getClass().getClassLoader();
|
||||
Class<?> debugCoroutineInfoClass = Class.forName(DEBUG_COROUTINE_INFO_FQN, false, loader);
|
||||
Class<?> coroutineContext = Class.forName(COROUTINE_CONTEXT_FQN, false, loader);
|
||||
Class<?> coroutineContextKey = Class.forName(COROUTINE_CONTEXT_KEY_FQN, false, loader);
|
||||
Class<?> coroutineJobClass = Class.forName(COROUTINE_JOB_FQN, false, loader);
|
||||
Object coroutineJobKey = coroutineJobClass.getField("Key").get(null); // Job.Key
|
||||
Method coroutineContextGet = coroutineContext.getMethod("get", coroutineContextKey);
|
||||
Method getParentJob = coroutineJobClass.getMethod("getParent");
|
||||
Method getContext = debugCoroutineInfoClass.getMethod("getContext");
|
||||
|
||||
for (int i = 0; i < debugCoroutineInfos.length * 2; i += 2) {
|
||||
Object info = debugCoroutineInfos[i / 2];
|
||||
if (info == null) {
|
||||
jobsWithParents[i] = null;
|
||||
jobsWithParents[i + 1] = null;
|
||||
continue;
|
||||
}
|
||||
Object context = invoke(info, getContext);
|
||||
Object job = invoke(context, coroutineContextGet, coroutineJobKey);
|
||||
Object parent = invoke(job, getParentJob);
|
||||
jobsWithParents[i] = (job == null) ? null : job.toString();
|
||||
jobsWithParents[i + 1] = (parent == null) ? null : parent.toString();
|
||||
}
|
||||
return jobsWithParents;
|
||||
}
|
||||
|
||||
private static Object getField(Object object, String fieldName) throws ReflectiveOperationException {
|
||||
Field field = object.getClass().getField(fieldName);
|
||||
field.setAccessible(true);
|
||||
return field.get(object);
|
||||
}
|
||||
|
||||
private static Object invoke(Object object, Method method, Object... args) throws ReflectiveOperationException {
|
||||
method.setAccessible(true);
|
||||
return method.invoke(object, args);
|
||||
}
|
||||
|
||||
private static Object invoke(Object object, String methodName) throws ReflectiveOperationException {
|
||||
Method method = object.getClass().getMethod(methodName);
|
||||
method.setAccessible(true);
|
||||
|
||||
Reference in New Issue
Block a user