jimu-decompiled/sources/com/squareup/leakcanary/ShortestPathFinder.java
2025-05-13 19:24:51 +02:00

383 lines
16 KiB
Java

package com.squareup.leakcanary;
import com.squareup.haha.perflib.ArrayInstance;
import com.squareup.haha.perflib.ClassInstance;
import com.squareup.haha.perflib.ClassObj;
import com.squareup.haha.perflib.Field;
import com.squareup.haha.perflib.HahaSpy;
import com.squareup.haha.perflib.Instance;
import com.squareup.haha.perflib.RootObj;
import com.squareup.haha.perflib.RootType;
import com.squareup.haha.perflib.Snapshot;
import com.squareup.haha.perflib.Type;
import com.squareup.leakcanary.LeakTraceElement;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
/* loaded from: classes.dex */
final class ShortestPathFinder {
private boolean canIgnoreStrings;
private final ExcludedRefs excludedRefs;
private final Deque<LeakNode> toVisitQueue = new ArrayDeque();
private final Deque<LeakNode> toVisitIfNoPathQueue = new ArrayDeque();
private final LinkedHashSet<Instance> toVisitSet = new LinkedHashSet<>();
private final LinkedHashSet<Instance> toVisitIfNoPathSet = new LinkedHashSet<>();
private final LinkedHashSet<Instance> visitedSet = new LinkedHashSet<>();
/* renamed from: com.squareup.leakcanary.ShortestPathFinder$1, reason: invalid class name */
static /* synthetic */ class AnonymousClass1 {
static final /* synthetic */ int[] $SwitchMap$com$squareup$haha$perflib$RootType = new int[RootType.values().length];
static {
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.JAVA_LOCAL.ordinal()] = 1;
} catch (NoSuchFieldError unused) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.INTERNED_STRING.ordinal()] = 2;
} catch (NoSuchFieldError unused2) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.DEBUGGER.ordinal()] = 3;
} catch (NoSuchFieldError unused3) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.INVALID_TYPE.ordinal()] = 4;
} catch (NoSuchFieldError unused4) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.UNREACHABLE.ordinal()] = 5;
} catch (NoSuchFieldError unused5) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.UNKNOWN.ordinal()] = 6;
} catch (NoSuchFieldError unused6) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.FINALIZING.ordinal()] = 7;
} catch (NoSuchFieldError unused7) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.SYSTEM_CLASS.ordinal()] = 8;
} catch (NoSuchFieldError unused8) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.VM_INTERNAL.ordinal()] = 9;
} catch (NoSuchFieldError unused9) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.NATIVE_LOCAL.ordinal()] = 10;
} catch (NoSuchFieldError unused10) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.NATIVE_STATIC.ordinal()] = 11;
} catch (NoSuchFieldError unused11) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.THREAD_BLOCK.ordinal()] = 12;
} catch (NoSuchFieldError unused12) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.BUSY_MONITOR.ordinal()] = 13;
} catch (NoSuchFieldError unused13) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.NATIVE_MONITOR.ordinal()] = 14;
} catch (NoSuchFieldError unused14) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.REFERENCE_CLEANUP.ordinal()] = 15;
} catch (NoSuchFieldError unused15) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.NATIVE_STACK.ordinal()] = 16;
} catch (NoSuchFieldError unused16) {
}
try {
$SwitchMap$com$squareup$haha$perflib$RootType[RootType.JAVA_STATIC.ordinal()] = 17;
} catch (NoSuchFieldError unused17) {
}
}
}
static final class Result {
final boolean excludingKnownLeaks;
final LeakNode leakingNode;
Result(LeakNode leakNode, boolean z) {
this.leakingNode = leakNode;
this.excludingKnownLeaks = z;
}
}
ShortestPathFinder(ExcludedRefs excludedRefs) {
this.excludedRefs = excludedRefs;
}
private boolean checkSeen(LeakNode leakNode) {
return !this.visitedSet.add(leakNode.instance);
}
private void clearState() {
this.toVisitQueue.clear();
this.toVisitIfNoPathQueue.clear();
this.toVisitSet.clear();
this.toVisitIfNoPathSet.clear();
this.visitedSet.clear();
}
private void enqueue(Exclusion exclusion, LeakNode leakNode, Instance instance, LeakReference leakReference) {
if (instance == null || HahaHelper.isPrimitiveOrWrapperArray(instance) || HahaHelper.isPrimitiveWrapper(instance) || this.toVisitSet.contains(instance)) {
return;
}
boolean z = exclusion == null;
if (z || !this.toVisitIfNoPathSet.contains(instance)) {
if ((this.canIgnoreStrings && isString(instance)) || this.visitedSet.contains(instance)) {
return;
}
LeakNode leakNode2 = new LeakNode(exclusion, instance, leakNode, leakReference);
if (z) {
this.toVisitSet.add(instance);
this.toVisitQueue.add(leakNode2);
} else {
this.toVisitIfNoPathSet.add(instance);
this.toVisitIfNoPathQueue.add(leakNode2);
}
}
}
private void enqueueGcRoots(Snapshot snapshot) {
for (RootObj rootObj : HahaSpy.allGcRoots(snapshot)) {
switch (AnonymousClass1.$SwitchMap$com$squareup$haha$perflib$RootType[rootObj.getRootType().ordinal()]) {
case 1:
Exclusion exclusion = this.excludedRefs.threadNames.get(HahaHelper.threadName(HahaSpy.allocatingThread(rootObj)));
if (exclusion == null || !exclusion.alwaysExclude) {
enqueue(exclusion, null, rootObj, null);
break;
} else {
break;
}
break;
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
break;
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
enqueue(null, null, rootObj, null);
break;
default:
throw new UnsupportedOperationException("Unknown root type:" + rootObj.getRootType());
}
}
}
private boolean isString(Instance instance) {
return instance.getClassObj() != null && instance.getClassObj().getClassName().equals(String.class.getName());
}
private void visitArrayInstance(LeakNode leakNode) {
ArrayInstance arrayInstance = (ArrayInstance) leakNode.instance;
if (arrayInstance.getArrayType() == Type.OBJECT) {
Object[] values = arrayInstance.getValues();
for (int i = 0; i < values.length; i++) {
Instance instance = (Instance) values[i];
enqueue(null, leakNode, instance, new LeakReference(LeakTraceElement.Type.ARRAY_ENTRY, Integer.toString(i), instance == null ? "null" : instance.toString()));
}
}
}
private void visitClassInstance(LeakNode leakNode) {
ClassInstance classInstance = (ClassInstance) leakNode.instance;
LinkedHashMap linkedHashMap = new LinkedHashMap();
Exclusion exclusion = null;
for (ClassObj classObj = classInstance.getClassObj(); classObj != null; classObj = classObj.getSuperClassObj()) {
Exclusion exclusion2 = this.excludedRefs.classNames.get(classObj.getClassName());
if (exclusion2 != null && (exclusion == null || !exclusion.alwaysExclude)) {
exclusion = exclusion2;
}
Map<String, Exclusion> map = this.excludedRefs.fieldNameByClassName.get(classObj.getClassName());
if (map != null) {
linkedHashMap.putAll(map);
}
}
if (exclusion == null || !exclusion.alwaysExclude) {
for (ClassInstance.FieldValue fieldValue : classInstance.getValues()) {
Field field = fieldValue.getField();
if (field.getType() == Type.OBJECT) {
Instance instance = (Instance) fieldValue.getValue();
String name = field.getName();
Exclusion exclusion3 = (Exclusion) linkedHashMap.get(name);
if (exclusion3 == null || (exclusion != null && (!exclusion3.alwaysExclude || exclusion.alwaysExclude))) {
exclusion3 = exclusion;
}
enqueue(exclusion3, leakNode, instance, new LeakReference(LeakTraceElement.Type.INSTANCE_FIELD, name, fieldValue.getValue() == null ? "null" : fieldValue.getValue().toString()));
}
}
}
}
private void visitClassObj(LeakNode leakNode) {
Exclusion exclusion;
ClassObj classObj = (ClassObj) leakNode.instance;
Map<String, Exclusion> map = this.excludedRefs.staticFieldNameByClassName.get(classObj.getClassName());
for (Map.Entry<Field, Object> entry : classObj.getStaticFieldValues().entrySet()) {
Field key = entry.getKey();
if (key.getType() == Type.OBJECT) {
String name = key.getName();
if (!name.equals("$staticOverhead")) {
Instance instance = (Instance) entry.getValue();
boolean z = true;
LeakReference leakReference = new LeakReference(LeakTraceElement.Type.STATIC_FIELD, name, entry.getValue() == null ? "null" : entry.getValue().toString());
if (map != null && (exclusion = map.get(name)) != null) {
z = false;
if (!exclusion.alwaysExclude) {
enqueue(exclusion, leakNode, instance, leakReference);
}
}
if (z) {
enqueue(null, leakNode, instance, leakReference);
}
}
}
}
}
private void visitRootObj(LeakNode leakNode) {
RootObj rootObj = (RootObj) leakNode.instance;
Instance referredInstance = rootObj.getReferredInstance();
if (rootObj.getRootType() != RootType.JAVA_LOCAL) {
enqueue(null, leakNode, referredInstance, null);
return;
}
Instance allocatingThread = HahaSpy.allocatingThread(rootObj);
Exclusion exclusion = leakNode.exclusion;
if (exclusion == null) {
exclusion = null;
}
enqueue(exclusion, new LeakNode(null, allocatingThread, null, null), referredInstance, new LeakReference(LeakTraceElement.Type.LOCAL, null, null));
}
/* JADX WARN: Code restructure failed: missing block: B:9:0x004e, code lost:
return new com.squareup.leakcanary.ShortestPathFinder.Result(r7, r2);
*/
/*
Code decompiled incorrectly, please refer to instructions dump.
To view partially-correct code enable 'Show inconsistent code' option in preferences
*/
com.squareup.leakcanary.ShortestPathFinder.Result findPath(com.squareup.haha.perflib.Snapshot r7, com.squareup.haha.perflib.Instance r8) {
/*
r6 = this;
r6.clearState()
boolean r0 = r6.isString(r8)
r1 = 1
r0 = r0 ^ r1
r6.canIgnoreStrings = r0
r6.enqueueGcRoots(r7)
r7 = 0
r0 = 0
L10:
java.util.Deque<com.squareup.leakcanary.LeakNode> r2 = r6.toVisitQueue
boolean r2 = r2.isEmpty()
if (r2 == 0) goto L24
java.util.Deque<com.squareup.leakcanary.LeakNode> r2 = r6.toVisitIfNoPathQueue
boolean r2 = r2.isEmpty()
if (r2 != 0) goto L21
goto L24
L21:
r2 = r7
r7 = r0
goto L49
L24:
java.util.Deque<com.squareup.leakcanary.LeakNode> r2 = r6.toVisitQueue
boolean r2 = r2.isEmpty()
if (r2 != 0) goto L38
java.util.Deque<com.squareup.leakcanary.LeakNode> r2 = r6.toVisitQueue
java.lang.Object r2 = r2.poll()
com.squareup.leakcanary.LeakNode r2 = (com.squareup.leakcanary.LeakNode) r2
r5 = r2
r2 = r7
r7 = r5
goto L45
L38:
java.util.Deque<com.squareup.leakcanary.LeakNode> r7 = r6.toVisitIfNoPathQueue
java.lang.Object r7 = r7.poll()
com.squareup.leakcanary.LeakNode r7 = (com.squareup.leakcanary.LeakNode) r7
com.squareup.leakcanary.Exclusion r2 = r7.exclusion
if (r2 == 0) goto L92
r2 = 1
L45:
com.squareup.haha.perflib.Instance r3 = r7.instance
if (r3 != r8) goto L4f
L49:
com.squareup.leakcanary.ShortestPathFinder$Result r8 = new com.squareup.leakcanary.ShortestPathFinder$Result
r8.<init>(r7, r2)
return r8
L4f:
boolean r3 = r6.checkSeen(r7)
if (r3 == 0) goto L56
goto L77
L56:
com.squareup.haha.perflib.Instance r3 = r7.instance
boolean r4 = r3 instanceof com.squareup.haha.perflib.RootObj
if (r4 == 0) goto L60
r6.visitRootObj(r7)
goto L77
L60:
boolean r4 = r3 instanceof com.squareup.haha.perflib.ClassObj
if (r4 == 0) goto L68
r6.visitClassObj(r7)
goto L77
L68:
boolean r4 = r3 instanceof com.squareup.haha.perflib.ClassInstance
if (r4 == 0) goto L70
r6.visitClassInstance(r7)
goto L77
L70:
boolean r3 = r3 instanceof com.squareup.haha.perflib.ArrayInstance
if (r3 == 0) goto L79
r6.visitArrayInstance(r7)
L77:
r7 = r2
goto L10
L79:
java.lang.IllegalStateException r8 = new java.lang.IllegalStateException
java.lang.StringBuilder r0 = new java.lang.StringBuilder
r0.<init>()
java.lang.String r1 = "Unexpected type for "
r0.append(r1)
com.squareup.haha.perflib.Instance r7 = r7.instance
r0.append(r7)
java.lang.String r7 = r0.toString()
r8.<init>(r7)
throw r8
L92:
java.lang.IllegalStateException r8 = new java.lang.IllegalStateException
java.lang.StringBuilder r0 = new java.lang.StringBuilder
r0.<init>()
java.lang.String r1 = "Expected node to have an exclusion "
r0.append(r1)
r0.append(r7)
java.lang.String r7 = r0.toString()
r8.<init>(r7)
throw r8
*/
throw new UnsupportedOperationException("Method not decompiled: com.squareup.leakcanary.ShortestPathFinder.findPath(com.squareup.haha.perflib.Snapshot, com.squareup.haha.perflib.Instance):com.squareup.leakcanary.ShortestPathFinder$Result");
}
}