Initial commit
This commit is contained in:
82
sources/com/squareup/haha/perflib/ArrayInstance.java
Normal file
82
sources/com/squareup/haha/perflib/ArrayInstance.java
Normal file
@@ -0,0 +1,82 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
import com.squareup.haha.perflib.io.HprofBuffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class ArrayInstance extends Instance {
|
||||
static final /* synthetic */ boolean $assertionsDisabled = false;
|
||||
private final int mLength;
|
||||
private final Type mType;
|
||||
private final long mValuesOffset;
|
||||
|
||||
public ArrayInstance(long j, StackTrace stackTrace, Type type, int i, long j2) {
|
||||
super(j, stackTrace);
|
||||
this.mType = type;
|
||||
this.mLength = i;
|
||||
this.mValuesOffset = j2;
|
||||
}
|
||||
|
||||
private byte[] asRawByteArray(int i, int i2) {
|
||||
getBuffer().setPosition(this.mValuesOffset);
|
||||
byte[] bArr = new byte[this.mType.getSize() * i2];
|
||||
getBuffer().readSubSequence(bArr, i * this.mType.getSize(), i2 * this.mType.getSize());
|
||||
return bArr;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.Instance
|
||||
public final void accept(Visitor visitor) {
|
||||
visitor.visitArrayInstance(this);
|
||||
if (this.mType == Type.OBJECT) {
|
||||
for (Object obj : getValues()) {
|
||||
if (obj instanceof Instance) {
|
||||
if (!this.mReferencesAdded) {
|
||||
((Instance) obj).addReference(null, this);
|
||||
}
|
||||
visitor.visitLater(this, (Instance) obj);
|
||||
}
|
||||
}
|
||||
this.mReferencesAdded = true;
|
||||
}
|
||||
}
|
||||
|
||||
public char[] asCharArray(int i, int i2) {
|
||||
CharBuffer asCharBuffer = ByteBuffer.wrap(asRawByteArray(i, i2)).order(HprofBuffer.HPROF_BYTE_ORDER).asCharBuffer();
|
||||
char[] cArr = new char[i2];
|
||||
asCharBuffer.get(cArr);
|
||||
return cArr;
|
||||
}
|
||||
|
||||
public Type getArrayType() {
|
||||
return this.mType;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.Instance
|
||||
public ClassObj getClassObj() {
|
||||
Type type = this.mType;
|
||||
return type == Type.OBJECT ? super.getClassObj() : this.mHeap.mSnapshot.findClass(Type.getClassNameOfPrimitiveArray(type));
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.Instance
|
||||
public final int getSize() {
|
||||
return this.mLength * this.mHeap.mSnapshot.getTypeSize(this.mType);
|
||||
}
|
||||
|
||||
public Object[] getValues() {
|
||||
Object[] objArr = new Object[this.mLength];
|
||||
getBuffer().setPosition(this.mValuesOffset);
|
||||
for (int i = 0; i < this.mLength; i++) {
|
||||
objArr[i] = readValue(this.mType);
|
||||
}
|
||||
return objArr;
|
||||
}
|
||||
|
||||
public final String toString() {
|
||||
String className = getClassObj().getClassName();
|
||||
if (className.endsWith("[]")) {
|
||||
className = className.substring(0, className.length() - 2);
|
||||
}
|
||||
return String.format("%s[%d]@%d (0x%x)", className, Integer.valueOf(this.mLength), Long.valueOf(getUniqueId()), Long.valueOf(getUniqueId()));
|
||||
}
|
||||
}
|
76
sources/com/squareup/haha/perflib/ClassInstance.java
Normal file
76
sources/com/squareup/haha/perflib/ClassInstance.java
Normal file
@@ -0,0 +1,76 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class ClassInstance extends Instance {
|
||||
private final long mValuesOffset;
|
||||
|
||||
public static class FieldValue {
|
||||
private Field mField;
|
||||
private Object mValue;
|
||||
|
||||
public FieldValue(Field field, Object obj) {
|
||||
this.mField = field;
|
||||
this.mValue = obj;
|
||||
}
|
||||
|
||||
public Field getField() {
|
||||
return this.mField;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return this.mValue;
|
||||
}
|
||||
}
|
||||
|
||||
public ClassInstance(long j, StackTrace stackTrace, long j2) {
|
||||
super(j, stackTrace);
|
||||
this.mValuesOffset = j2;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.Instance
|
||||
public final void accept(Visitor visitor) {
|
||||
visitor.visitClassInstance(this);
|
||||
for (FieldValue fieldValue : getValues()) {
|
||||
if (fieldValue.getValue() instanceof Instance) {
|
||||
if (!this.mReferencesAdded) {
|
||||
((Instance) fieldValue.getValue()).addReference(fieldValue.getField(), this);
|
||||
}
|
||||
visitor.visitLater(this, (Instance) fieldValue.getValue());
|
||||
}
|
||||
}
|
||||
this.mReferencesAdded = true;
|
||||
}
|
||||
|
||||
List<FieldValue> getFields(String str) {
|
||||
ArrayList arrayList = new ArrayList();
|
||||
for (FieldValue fieldValue : getValues()) {
|
||||
if (fieldValue.getField().getName().equals(str)) {
|
||||
arrayList.add(fieldValue);
|
||||
}
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.Instance
|
||||
public boolean getIsSoftReference() {
|
||||
return getClassObj().getIsSoftReference();
|
||||
}
|
||||
|
||||
public List<FieldValue> getValues() {
|
||||
ArrayList arrayList = new ArrayList();
|
||||
getBuffer().setPosition(this.mValuesOffset);
|
||||
for (ClassObj classObj = getClassObj(); classObj != null; classObj = classObj.getSuperClassObj()) {
|
||||
for (Field field : classObj.getFields()) {
|
||||
arrayList.add(new FieldValue(field, readValue(field.getType())));
|
||||
}
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public final String toString() {
|
||||
return String.format("%s@%d (0x%x)", getClassObj().getClassName(), Long.valueOf(getUniqueId()), Long.valueOf(getUniqueId()));
|
||||
}
|
||||
}
|
260
sources/com/squareup/haha/perflib/ClassObj.java
Normal file
260
sources/com/squareup/haha/perflib/ClassObj.java
Normal file
@@ -0,0 +1,260 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class ClassObj extends Instance implements Comparable<ClassObj> {
|
||||
long mClassLoaderId;
|
||||
final String mClassName;
|
||||
Field[] mFields;
|
||||
TIntObjectHashMap<HeapData> mHeapData;
|
||||
private int mInstanceSize;
|
||||
private boolean mIsSoftReference;
|
||||
Field[] mStaticFields;
|
||||
private final long mStaticFieldsOffset;
|
||||
Set<ClassObj> mSubclasses;
|
||||
long mSuperClassId;
|
||||
|
||||
public static class HeapData {
|
||||
public int mShallowSize = 0;
|
||||
public List<Instance> mInstances = new ArrayList();
|
||||
}
|
||||
|
||||
public ClassObj(long j, StackTrace stackTrace, String str, long j2) {
|
||||
super(j, stackTrace);
|
||||
this.mIsSoftReference = false;
|
||||
this.mHeapData = new TIntObjectHashMap<>();
|
||||
this.mSubclasses = new HashSet();
|
||||
this.mClassName = str;
|
||||
this.mStaticFieldsOffset = j2;
|
||||
}
|
||||
|
||||
public static String getReferenceClassName() {
|
||||
return "java.lang.ref.Reference";
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.Instance
|
||||
public final void accept(Visitor visitor) {
|
||||
visitor.visitClassObj(this);
|
||||
for (Map.Entry<Field, Object> entry : getStaticFieldValues().entrySet()) {
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof Instance) {
|
||||
if (!this.mReferencesAdded) {
|
||||
((Instance) value).addReference(entry.getKey(), this);
|
||||
}
|
||||
visitor.visitLater(this, (Instance) value);
|
||||
}
|
||||
}
|
||||
this.mReferencesAdded = true;
|
||||
}
|
||||
|
||||
public final void addInstance(int i, Instance instance) {
|
||||
if (instance instanceof ClassInstance) {
|
||||
instance.setSize(this.mInstanceSize);
|
||||
}
|
||||
HeapData heapData = this.mHeapData.get(i);
|
||||
if (heapData == null) {
|
||||
heapData = new HeapData();
|
||||
this.mHeapData.put(i, heapData);
|
||||
}
|
||||
heapData.mInstances.add(instance);
|
||||
heapData.mShallowSize += instance.getSize();
|
||||
}
|
||||
|
||||
public final void addSubclass(ClassObj classObj) {
|
||||
this.mSubclasses.add(classObj);
|
||||
}
|
||||
|
||||
public final void dump() {
|
||||
ClassObj classObj = this;
|
||||
while (true) {
|
||||
System.out.println("+---------- ClassObj dump for: " + classObj.mClassName);
|
||||
System.out.println("+----- Static fields");
|
||||
Map<Field, Object> staticFieldValues = classObj.getStaticFieldValues();
|
||||
for (Field field : staticFieldValues.keySet()) {
|
||||
System.out.println(field.getName() + ": " + field.getType() + " = " + staticFieldValues.get(field));
|
||||
}
|
||||
System.out.println("+----- Instance fields");
|
||||
for (Field field2 : classObj.mFields) {
|
||||
System.out.println(field2.getName() + ": " + field2.getType());
|
||||
}
|
||||
if (classObj.getSuperClassObj() == null) {
|
||||
return;
|
||||
} else {
|
||||
classObj = classObj.getSuperClassObj();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void dumpSubclasses() {
|
||||
for (ClassObj classObj : this.mSubclasses) {
|
||||
System.out.println(" " + classObj.mClassName);
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean equals(Object obj) {
|
||||
return (obj instanceof ClassObj) && compareTo((ClassObj) obj) == 0;
|
||||
}
|
||||
|
||||
public int getAllFieldsCount() {
|
||||
int i = 0;
|
||||
for (ClassObj classObj = this; classObj != null; classObj = classObj.getSuperClassObj()) {
|
||||
i += classObj.getFields().length;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
public Instance getClassLoader() {
|
||||
return this.mHeap.mSnapshot.findInstance(this.mClassLoaderId);
|
||||
}
|
||||
|
||||
public final String getClassName() {
|
||||
return this.mClassName;
|
||||
}
|
||||
|
||||
public List<ClassObj> getDescendantClasses() {
|
||||
ArrayList arrayList = new ArrayList();
|
||||
Stack stack = new Stack();
|
||||
stack.push(this);
|
||||
while (!stack.isEmpty()) {
|
||||
ClassObj classObj = (ClassObj) stack.pop();
|
||||
arrayList.add(classObj);
|
||||
Iterator<ClassObj> it = classObj.getSubclasses().iterator();
|
||||
while (it.hasNext()) {
|
||||
stack.push(it.next());
|
||||
}
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public Field[] getFields() {
|
||||
return this.mFields;
|
||||
}
|
||||
|
||||
public List<Instance> getHeapInstances(int i) {
|
||||
HeapData heapData = this.mHeapData.get(i);
|
||||
return heapData == null ? new ArrayList(0) : heapData.mInstances;
|
||||
}
|
||||
|
||||
public int getHeapInstancesCount(int i) {
|
||||
HeapData heapData = this.mHeapData.get(i);
|
||||
if (heapData == null) {
|
||||
return 0;
|
||||
}
|
||||
return heapData.mInstances.size();
|
||||
}
|
||||
|
||||
public int getInstanceCount() {
|
||||
int i = 0;
|
||||
for (Object obj : this.mHeapData.getValues()) {
|
||||
i += ((HeapData) obj).mInstances.size();
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
public int getInstanceSize() {
|
||||
return this.mInstanceSize;
|
||||
}
|
||||
|
||||
public List<Instance> getInstancesList() {
|
||||
ArrayList arrayList = new ArrayList(getInstanceCount());
|
||||
for (int i : this.mHeapData.keys()) {
|
||||
arrayList.addAll(getHeapInstances(i));
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.Instance
|
||||
public boolean getIsSoftReference() {
|
||||
return this.mIsSoftReference;
|
||||
}
|
||||
|
||||
public int getShallowSize(int i) {
|
||||
if (this.mHeapData.get(i) == null) {
|
||||
return 0;
|
||||
}
|
||||
return this.mHeapData.get(i).mShallowSize;
|
||||
}
|
||||
|
||||
Object getStaticField(Type type, String str) {
|
||||
return getStaticFieldValues().get(new Field(type, str));
|
||||
}
|
||||
|
||||
public Map<Field, Object> getStaticFieldValues() {
|
||||
HashMap hashMap = new HashMap();
|
||||
getBuffer().setPosition(this.mStaticFieldsOffset);
|
||||
int readUnsignedShort = readUnsignedShort();
|
||||
for (int i = 0; i < readUnsignedShort; i++) {
|
||||
Field field = this.mStaticFields[i];
|
||||
readId();
|
||||
readUnsignedByte();
|
||||
hashMap.put(field, readValue(field.getType()));
|
||||
}
|
||||
return hashMap;
|
||||
}
|
||||
|
||||
public final Set<ClassObj> getSubclasses() {
|
||||
return this.mSubclasses;
|
||||
}
|
||||
|
||||
public ClassObj getSuperClassObj() {
|
||||
return this.mHeap.mSnapshot.findClass(this.mSuperClassId);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.mClassName.hashCode();
|
||||
}
|
||||
|
||||
public final void setClassLoaderId(long j) {
|
||||
this.mClassLoaderId = j;
|
||||
}
|
||||
|
||||
public void setFields(Field[] fieldArr) {
|
||||
this.mFields = fieldArr;
|
||||
}
|
||||
|
||||
public void setInstanceSize(int i) {
|
||||
this.mInstanceSize = i;
|
||||
}
|
||||
|
||||
public void setIsSoftReference() {
|
||||
this.mIsSoftReference = true;
|
||||
}
|
||||
|
||||
public void setStaticFields(Field[] fieldArr) {
|
||||
this.mStaticFields = fieldArr;
|
||||
}
|
||||
|
||||
public final void setSuperClassId(long j) {
|
||||
this.mSuperClassId = j;
|
||||
}
|
||||
|
||||
public final String toString() {
|
||||
return this.mClassName.replace('/', '.');
|
||||
}
|
||||
|
||||
@Override // java.lang.Comparable
|
||||
public final int compareTo(ClassObj classObj) {
|
||||
if (getId() == classObj.getId()) {
|
||||
return 0;
|
||||
}
|
||||
int compareTo = this.mClassName.compareTo(classObj.mClassName);
|
||||
return compareTo != 0 ? compareTo : getId() - classObj.getId() > 0 ? 1 : -1;
|
||||
}
|
||||
|
||||
public int getShallowSize() {
|
||||
int i = 0;
|
||||
for (Object obj : this.mHeapData.getValues()) {
|
||||
i += ((HeapData) obj).mShallowSize;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
37
sources/com/squareup/haha/perflib/Field.java
Normal file
37
sources/com/squareup/haha/perflib/Field.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public final class Field {
|
||||
private final String mName;
|
||||
private final Type mType;
|
||||
|
||||
public Field(Type type, String str) {
|
||||
this.mType = type;
|
||||
this.mName = str;
|
||||
}
|
||||
|
||||
public final boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof Field)) {
|
||||
return false;
|
||||
}
|
||||
Field field = (Field) obj;
|
||||
return this.mType == field.mType && this.mName.equals(field.mName);
|
||||
}
|
||||
|
||||
public final String getName() {
|
||||
return this.mName;
|
||||
}
|
||||
|
||||
public final Type getType() {
|
||||
return this.mType;
|
||||
}
|
||||
|
||||
public final int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{this.mType, this.mName});
|
||||
}
|
||||
}
|
26
sources/com/squareup/haha/perflib/HahaSpy.java
Normal file
26
sources/com/squareup/haha/perflib/HahaSpy.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public final class HahaSpy {
|
||||
private HahaSpy() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public static Set<RootObj> allGcRoots(Snapshot snapshot) {
|
||||
HashSet hashSet = new HashSet();
|
||||
Iterator<Heap> it = snapshot.getHeaps().iterator();
|
||||
while (it.hasNext()) {
|
||||
hashSet.addAll(it.next().mRoots);
|
||||
}
|
||||
return hashSet;
|
||||
}
|
||||
|
||||
public static Instance allocatingThread(Instance instance) {
|
||||
Snapshot snapshot = instance.mHeap.mSnapshot;
|
||||
return snapshot.findInstance(snapshot.getThread(instance instanceof RootObj ? ((RootObj) instance).mThread : instance.mStack.mThreadSerialNumber).mId);
|
||||
}
|
||||
}
|
154
sources/com/squareup/haha/perflib/Heap.java
Normal file
154
sources/com/squareup/haha/perflib/Heap.java
Normal file
@@ -0,0 +1,154 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
import com.squareup.haha.guava.collect.ArrayListMultimap;
|
||||
import com.squareup.haha.guava.collect.Multimap;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import gnu.trove.TLongObjectHashMap;
|
||||
import gnu.trove.TObjectProcedure;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class Heap {
|
||||
private final int mId;
|
||||
private final String mName;
|
||||
Snapshot mSnapshot;
|
||||
TLongObjectHashMap<StackFrame> mFrames = new TLongObjectHashMap<>();
|
||||
TIntObjectHashMap<StackTrace> mTraces = new TIntObjectHashMap<>();
|
||||
ArrayList<RootObj> mRoots = new ArrayList<>();
|
||||
TIntObjectHashMap<ThreadObj> mThreads = new TIntObjectHashMap<>();
|
||||
TLongObjectHashMap<ClassObj> mClassesById = new TLongObjectHashMap<>();
|
||||
Multimap<String, ClassObj> mClassesByName = ArrayListMultimap.create();
|
||||
private final TLongObjectHashMap<Instance> mInstances = new TLongObjectHashMap<>();
|
||||
|
||||
public Heap(int i, String str) {
|
||||
this.mId = i;
|
||||
this.mName = str;
|
||||
}
|
||||
|
||||
public final void addClass(long j, ClassObj classObj) {
|
||||
this.mClassesById.put(j, classObj);
|
||||
this.mClassesByName.put(classObj.mClassName, classObj);
|
||||
}
|
||||
|
||||
public final void addInstance(long j, Instance instance) {
|
||||
this.mInstances.put(j, instance);
|
||||
}
|
||||
|
||||
public final void addRoot(RootObj rootObj) {
|
||||
rootObj.mIndex = this.mRoots.size();
|
||||
this.mRoots.add(rootObj);
|
||||
}
|
||||
|
||||
public final void addStackFrame(StackFrame stackFrame) {
|
||||
this.mFrames.put(stackFrame.mId, stackFrame);
|
||||
}
|
||||
|
||||
public final void addStackTrace(StackTrace stackTrace) {
|
||||
this.mTraces.put(stackTrace.mSerialNumber, stackTrace);
|
||||
}
|
||||
|
||||
public final void addThread(ThreadObj threadObj, int i) {
|
||||
this.mThreads.put(i, threadObj);
|
||||
}
|
||||
|
||||
public final void dumpInstanceCounts() {
|
||||
for (Object obj : this.mClassesById.getValues()) {
|
||||
ClassObj classObj = (ClassObj) obj;
|
||||
int instanceCount = classObj.getInstanceCount();
|
||||
if (instanceCount > 0) {
|
||||
System.out.println(classObj + ": " + instanceCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void dumpSizes() {
|
||||
for (Object obj : this.mClassesById.getValues()) {
|
||||
ClassObj classObj = (ClassObj) obj;
|
||||
Iterator<Instance> it = classObj.getHeapInstances(getId()).iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
i += it.next().getCompositeSize();
|
||||
}
|
||||
if (i > 0) {
|
||||
System.out.println(classObj + ": base " + classObj.getSize() + ", composite " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void dumpSubclasses() {
|
||||
for (Object obj : this.mClassesById.getValues()) {
|
||||
ClassObj classObj = (ClassObj) obj;
|
||||
if (classObj.mSubclasses.size() > 0) {
|
||||
System.out.println(classObj);
|
||||
classObj.dumpSubclasses();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final ClassObj getClass(long j) {
|
||||
return this.mClassesById.get(j);
|
||||
}
|
||||
|
||||
public final Collection<ClassObj> getClasses(String str) {
|
||||
return this.mClassesByName.get(str);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.mId;
|
||||
}
|
||||
|
||||
public final Instance getInstance(long j) {
|
||||
return this.mInstances.get(j);
|
||||
}
|
||||
|
||||
public Collection<Instance> getInstances() {
|
||||
final ArrayList arrayList = new ArrayList(this.mInstances.size());
|
||||
this.mInstances.forEachValue(new TObjectProcedure<Instance>() { // from class: com.squareup.haha.perflib.Heap.1
|
||||
@Override // gnu.trove.TObjectProcedure
|
||||
public boolean execute(Instance instance) {
|
||||
arrayList.add(instance);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public int getInstancesCount() {
|
||||
return this.mInstances.size();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.mName;
|
||||
}
|
||||
|
||||
public final StackFrame getStackFrame(long j) {
|
||||
return this.mFrames.get(j);
|
||||
}
|
||||
|
||||
public final StackTrace getStackTrace(int i) {
|
||||
return this.mTraces.get(i);
|
||||
}
|
||||
|
||||
public final StackTrace getStackTraceAtDepth(int i, int i2) {
|
||||
StackTrace stackTrace = this.mTraces.get(i);
|
||||
return stackTrace != null ? stackTrace.fromDepth(i2) : stackTrace;
|
||||
}
|
||||
|
||||
public final ThreadObj getThread(int i) {
|
||||
return this.mThreads.get(i);
|
||||
}
|
||||
|
||||
public final ClassObj getClass(String str) {
|
||||
Collection<ClassObj> collection = this.mClassesByName.get(str);
|
||||
if (collection.size() == 1) {
|
||||
return collection.iterator().next();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<ClassObj> getClasses() {
|
||||
return this.mClassesByName.values();
|
||||
}
|
||||
}
|
402
sources/com/squareup/haha/perflib/HprofParser.java
Normal file
402
sources/com/squareup/haha/perflib/HprofParser.java
Normal file
@@ -0,0 +1,402 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
import com.squareup.haha.perflib.io.HprofBuffer;
|
||||
import gnu.trove.TLongObjectHashMap;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class HprofParser {
|
||||
private static final int ALLOC_SITES = 6;
|
||||
private static final int CONTROL_SETTINGS = 14;
|
||||
private static final int CPU_SAMPLES = 13;
|
||||
private static final int END_THREAD = 11;
|
||||
private static final int HEAP_DUMP = 12;
|
||||
private static final int HEAP_DUMP_END = 44;
|
||||
private static final int HEAP_DUMP_SEGMENT = 28;
|
||||
private static final int HEAP_SUMMARY = 7;
|
||||
private static final int LOAD_CLASS = 2;
|
||||
private static final int ROOT_CLASS_DUMP = 32;
|
||||
private static final int ROOT_DEBUGGER = 139;
|
||||
private static final int ROOT_FINALIZING = 138;
|
||||
private static final int ROOT_HEAP_DUMP_INFO = 254;
|
||||
private static final int ROOT_INSTANCE_DUMP = 33;
|
||||
private static final int ROOT_INTERNED_STRING = 137;
|
||||
private static final int ROOT_JAVA_FRAME = 3;
|
||||
private static final int ROOT_JNI_GLOBAL = 1;
|
||||
private static final int ROOT_JNI_LOCAL = 2;
|
||||
private static final int ROOT_JNI_MONITOR = 142;
|
||||
private static final int ROOT_MONITOR_USED = 7;
|
||||
private static final int ROOT_NATIVE_STACK = 4;
|
||||
private static final int ROOT_OBJECT_ARRAY_DUMP = 34;
|
||||
private static final int ROOT_PRIMITIVE_ARRAY_DUMP = 35;
|
||||
private static final int ROOT_PRIMITIVE_ARRAY_NODATA = 195;
|
||||
private static final int ROOT_REFERENCE_CLEANUP = 140;
|
||||
private static final int ROOT_STICKY_CLASS = 5;
|
||||
private static final int ROOT_THREAD_BLOCK = 6;
|
||||
private static final int ROOT_THREAD_OBJECT = 8;
|
||||
private static final int ROOT_UNKNOWN = 255;
|
||||
private static final int ROOT_UNREACHABLE = 144;
|
||||
private static final int ROOT_VM_INTERNAL = 141;
|
||||
private static final int STACK_FRAME = 4;
|
||||
private static final int STACK_TRACE = 5;
|
||||
private static final int START_THREAD = 10;
|
||||
private static final int STRING_IN_UTF8 = 1;
|
||||
private static final int UNLOAD_CLASS = 3;
|
||||
int mIdSize;
|
||||
private final HprofBuffer mInput;
|
||||
Snapshot mSnapshot;
|
||||
TLongObjectHashMap<String> mStrings = new TLongObjectHashMap<>();
|
||||
TLongObjectHashMap<String> mClassNames = new TLongObjectHashMap<>();
|
||||
|
||||
public HprofParser(HprofBuffer hprofBuffer) {
|
||||
this.mInput = hprofBuffer;
|
||||
}
|
||||
|
||||
private int loadBasicObj(RootType rootType) throws IOException {
|
||||
this.mSnapshot.addRoot(new RootObj(rootType, readId()));
|
||||
return this.mIdSize;
|
||||
}
|
||||
|
||||
private void loadClass() throws IOException {
|
||||
this.mInput.readInt();
|
||||
long readId = readId();
|
||||
this.mInput.readInt();
|
||||
this.mClassNames.put(readId, this.mStrings.get(readId()));
|
||||
}
|
||||
|
||||
private int loadClassDump() throws IOException {
|
||||
long readId = readId();
|
||||
StackTrace stackTrace = this.mSnapshot.getStackTrace(this.mInput.readInt());
|
||||
long readId2 = readId();
|
||||
long readId3 = readId();
|
||||
readId();
|
||||
readId();
|
||||
readId();
|
||||
readId();
|
||||
int readInt = this.mInput.readInt();
|
||||
int i = (this.mIdSize * 7) + 4 + 4;
|
||||
int readUnsignedShort = readUnsignedShort();
|
||||
int i2 = i + 2;
|
||||
for (int i3 = 0; i3 < readUnsignedShort; i3++) {
|
||||
readUnsignedShort();
|
||||
i2 += skipValue() + 2;
|
||||
}
|
||||
ClassObj classObj = new ClassObj(readId, stackTrace, this.mClassNames.get(readId), this.mInput.position());
|
||||
classObj.setSuperClassId(readId2);
|
||||
classObj.setClassLoaderId(readId3);
|
||||
int readUnsignedShort2 = readUnsignedShort();
|
||||
int i4 = i2 + 2;
|
||||
Field[] fieldArr = new Field[readUnsignedShort2];
|
||||
for (int i5 = 0; i5 < readUnsignedShort2; i5++) {
|
||||
String str = this.mStrings.get(readId());
|
||||
Type type = Type.getType(this.mInput.readByte());
|
||||
fieldArr[i5] = new Field(type, str);
|
||||
skipFully(this.mSnapshot.getTypeSize(type));
|
||||
i4 += this.mIdSize + 1 + this.mSnapshot.getTypeSize(type);
|
||||
}
|
||||
classObj.setStaticFields(fieldArr);
|
||||
int readUnsignedShort3 = readUnsignedShort();
|
||||
int i6 = i4 + 2;
|
||||
Field[] fieldArr2 = new Field[readUnsignedShort3];
|
||||
for (int i7 = 0; i7 < readUnsignedShort3; i7++) {
|
||||
fieldArr2[i7] = new Field(Type.getType(readUnsignedByte()), this.mStrings.get(readId()));
|
||||
i6 += this.mIdSize + 1;
|
||||
}
|
||||
classObj.setFields(fieldArr2);
|
||||
classObj.setInstanceSize(readInt);
|
||||
this.mSnapshot.addClass(readId, classObj);
|
||||
return i6;
|
||||
}
|
||||
|
||||
private void loadHeapDump(long j) throws IOException {
|
||||
int loadBasicObj;
|
||||
while (j > 0) {
|
||||
int readUnsignedByte = readUnsignedByte();
|
||||
long j2 = j - 1;
|
||||
if (readUnsignedByte == ROOT_UNREACHABLE) {
|
||||
loadBasicObj = loadBasicObj(RootType.UNREACHABLE);
|
||||
} else {
|
||||
if (readUnsignedByte == ROOT_PRIMITIVE_ARRAY_NODATA) {
|
||||
System.err.println("+--- PRIMITIVE ARRAY NODATA DUMP");
|
||||
loadPrimitiveArrayDump();
|
||||
throw new IllegalArgumentException("Don't know how to load a nodata array");
|
||||
}
|
||||
if (readUnsignedByte == ROOT_HEAP_DUMP_INFO) {
|
||||
this.mSnapshot.setHeapTo(this.mInput.readInt(), this.mStrings.get(readId()));
|
||||
loadBasicObj = this.mIdSize + 4;
|
||||
} else if (readUnsignedByte != ROOT_UNKNOWN) {
|
||||
switch (readUnsignedByte) {
|
||||
case 1:
|
||||
j2 -= loadBasicObj(RootType.NATIVE_STATIC);
|
||||
readId();
|
||||
loadBasicObj = this.mIdSize;
|
||||
break;
|
||||
case 2:
|
||||
loadBasicObj = loadJniLocal();
|
||||
break;
|
||||
case 3:
|
||||
loadBasicObj = loadJavaFrame();
|
||||
break;
|
||||
case 4:
|
||||
loadBasicObj = loadNativeStack();
|
||||
break;
|
||||
case 5:
|
||||
loadBasicObj = loadBasicObj(RootType.SYSTEM_CLASS);
|
||||
break;
|
||||
case 6:
|
||||
loadBasicObj = loadThreadBlock();
|
||||
break;
|
||||
case 7:
|
||||
loadBasicObj = loadBasicObj(RootType.BUSY_MONITOR);
|
||||
break;
|
||||
case 8:
|
||||
loadBasicObj = loadThreadObject();
|
||||
break;
|
||||
default:
|
||||
switch (readUnsignedByte) {
|
||||
case 32:
|
||||
loadBasicObj = loadClassDump();
|
||||
break;
|
||||
case 33:
|
||||
loadBasicObj = loadInstanceDump();
|
||||
break;
|
||||
case 34:
|
||||
loadBasicObj = loadObjectArrayDump();
|
||||
break;
|
||||
case 35:
|
||||
loadBasicObj = loadPrimitiveArrayDump();
|
||||
break;
|
||||
default:
|
||||
switch (readUnsignedByte) {
|
||||
case ROOT_INTERNED_STRING /* 137 */:
|
||||
loadBasicObj = loadBasicObj(RootType.INTERNED_STRING);
|
||||
break;
|
||||
case ROOT_FINALIZING /* 138 */:
|
||||
loadBasicObj = loadBasicObj(RootType.FINALIZING);
|
||||
break;
|
||||
case ROOT_DEBUGGER /* 139 */:
|
||||
loadBasicObj = loadBasicObj(RootType.DEBUGGER);
|
||||
break;
|
||||
case 140:
|
||||
loadBasicObj = loadBasicObj(RootType.REFERENCE_CLEANUP);
|
||||
break;
|
||||
case ROOT_VM_INTERNAL /* 141 */:
|
||||
loadBasicObj = loadBasicObj(RootType.VM_INTERNAL);
|
||||
break;
|
||||
case ROOT_JNI_MONITOR /* 142 */:
|
||||
loadBasicObj = loadJniMonitor();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("loadHeapDump loop with unknown tag " + readUnsignedByte + " with " + this.mInput.remaining() + " bytes possibly remaining");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
loadBasicObj = loadBasicObj(RootType.UNKNOWN);
|
||||
}
|
||||
}
|
||||
j = j2 - loadBasicObj;
|
||||
}
|
||||
}
|
||||
|
||||
private int loadInstanceDump() throws IOException {
|
||||
long readId = readId();
|
||||
StackTrace stackTrace = this.mSnapshot.getStackTrace(this.mInput.readInt());
|
||||
long readId2 = readId();
|
||||
int readInt = this.mInput.readInt();
|
||||
ClassInstance classInstance = new ClassInstance(readId, stackTrace, this.mInput.position());
|
||||
classInstance.setClassId(readId2);
|
||||
this.mSnapshot.addInstance(readId, classInstance);
|
||||
skipFully(readInt);
|
||||
int i = this.mIdSize;
|
||||
return i + 4 + i + 4 + readInt;
|
||||
}
|
||||
|
||||
private int loadJavaFrame() throws IOException {
|
||||
long readId = readId();
|
||||
int readInt = this.mInput.readInt();
|
||||
this.mSnapshot.addRoot(new RootObj(RootType.JAVA_LOCAL, readId, readInt, this.mSnapshot.getStackTraceAtDepth(this.mSnapshot.getThread(readInt).mStackTrace, this.mInput.readInt())));
|
||||
return this.mIdSize + 4 + 4;
|
||||
}
|
||||
|
||||
private int loadJniLocal() throws IOException {
|
||||
long readId = readId();
|
||||
int readInt = this.mInput.readInt();
|
||||
this.mSnapshot.addRoot(new RootObj(RootType.NATIVE_LOCAL, readId, readInt, this.mSnapshot.getStackTraceAtDepth(this.mSnapshot.getThread(readInt).mStackTrace, this.mInput.readInt())));
|
||||
return this.mIdSize + 4 + 4;
|
||||
}
|
||||
|
||||
private int loadJniMonitor() throws IOException {
|
||||
long readId = readId();
|
||||
int readInt = this.mInput.readInt();
|
||||
this.mSnapshot.addRoot(new RootObj(RootType.NATIVE_MONITOR, readId, readInt, this.mSnapshot.getStackTraceAtDepth(this.mSnapshot.getThread(readInt).mStackTrace, this.mInput.readInt())));
|
||||
return this.mIdSize + 4 + 4;
|
||||
}
|
||||
|
||||
private int loadNativeStack() throws IOException {
|
||||
long readId = readId();
|
||||
int readInt = this.mInput.readInt();
|
||||
this.mSnapshot.addRoot(new RootObj(RootType.NATIVE_STACK, readId, readInt, this.mSnapshot.getStackTrace(this.mSnapshot.getThread(readInt).mStackTrace)));
|
||||
return this.mIdSize + 4;
|
||||
}
|
||||
|
||||
private int loadObjectArrayDump() throws IOException {
|
||||
long readId = readId();
|
||||
StackTrace stackTrace = this.mSnapshot.getStackTrace(this.mInput.readInt());
|
||||
int readInt = this.mInput.readInt();
|
||||
long readId2 = readId();
|
||||
ArrayInstance arrayInstance = new ArrayInstance(readId, stackTrace, Type.OBJECT, readInt, this.mInput.position());
|
||||
arrayInstance.setClassId(readId2);
|
||||
this.mSnapshot.addInstance(readId, arrayInstance);
|
||||
int i = readInt * this.mIdSize;
|
||||
skipFully(i);
|
||||
int i2 = this.mIdSize;
|
||||
return i2 + 4 + 4 + i2 + i;
|
||||
}
|
||||
|
||||
private int loadPrimitiveArrayDump() throws IOException {
|
||||
long readId = readId();
|
||||
StackTrace stackTrace = this.mSnapshot.getStackTrace(this.mInput.readInt());
|
||||
int readInt = this.mInput.readInt();
|
||||
Type type = Type.getType(readUnsignedByte());
|
||||
int typeSize = this.mSnapshot.getTypeSize(type);
|
||||
this.mSnapshot.addInstance(readId, new ArrayInstance(readId, stackTrace, type, readInt, this.mInput.position()));
|
||||
int i = readInt * typeSize;
|
||||
skipFully(i);
|
||||
return this.mIdSize + 4 + 4 + 1 + i;
|
||||
}
|
||||
|
||||
private void loadStackFrame() throws IOException {
|
||||
this.mSnapshot.addStackFrame(new StackFrame(readId(), this.mStrings.get(readId()), this.mStrings.get(readId()), this.mStrings.get(readId()), this.mInput.readInt(), this.mInput.readInt()));
|
||||
}
|
||||
|
||||
private void loadStackTrace() throws IOException {
|
||||
int readInt = this.mInput.readInt();
|
||||
int readInt2 = this.mInput.readInt();
|
||||
int readInt3 = this.mInput.readInt();
|
||||
StackFrame[] stackFrameArr = new StackFrame[readInt3];
|
||||
for (int i = 0; i < readInt3; i++) {
|
||||
stackFrameArr[i] = this.mSnapshot.getStackFrame(readId());
|
||||
}
|
||||
this.mSnapshot.addStackTrace(new StackTrace(readInt, readInt2, stackFrameArr));
|
||||
}
|
||||
|
||||
private void loadString(int i) throws IOException {
|
||||
this.mStrings.put(readId(), readUTF8(i));
|
||||
}
|
||||
|
||||
private int loadThreadBlock() throws IOException {
|
||||
long readId = readId();
|
||||
int readInt = this.mInput.readInt();
|
||||
this.mSnapshot.addRoot(new RootObj(RootType.THREAD_BLOCK, readId, readInt, this.mSnapshot.getStackTrace(this.mSnapshot.getThread(readInt).mStackTrace)));
|
||||
return this.mIdSize + 4;
|
||||
}
|
||||
|
||||
private int loadThreadObject() throws IOException {
|
||||
long readId = readId();
|
||||
int readInt = this.mInput.readInt();
|
||||
this.mSnapshot.addThread(new ThreadObj(readId, this.mInput.readInt()), readInt);
|
||||
return this.mIdSize + 4 + 4;
|
||||
}
|
||||
|
||||
private long readId() throws IOException {
|
||||
int i = this.mIdSize;
|
||||
if (i == 1) {
|
||||
return this.mInput.readByte();
|
||||
}
|
||||
if (i == 2) {
|
||||
return this.mInput.readShort();
|
||||
}
|
||||
if (i == 4) {
|
||||
return this.mInput.readInt();
|
||||
}
|
||||
if (i == 8) {
|
||||
return this.mInput.readLong();
|
||||
}
|
||||
throw new IllegalArgumentException("ID Length must be 1, 2, 4, or 8");
|
||||
}
|
||||
|
||||
private String readNullTerminatedString() throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (true) {
|
||||
byte readByte = this.mInput.readByte();
|
||||
if (readByte == 0) {
|
||||
return sb.toString();
|
||||
}
|
||||
sb.append((char) readByte);
|
||||
}
|
||||
}
|
||||
|
||||
private String readUTF8(int i) throws IOException {
|
||||
byte[] bArr = new byte[i];
|
||||
this.mInput.read(bArr);
|
||||
return new String(bArr, "utf-8");
|
||||
}
|
||||
|
||||
private int readUnsignedByte() throws IOException {
|
||||
return this.mInput.readByte() & 255;
|
||||
}
|
||||
|
||||
private long readUnsignedInt() throws IOException {
|
||||
return this.mInput.readInt() & 4294967295L;
|
||||
}
|
||||
|
||||
private int readUnsignedShort() throws IOException {
|
||||
return this.mInput.readShort() & 65535;
|
||||
}
|
||||
|
||||
private void skipFully(long j) throws IOException {
|
||||
HprofBuffer hprofBuffer = this.mInput;
|
||||
hprofBuffer.setPosition(hprofBuffer.position() + j);
|
||||
}
|
||||
|
||||
private int skipValue() throws IOException {
|
||||
int typeSize = this.mSnapshot.getTypeSize(Type.getType(readUnsignedByte()));
|
||||
skipFully(typeSize);
|
||||
return typeSize + 1;
|
||||
}
|
||||
|
||||
public final Snapshot parse() {
|
||||
Snapshot snapshot = new Snapshot(this.mInput);
|
||||
this.mSnapshot = snapshot;
|
||||
try {
|
||||
try {
|
||||
readNullTerminatedString();
|
||||
this.mIdSize = this.mInput.readInt();
|
||||
this.mSnapshot.setIdSize(this.mIdSize);
|
||||
this.mInput.readLong();
|
||||
while (this.mInput.hasRemaining()) {
|
||||
int readUnsignedByte = readUnsignedByte();
|
||||
this.mInput.readInt();
|
||||
long readUnsignedInt = readUnsignedInt();
|
||||
if (readUnsignedByte == 1) {
|
||||
loadString(((int) readUnsignedInt) - this.mIdSize);
|
||||
} else if (readUnsignedByte == 2) {
|
||||
loadClass();
|
||||
} else if (readUnsignedByte == 4) {
|
||||
loadStackFrame();
|
||||
} else if (readUnsignedByte == 5) {
|
||||
loadStackTrace();
|
||||
} else if (readUnsignedByte == 12) {
|
||||
loadHeapDump(readUnsignedInt);
|
||||
this.mSnapshot.setToDefaultHeap();
|
||||
} else if (readUnsignedByte != 28) {
|
||||
skipFully(readUnsignedInt);
|
||||
} else {
|
||||
loadHeapDump(readUnsignedInt);
|
||||
this.mSnapshot.setToDefaultHeap();
|
||||
}
|
||||
}
|
||||
} catch (EOFException unused) {
|
||||
}
|
||||
this.mSnapshot.resolveClasses();
|
||||
this.mSnapshot.resolveReferences();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.mClassNames.clear();
|
||||
this.mStrings.clear();
|
||||
return snapshot;
|
||||
}
|
||||
}
|
267
sources/com/squareup/haha/perflib/Instance.java
Normal file
267
sources/com/squareup/haha/perflib/Instance.java
Normal file
@@ -0,0 +1,267 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
import com.squareup.haha.guava.collect.ImmutableList;
|
||||
import com.squareup.haha.perflib.io.HprofBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public abstract class Instance {
|
||||
static final /* synthetic */ boolean $assertionsDisabled = false;
|
||||
long mClassId;
|
||||
Heap mHeap;
|
||||
protected final long mId;
|
||||
private Instance mImmediateDominator;
|
||||
private long[] mRetainedSizes;
|
||||
int mSize;
|
||||
protected final StackTrace mStack;
|
||||
int mTopologicalOrder;
|
||||
int mDistanceToGcRoot = Integer.MAX_VALUE;
|
||||
boolean mReferencesAdded = false;
|
||||
Instance mNextInstanceToGcRoot = null;
|
||||
private final ArrayList<Instance> mHardReferences = new ArrayList<>();
|
||||
private ArrayList<Instance> mSoftReferences = null;
|
||||
|
||||
/* renamed from: com.squareup.haha.perflib.Instance$1, reason: invalid class name */
|
||||
static /* synthetic */ class AnonymousClass1 {
|
||||
static final /* synthetic */ int[] $SwitchMap$com$android$tools$perflib$heap$Type = new int[Type.values().length];
|
||||
|
||||
static {
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.OBJECT.ordinal()] = 1;
|
||||
} catch (NoSuchFieldError unused) {
|
||||
}
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.BOOLEAN.ordinal()] = 2;
|
||||
} catch (NoSuchFieldError unused2) {
|
||||
}
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.CHAR.ordinal()] = 3;
|
||||
} catch (NoSuchFieldError unused3) {
|
||||
}
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.FLOAT.ordinal()] = 4;
|
||||
} catch (NoSuchFieldError unused4) {
|
||||
}
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.DOUBLE.ordinal()] = 5;
|
||||
} catch (NoSuchFieldError unused5) {
|
||||
}
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.BYTE.ordinal()] = 6;
|
||||
} catch (NoSuchFieldError unused6) {
|
||||
}
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.SHORT.ordinal()] = 7;
|
||||
} catch (NoSuchFieldError unused7) {
|
||||
}
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.INT.ordinal()] = 8;
|
||||
} catch (NoSuchFieldError unused8) {
|
||||
}
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.LONG.ordinal()] = 9;
|
||||
} catch (NoSuchFieldError unused9) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CompositeSizeVisitor extends NonRecursiveVisitor {
|
||||
int mSize = 0;
|
||||
|
||||
@Override // com.squareup.haha.perflib.NonRecursiveVisitor
|
||||
protected void defaultAction(Instance instance) {
|
||||
this.mSize += instance.getSize();
|
||||
}
|
||||
|
||||
public int getCompositeSize() {
|
||||
return this.mSize;
|
||||
}
|
||||
}
|
||||
|
||||
Instance(long j, StackTrace stackTrace) {
|
||||
this.mId = j;
|
||||
this.mStack = stackTrace;
|
||||
}
|
||||
|
||||
public abstract void accept(Visitor visitor);
|
||||
|
||||
public void addReference(Field field, Instance instance) {
|
||||
if (!instance.getIsSoftReference() || field == null || !field.getName().equals("referent")) {
|
||||
this.mHardReferences.add(instance);
|
||||
return;
|
||||
}
|
||||
if (this.mSoftReferences == null) {
|
||||
this.mSoftReferences = new ArrayList<>();
|
||||
}
|
||||
this.mSoftReferences.add(instance);
|
||||
}
|
||||
|
||||
public void addRetainedSize(int i, long j) {
|
||||
long[] jArr = this.mRetainedSizes;
|
||||
jArr[i] = jArr[i] + j;
|
||||
}
|
||||
|
||||
protected HprofBuffer getBuffer() {
|
||||
return this.mHeap.mSnapshot.mBuffer;
|
||||
}
|
||||
|
||||
public ClassObj getClassObj() {
|
||||
return this.mHeap.mSnapshot.findClass(this.mClassId);
|
||||
}
|
||||
|
||||
public final int getCompositeSize() {
|
||||
CompositeSizeVisitor compositeSizeVisitor = new CompositeSizeVisitor();
|
||||
compositeSizeVisitor.doVisit(ImmutableList.of(this));
|
||||
return compositeSizeVisitor.getCompositeSize();
|
||||
}
|
||||
|
||||
public int getDistanceToGcRoot() {
|
||||
return this.mDistanceToGcRoot;
|
||||
}
|
||||
|
||||
public ArrayList<Instance> getHardReferences() {
|
||||
return this.mHardReferences;
|
||||
}
|
||||
|
||||
public Heap getHeap() {
|
||||
return this.mHeap;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return this.mId;
|
||||
}
|
||||
|
||||
public Instance getImmediateDominator() {
|
||||
return this.mImmediateDominator;
|
||||
}
|
||||
|
||||
public boolean getIsSoftReference() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Instance getNextInstanceToGcRoot() {
|
||||
return this.mNextInstanceToGcRoot;
|
||||
}
|
||||
|
||||
public long getRetainedSize(int i) {
|
||||
return this.mRetainedSizes[i];
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return this.mSize;
|
||||
}
|
||||
|
||||
public ArrayList<Instance> getSoftReferences() {
|
||||
return this.mSoftReferences;
|
||||
}
|
||||
|
||||
public int getTopologicalOrder() {
|
||||
return this.mTopologicalOrder;
|
||||
}
|
||||
|
||||
public long getTotalRetainedSize() {
|
||||
long[] jArr = this.mRetainedSizes;
|
||||
long j = 0;
|
||||
if (jArr == null) {
|
||||
return 0L;
|
||||
}
|
||||
for (long j2 : jArr) {
|
||||
j += j2;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
public long getUniqueId() {
|
||||
return getId() & this.mHeap.mSnapshot.getIdSizeMask();
|
||||
}
|
||||
|
||||
protected long readId() {
|
||||
int typeSize = this.mHeap.mSnapshot.getTypeSize(Type.OBJECT);
|
||||
if (typeSize == 1) {
|
||||
return getBuffer().readByte();
|
||||
}
|
||||
if (typeSize == 2) {
|
||||
return getBuffer().readShort();
|
||||
}
|
||||
if (typeSize == 4) {
|
||||
return getBuffer().readInt();
|
||||
}
|
||||
if (typeSize != 8) {
|
||||
return 0L;
|
||||
}
|
||||
return getBuffer().readLong();
|
||||
}
|
||||
|
||||
protected int readUnsignedByte() {
|
||||
return getBuffer().readByte() & 255;
|
||||
}
|
||||
|
||||
protected int readUnsignedShort() {
|
||||
return getBuffer().readShort() & 65535;
|
||||
}
|
||||
|
||||
protected Object readValue(Type type) {
|
||||
switch (AnonymousClass1.$SwitchMap$com$android$tools$perflib$heap$Type[type.ordinal()]) {
|
||||
case 1:
|
||||
return this.mHeap.mSnapshot.findInstance(readId());
|
||||
case 2:
|
||||
return Boolean.valueOf(getBuffer().readByte() != 0);
|
||||
case 3:
|
||||
return Character.valueOf(getBuffer().readChar());
|
||||
case 4:
|
||||
return Float.valueOf(getBuffer().readFloat());
|
||||
case 5:
|
||||
return Double.valueOf(getBuffer().readDouble());
|
||||
case 6:
|
||||
return Byte.valueOf(getBuffer().readByte());
|
||||
case 7:
|
||||
return Short.valueOf(getBuffer().readShort());
|
||||
case 8:
|
||||
return Integer.valueOf(getBuffer().readInt());
|
||||
case 9:
|
||||
return Long.valueOf(getBuffer().readLong());
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void resetRetainedSize() {
|
||||
ArrayList<Heap> arrayList = this.mHeap.mSnapshot.mHeaps;
|
||||
long[] jArr = this.mRetainedSizes;
|
||||
if (jArr == null) {
|
||||
this.mRetainedSizes = new long[arrayList.size()];
|
||||
} else {
|
||||
Arrays.fill(jArr, 0L);
|
||||
}
|
||||
this.mRetainedSizes[arrayList.indexOf(this.mHeap)] = getSize();
|
||||
}
|
||||
|
||||
public void setClassId(long j) {
|
||||
this.mClassId = j;
|
||||
}
|
||||
|
||||
public void setDistanceToGcRoot(int i) {
|
||||
this.mDistanceToGcRoot = i;
|
||||
}
|
||||
|
||||
public void setHeap(Heap heap) {
|
||||
this.mHeap = heap;
|
||||
}
|
||||
|
||||
public void setImmediateDominator(Instance instance) {
|
||||
this.mImmediateDominator = instance;
|
||||
}
|
||||
|
||||
public void setNextInstanceToGcRoot(Instance instance) {
|
||||
this.mNextInstanceToGcRoot = instance;
|
||||
}
|
||||
|
||||
public void setSize(int i) {
|
||||
this.mSize = i;
|
||||
}
|
||||
|
||||
public void setTopologicalOrder(int i) {
|
||||
this.mTopologicalOrder = i;
|
||||
}
|
||||
}
|
54
sources/com/squareup/haha/perflib/Main.java
Normal file
54
sources/com/squareup/haha/perflib/Main.java
Normal file
@@ -0,0 +1,54 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
import com.squareup.haha.perflib.io.MemoryMappedFileBuffer;
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class Main {
|
||||
public static void main(String[] strArr) {
|
||||
try {
|
||||
long nanoTime = System.nanoTime();
|
||||
Snapshot parse = new HprofParser(new MemoryMappedFileBuffer(new File(strArr[0]))).parse();
|
||||
testClassesQuery(parse);
|
||||
testAllClassesQuery(parse);
|
||||
testFindInstancesOf(parse);
|
||||
testFindAllInstancesOf(parse);
|
||||
System.out.println("Memory stats: free=" + Runtime.getRuntime().freeMemory() + " / total=" + Runtime.getRuntime().totalMemory());
|
||||
System.out.println("Time: " + ((System.nanoTime() - nanoTime) / 1000000) + "ms");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void testAllClassesQuery(Snapshot snapshot) {
|
||||
Map<String, Set<ClassObj>> allClasses = Queries.allClasses(snapshot);
|
||||
for (String str : allClasses.keySet()) {
|
||||
System.out.println("------------------- " + str);
|
||||
for (ClassObj classObj : allClasses.get(str)) {
|
||||
System.out.println(" " + classObj.mClassName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void testClassesQuery(Snapshot snapshot) {
|
||||
Map<String, Set<ClassObj>> classes = Queries.classes(snapshot, new String[]{"char[", "javax.", "org.xml.sax"});
|
||||
for (String str : classes.keySet()) {
|
||||
System.out.println("------------------- " + str);
|
||||
for (ClassObj classObj : classes.get(str)) {
|
||||
System.out.println(" " + classObj.mClassName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void testFindAllInstancesOf(Snapshot snapshot) {
|
||||
Instance[] allInstancesOf = Queries.allInstancesOf(snapshot, "android.graphics.drawable.Drawable");
|
||||
System.out.println("There are " + allInstancesOf.length + " instances of Drawables and its subclasses.");
|
||||
}
|
||||
|
||||
private static void testFindInstancesOf(Snapshot snapshot) {
|
||||
Instance[] instancesOf = Queries.instancesOf(snapshot, "java.lang.String");
|
||||
System.out.println("There are " + instancesOf.length + " Strings.");
|
||||
}
|
||||
}
|
55
sources/com/squareup/haha/perflib/NonRecursiveVisitor.java
Normal file
55
sources/com/squareup/haha/perflib/NonRecursiveVisitor.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
import gnu.trove.TLongHashSet;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class NonRecursiveVisitor implements Visitor {
|
||||
public final Deque<Instance> mStack = new ArrayDeque();
|
||||
public final TLongHashSet mSeen = new TLongHashSet();
|
||||
|
||||
protected void defaultAction(Instance instance) {
|
||||
}
|
||||
|
||||
public void doVisit(Iterable<? extends Instance> iterable) {
|
||||
for (Instance instance : iterable) {
|
||||
if (instance instanceof RootObj) {
|
||||
instance.accept(this);
|
||||
} else {
|
||||
visitLater(null, instance);
|
||||
}
|
||||
}
|
||||
while (!this.mStack.isEmpty()) {
|
||||
Instance pop = this.mStack.pop();
|
||||
if (this.mSeen.add(pop.getId())) {
|
||||
pop.accept(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.Visitor
|
||||
public void visitArrayInstance(ArrayInstance arrayInstance) {
|
||||
defaultAction(arrayInstance);
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.Visitor
|
||||
public void visitClassInstance(ClassInstance classInstance) {
|
||||
defaultAction(classInstance);
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.Visitor
|
||||
public void visitClassObj(ClassObj classObj) {
|
||||
defaultAction(classObj);
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.Visitor
|
||||
public void visitLater(Instance instance, Instance instance2) {
|
||||
this.mStack.push(instance2);
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.Visitor
|
||||
public void visitRootObj(RootObj rootObj) {
|
||||
defaultAction(rootObj);
|
||||
}
|
||||
}
|
142
sources/com/squareup/haha/perflib/Queries.java
Normal file
142
sources/com/squareup/haha/perflib/Queries.java
Normal file
@@ -0,0 +1,142 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class Queries {
|
||||
private static final String DEFAULT_PACKAGE = "<default>";
|
||||
|
||||
public static Map<String, Set<ClassObj>> allClasses(Snapshot snapshot) {
|
||||
return classes(snapshot, null);
|
||||
}
|
||||
|
||||
public static Instance[] allInstancesOf(Snapshot snapshot, String str) {
|
||||
ClassObj findClass = snapshot.findClass(str);
|
||||
if (findClass == null) {
|
||||
throw new IllegalArgumentException("Class not found: " + str);
|
||||
}
|
||||
ArrayList arrayList = new ArrayList();
|
||||
arrayList.add(findClass);
|
||||
arrayList.addAll(traverseSubclasses(findClass));
|
||||
ArrayList arrayList2 = new ArrayList();
|
||||
Iterator it = arrayList.iterator();
|
||||
while (it.hasNext()) {
|
||||
arrayList2.addAll(((ClassObj) it.next()).getInstancesList());
|
||||
}
|
||||
Instance[] instanceArr = new Instance[arrayList2.size()];
|
||||
arrayList2.toArray(instanceArr);
|
||||
return instanceArr;
|
||||
}
|
||||
|
||||
public static Map<String, Set<ClassObj>> classes(Snapshot snapshot, String[] strArr) {
|
||||
TreeMap treeMap = new TreeMap();
|
||||
TreeSet<ClassObj> treeSet = new TreeSet();
|
||||
Iterator<Heap> it = snapshot.mHeaps.iterator();
|
||||
while (it.hasNext()) {
|
||||
treeSet.addAll(it.next().getClasses());
|
||||
}
|
||||
if (strArr != null) {
|
||||
int length = strArr.length;
|
||||
Iterator it2 = treeSet.iterator();
|
||||
while (it2.hasNext()) {
|
||||
String classObj = ((ClassObj) it2.next()).toString();
|
||||
int i = 0;
|
||||
while (true) {
|
||||
if (i >= length) {
|
||||
break;
|
||||
}
|
||||
if (classObj.startsWith(strArr[i])) {
|
||||
it2.remove();
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (ClassObj classObj2 : treeSet) {
|
||||
int lastIndexOf = classObj2.mClassName.lastIndexOf(46);
|
||||
String substring = lastIndexOf != -1 ? classObj2.mClassName.substring(0, lastIndexOf) : DEFAULT_PACKAGE;
|
||||
Set set = (Set) treeMap.get(substring);
|
||||
if (set == null) {
|
||||
set = new TreeSet();
|
||||
treeMap.put(substring, set);
|
||||
}
|
||||
set.add(classObj2);
|
||||
}
|
||||
return treeMap;
|
||||
}
|
||||
|
||||
public static Collection<ClassObj> commonClasses(Snapshot snapshot, Snapshot snapshot2) {
|
||||
ArrayList arrayList = new ArrayList();
|
||||
Iterator<Heap> it = snapshot.getHeaps().iterator();
|
||||
while (it.hasNext()) {
|
||||
for (ClassObj classObj : it.next().getClasses()) {
|
||||
if (snapshot2.findClass(classObj.getClassName()) != null) {
|
||||
arrayList.add(classObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public static ClassObj findClass(Snapshot snapshot, String str) {
|
||||
return snapshot.findClass(str);
|
||||
}
|
||||
|
||||
public static Instance findObject(Snapshot snapshot, String str) {
|
||||
return snapshot.findInstance(Long.parseLong(str, 16));
|
||||
}
|
||||
|
||||
public static Collection<RootObj> getRoots(Snapshot snapshot) {
|
||||
HashSet hashSet = new HashSet();
|
||||
Iterator<Heap> it = snapshot.mHeaps.iterator();
|
||||
while (it.hasNext()) {
|
||||
hashSet.addAll(it.next().mRoots);
|
||||
}
|
||||
return hashSet;
|
||||
}
|
||||
|
||||
public static Instance[] instancesOf(Snapshot snapshot, String str) {
|
||||
ClassObj findClass = snapshot.findClass(str);
|
||||
if (findClass != null) {
|
||||
List<Instance> instancesList = findClass.getInstancesList();
|
||||
return (Instance[]) instancesList.toArray(new Instance[instancesList.size()]);
|
||||
}
|
||||
throw new IllegalArgumentException("Class not found: " + str);
|
||||
}
|
||||
|
||||
public static final Instance[] newInstances(Snapshot snapshot, Snapshot snapshot2) {
|
||||
ArrayList arrayList = new ArrayList();
|
||||
Iterator<Heap> it = snapshot2.mHeaps.iterator();
|
||||
while (it.hasNext()) {
|
||||
Heap next = it.next();
|
||||
Heap heap = snapshot.getHeap(next.getName());
|
||||
if (heap != null) {
|
||||
for (Instance instance : next.getInstances()) {
|
||||
Instance heap2 = heap.getInstance(instance.mId);
|
||||
if (heap2 == null || instance.getClassObj() != heap2.getClassObj()) {
|
||||
arrayList.add(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (Instance[]) arrayList.toArray(new Instance[arrayList.size()]);
|
||||
}
|
||||
|
||||
private static ArrayList<ClassObj> traverseSubclasses(ClassObj classObj) {
|
||||
ArrayList<ClassObj> arrayList = new ArrayList<>();
|
||||
for (ClassObj classObj2 : classObj.mSubclasses) {
|
||||
arrayList.add(classObj2);
|
||||
arrayList.addAll(traverseSubclasses(classObj2));
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
}
|
50
sources/com/squareup/haha/perflib/RootObj.java
Normal file
50
sources/com/squareup/haha/perflib/RootObj.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class RootObj extends Instance {
|
||||
public static final String UNDEFINED_CLASS_NAME = "no class defined!!";
|
||||
int mIndex;
|
||||
int mThread;
|
||||
RootType mType;
|
||||
|
||||
public RootObj(RootType rootType) {
|
||||
this(rootType, 0L, 0, null);
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.Instance
|
||||
public final void accept(Visitor visitor) {
|
||||
visitor.visitRootObj(this);
|
||||
Instance referredInstance = getReferredInstance();
|
||||
if (referredInstance != null) {
|
||||
visitor.visitLater(null, referredInstance);
|
||||
}
|
||||
}
|
||||
|
||||
public final String getClassName(Snapshot snapshot) {
|
||||
ClassObj findClass = this.mType == RootType.SYSTEM_CLASS ? snapshot.findClass(this.mId) : snapshot.findInstance(this.mId).getClassObj();
|
||||
return findClass == null ? UNDEFINED_CLASS_NAME : findClass.mClassName;
|
||||
}
|
||||
|
||||
public Instance getReferredInstance() {
|
||||
return this.mType == RootType.SYSTEM_CLASS ? this.mHeap.mSnapshot.findClass(this.mId) : this.mHeap.mSnapshot.findInstance(this.mId);
|
||||
}
|
||||
|
||||
public RootType getRootType() {
|
||||
return this.mType;
|
||||
}
|
||||
|
||||
public final String toString() {
|
||||
return String.format("%s@0x%08x", this.mType.getName(), Long.valueOf(this.mId));
|
||||
}
|
||||
|
||||
public RootObj(RootType rootType, long j) {
|
||||
this(rootType, j, 0, null);
|
||||
}
|
||||
|
||||
public RootObj(RootType rootType, long j, int i, StackTrace stackTrace) {
|
||||
super(j, stackTrace);
|
||||
this.mType = RootType.UNKNOWN;
|
||||
this.mType = rootType;
|
||||
this.mThread = i;
|
||||
}
|
||||
}
|
40
sources/com/squareup/haha/perflib/RootType.java
Normal file
40
sources/com/squareup/haha/perflib/RootType.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
import com.ubt.jimu.diy.model.CategoryModel;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public enum RootType {
|
||||
UNREACHABLE(0, "unreachable object"),
|
||||
INVALID_TYPE(1, "invalid type"),
|
||||
INTERNED_STRING(2, "interned string"),
|
||||
UNKNOWN(3, CategoryModel.unknown),
|
||||
SYSTEM_CLASS(4, "system class"),
|
||||
VM_INTERNAL(5, "vm internal"),
|
||||
DEBUGGER(6, "debugger"),
|
||||
NATIVE_LOCAL(7, "native local"),
|
||||
NATIVE_STATIC(8, "native static"),
|
||||
THREAD_BLOCK(9, "thread block"),
|
||||
BUSY_MONITOR(10, "busy monitor"),
|
||||
NATIVE_MONITOR(11, "native monitor"),
|
||||
REFERENCE_CLEANUP(12, "reference cleanup"),
|
||||
FINALIZING(13, "finalizing"),
|
||||
JAVA_LOCAL(14, "java local"),
|
||||
NATIVE_STACK(15, "native stack"),
|
||||
JAVA_STATIC(16, "java static");
|
||||
|
||||
private final String mName;
|
||||
private final int mType;
|
||||
|
||||
RootType(int i, String str) {
|
||||
this.mType = i;
|
||||
this.mName = str;
|
||||
}
|
||||
|
||||
public final String getName() {
|
||||
return this.mName;
|
||||
}
|
||||
|
||||
public final int getType() {
|
||||
return this.mType;
|
||||
}
|
||||
}
|
278
sources/com/squareup/haha/perflib/Snapshot.java
Normal file
278
sources/com/squareup/haha/perflib/Snapshot.java
Normal file
@@ -0,0 +1,278 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
import com.squareup.haha.guava.collect.ImmutableList;
|
||||
import com.squareup.haha.guava.collect.UnmodifiableIterator;
|
||||
import com.squareup.haha.perflib.analysis.Dominators;
|
||||
import com.squareup.haha.perflib.analysis.ShortestDistanceVisitor;
|
||||
import com.squareup.haha.perflib.analysis.TopologicalSort;
|
||||
import com.squareup.haha.perflib.io.HprofBuffer;
|
||||
import gnu.trove.THashSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class Snapshot {
|
||||
static final /* synthetic */ boolean $assertionsDisabled = false;
|
||||
private static final int DEFAULT_HEAP_ID = 0;
|
||||
private static final String JAVA_LANG_CLASS = "java.lang.Class";
|
||||
public static final Instance SENTINEL_ROOT = new RootObj(RootType.UNKNOWN);
|
||||
final HprofBuffer mBuffer;
|
||||
Heap mCurrentHeap;
|
||||
private Dominators mDominators;
|
||||
private ImmutableList<Instance> mTopSort;
|
||||
private int[] mTypeSizes;
|
||||
ArrayList<Heap> mHeaps = new ArrayList<>();
|
||||
private THashSet<ClassObj> mReferenceClasses = new THashSet<>();
|
||||
private long mIdSizeMask = 4294967295L;
|
||||
|
||||
public Snapshot(HprofBuffer hprofBuffer) {
|
||||
this.mBuffer = hprofBuffer;
|
||||
setToDefaultHeap();
|
||||
}
|
||||
|
||||
public final void addClass(long j, ClassObj classObj) {
|
||||
this.mCurrentHeap.addClass(j, classObj);
|
||||
classObj.setHeap(this.mCurrentHeap);
|
||||
}
|
||||
|
||||
public final void addInstance(long j, Instance instance) {
|
||||
this.mCurrentHeap.addInstance(j, instance);
|
||||
instance.setHeap(this.mCurrentHeap);
|
||||
}
|
||||
|
||||
public final void addRoot(RootObj rootObj) {
|
||||
this.mCurrentHeap.addRoot(rootObj);
|
||||
rootObj.setHeap(this.mCurrentHeap);
|
||||
}
|
||||
|
||||
public final void addStackFrame(StackFrame stackFrame) {
|
||||
this.mCurrentHeap.addStackFrame(stackFrame);
|
||||
}
|
||||
|
||||
public final void addStackTrace(StackTrace stackTrace) {
|
||||
this.mCurrentHeap.addStackTrace(stackTrace);
|
||||
}
|
||||
|
||||
public final void addThread(ThreadObj threadObj, int i) {
|
||||
this.mCurrentHeap.addThread(threadObj, i);
|
||||
}
|
||||
|
||||
public void computeDominators() {
|
||||
if (this.mDominators == null) {
|
||||
this.mTopSort = TopologicalSort.compute(getGCRoots());
|
||||
this.mDominators = new Dominators(this, this.mTopSort);
|
||||
this.mDominators.computeRetainedSizes();
|
||||
new ShortestDistanceVisitor().doVisit(getGCRoots());
|
||||
}
|
||||
}
|
||||
|
||||
public final void dumpInstanceCounts() {
|
||||
Iterator<Heap> it = this.mHeaps.iterator();
|
||||
while (it.hasNext()) {
|
||||
Heap next = it.next();
|
||||
System.out.println("+------------------ instance counts for heap: " + next.getName());
|
||||
next.dumpInstanceCounts();
|
||||
}
|
||||
}
|
||||
|
||||
public final void dumpSizes() {
|
||||
Iterator<Heap> it = this.mHeaps.iterator();
|
||||
while (it.hasNext()) {
|
||||
Heap next = it.next();
|
||||
System.out.println("+------------------ sizes for heap: " + next.getName());
|
||||
next.dumpSizes();
|
||||
}
|
||||
}
|
||||
|
||||
public final void dumpSubclasses() {
|
||||
Iterator<Heap> it = this.mHeaps.iterator();
|
||||
while (it.hasNext()) {
|
||||
Heap next = it.next();
|
||||
System.out.println("+------------------ subclasses for heap: " + next.getName());
|
||||
next.dumpSubclasses();
|
||||
}
|
||||
}
|
||||
|
||||
public List<ClassObj> findAllDescendantClasses(String str) {
|
||||
Collection<ClassObj> findClasses = findClasses(str);
|
||||
ArrayList arrayList = new ArrayList();
|
||||
Iterator<ClassObj> it = findClasses.iterator();
|
||||
while (it.hasNext()) {
|
||||
arrayList.addAll(it.next().getDescendantClasses());
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public final ClassObj findClass(long j) {
|
||||
for (int i = 0; i < this.mHeaps.size(); i++) {
|
||||
ClassObj classObj = this.mHeaps.get(i).getClass(j);
|
||||
if (classObj != null) {
|
||||
return classObj;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final Collection<ClassObj> findClasses(String str) {
|
||||
ArrayList arrayList = new ArrayList();
|
||||
for (int i = 0; i < this.mHeaps.size(); i++) {
|
||||
arrayList.addAll(this.mHeaps.get(i).getClasses(str));
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public final Instance findInstance(long j) {
|
||||
for (int i = 0; i < this.mHeaps.size(); i++) {
|
||||
Instance heap = this.mHeaps.get(i).getInstance(j);
|
||||
if (heap != null) {
|
||||
return heap;
|
||||
}
|
||||
}
|
||||
return findClass(j);
|
||||
}
|
||||
|
||||
public Collection<RootObj> getGCRoots() {
|
||||
return this.mHeaps.get(0).mRoots;
|
||||
}
|
||||
|
||||
public Heap getHeap(int i) {
|
||||
for (int i2 = 0; i2 < this.mHeaps.size(); i2++) {
|
||||
if (this.mHeaps.get(i2).getId() == i) {
|
||||
return this.mHeaps.get(i2);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getHeapIndex(Heap heap) {
|
||||
return this.mHeaps.indexOf(heap);
|
||||
}
|
||||
|
||||
public Collection<Heap> getHeaps() {
|
||||
return this.mHeaps;
|
||||
}
|
||||
|
||||
public final long getIdSizeMask() {
|
||||
return this.mIdSizeMask;
|
||||
}
|
||||
|
||||
public List<Instance> getReachableInstances() {
|
||||
ArrayList arrayList = new ArrayList(this.mTopSort.size());
|
||||
UnmodifiableIterator<Instance> it = this.mTopSort.iterator();
|
||||
while (it.hasNext()) {
|
||||
Instance next = it.next();
|
||||
if (next.getImmediateDominator() != null) {
|
||||
arrayList.add(next);
|
||||
}
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public final StackFrame getStackFrame(long j) {
|
||||
return this.mCurrentHeap.getStackFrame(j);
|
||||
}
|
||||
|
||||
public final StackTrace getStackTrace(int i) {
|
||||
return this.mCurrentHeap.getStackTrace(i);
|
||||
}
|
||||
|
||||
public final StackTrace getStackTraceAtDepth(int i, int i2) {
|
||||
return this.mCurrentHeap.getStackTraceAtDepth(i, i2);
|
||||
}
|
||||
|
||||
public final ThreadObj getThread(int i) {
|
||||
return this.mCurrentHeap.getThread(i);
|
||||
}
|
||||
|
||||
public ImmutableList<Instance> getTopologicalOrdering() {
|
||||
return this.mTopSort;
|
||||
}
|
||||
|
||||
public final int getTypeSize(Type type) {
|
||||
return this.mTypeSizes[type.getTypeId()];
|
||||
}
|
||||
|
||||
public void resolveClasses() {
|
||||
ClassObj findClass = findClass(JAVA_LANG_CLASS);
|
||||
int instanceSize = findClass != null ? findClass.getInstanceSize() : 0;
|
||||
Iterator<Heap> it = this.mHeaps.iterator();
|
||||
while (it.hasNext()) {
|
||||
Heap next = it.next();
|
||||
for (ClassObj classObj : next.getClasses()) {
|
||||
ClassObj superClassObj = classObj.getSuperClassObj();
|
||||
if (superClassObj != null) {
|
||||
superClassObj.addSubclass(classObj);
|
||||
}
|
||||
int i = instanceSize;
|
||||
for (Field field : classObj.mStaticFields) {
|
||||
i += getTypeSize(field.getType());
|
||||
}
|
||||
classObj.setSize(i);
|
||||
}
|
||||
for (Instance instance : next.getInstances()) {
|
||||
ClassObj classObj2 = instance.getClassObj();
|
||||
if (classObj2 != null) {
|
||||
classObj2.addInstance(next.getId(), instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void resolveReferences() {
|
||||
for (ClassObj classObj : findAllDescendantClasses(ClassObj.getReferenceClassName())) {
|
||||
classObj.setIsSoftReference();
|
||||
this.mReferenceClasses.add(classObj);
|
||||
}
|
||||
}
|
||||
|
||||
public Heap setHeapTo(int i, String str) {
|
||||
Heap heap = getHeap(i);
|
||||
if (heap == null) {
|
||||
heap = new Heap(i, str);
|
||||
heap.mSnapshot = this;
|
||||
this.mHeaps.add(heap);
|
||||
}
|
||||
this.mCurrentHeap = heap;
|
||||
return this.mCurrentHeap;
|
||||
}
|
||||
|
||||
public final void setIdSize(int i) {
|
||||
int i2 = -1;
|
||||
for (int i3 = 0; i3 < Type.values().length; i3++) {
|
||||
i2 = Math.max(Type.values()[i3].getTypeId(), i2);
|
||||
}
|
||||
this.mTypeSizes = new int[i2 + 1];
|
||||
Arrays.fill(this.mTypeSizes, -1);
|
||||
for (int i4 = 0; i4 < Type.values().length; i4++) {
|
||||
this.mTypeSizes[Type.values()[i4].getTypeId()] = Type.values()[i4].getSize();
|
||||
}
|
||||
this.mTypeSizes[Type.OBJECT.getTypeId()] = i;
|
||||
this.mIdSizeMask = (-1) >>> ((8 - i) << 3);
|
||||
}
|
||||
|
||||
public Heap setToDefaultHeap() {
|
||||
return setHeapTo(0, "default");
|
||||
}
|
||||
|
||||
public final ClassObj findClass(String str) {
|
||||
for (int i = 0; i < this.mHeaps.size(); i++) {
|
||||
ClassObj classObj = this.mHeaps.get(i).getClass(str);
|
||||
if (classObj != null) {
|
||||
return classObj;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Heap getHeap(String str) {
|
||||
for (int i = 0; i < this.mHeaps.size(); i++) {
|
||||
if (str.equals(this.mHeaps.get(i).getName())) {
|
||||
return this.mHeaps.get(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
33
sources/com/squareup/haha/perflib/StackFrame.java
Normal file
33
sources/com/squareup/haha/perflib/StackFrame.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class StackFrame {
|
||||
public static final int COMPILED_METHOD = -2;
|
||||
public static final int NATIVE_METHOD = -3;
|
||||
public static final int NO_LINE_NUMBER = 0;
|
||||
public static final int UNKNOWN_LOCATION = -1;
|
||||
String mFilename;
|
||||
long mId;
|
||||
int mLineNumber;
|
||||
String mMethodName;
|
||||
int mSerialNumber;
|
||||
String mSignature;
|
||||
|
||||
public StackFrame(long j, String str, String str2, String str3, int i, int i2) {
|
||||
this.mId = j;
|
||||
this.mMethodName = str;
|
||||
this.mSignature = str2;
|
||||
this.mFilename = str3;
|
||||
this.mSerialNumber = i;
|
||||
this.mLineNumber = i2;
|
||||
}
|
||||
|
||||
private String lineNumberString() {
|
||||
int i = this.mLineNumber;
|
||||
return i != -3 ? i != -2 ? i != -1 ? i != 0 ? String.valueOf(i) : "No line number" : "Unknown line number" : "Compiled method" : "Native method";
|
||||
}
|
||||
|
||||
public final String toString() {
|
||||
return this.mMethodName + this.mSignature.replace('/', '.') + " - " + this.mFilename + ":" + lineNumberString();
|
||||
}
|
||||
}
|
38
sources/com/squareup/haha/perflib/StackTrace.java
Normal file
38
sources/com/squareup/haha/perflib/StackTrace.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class StackTrace {
|
||||
StackFrame[] mFrames;
|
||||
int mSerialNumber;
|
||||
int mThreadSerialNumber;
|
||||
StackTrace mParent = null;
|
||||
int mOffset = 0;
|
||||
|
||||
private StackTrace() {
|
||||
}
|
||||
|
||||
public final void dump() {
|
||||
int length = this.mFrames.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
System.out.println(this.mFrames[i].toString());
|
||||
}
|
||||
}
|
||||
|
||||
public final StackTrace fromDepth(int i) {
|
||||
StackTrace stackTrace = new StackTrace();
|
||||
StackTrace stackTrace2 = this.mParent;
|
||||
if (stackTrace2 != null) {
|
||||
stackTrace.mParent = stackTrace2;
|
||||
} else {
|
||||
stackTrace.mParent = this;
|
||||
}
|
||||
stackTrace.mOffset = i + this.mOffset;
|
||||
return stackTrace;
|
||||
}
|
||||
|
||||
public StackTrace(int i, int i2, StackFrame[] stackFrameArr) {
|
||||
this.mSerialNumber = i;
|
||||
this.mThreadSerialNumber = i2;
|
||||
this.mFrames = stackFrameArr;
|
||||
}
|
||||
}
|
12
sources/com/squareup/haha/perflib/ThreadObj.java
Normal file
12
sources/com/squareup/haha/perflib/ThreadObj.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class ThreadObj {
|
||||
long mId;
|
||||
int mStackTrace;
|
||||
|
||||
public ThreadObj(long j, int i) {
|
||||
this.mId = j;
|
||||
this.mStackTrace = i;
|
||||
}
|
||||
}
|
107
sources/com/squareup/haha/perflib/Type.java
Normal file
107
sources/com/squareup/haha/perflib/Type.java
Normal file
@@ -0,0 +1,107 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
import com.squareup.haha.guava.collect.Maps;
|
||||
import java.util.Map;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public enum Type {
|
||||
OBJECT(2, 0),
|
||||
BOOLEAN(4, 1),
|
||||
CHAR(5, 2),
|
||||
FLOAT(6, 4),
|
||||
DOUBLE(7, 8),
|
||||
BYTE(8, 1),
|
||||
SHORT(9, 2),
|
||||
INT(10, 4),
|
||||
LONG(11, 8);
|
||||
|
||||
private static Map<Integer, Type> sTypeMap = Maps.newHashMap();
|
||||
private int mId;
|
||||
private int mSize;
|
||||
|
||||
/* renamed from: com.squareup.haha.perflib.Type$1, reason: invalid class name */
|
||||
static /* synthetic */ class AnonymousClass1 {
|
||||
static final /* synthetic */ int[] $SwitchMap$com$android$tools$perflib$heap$Type = new int[Type.values().length];
|
||||
|
||||
static {
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.BOOLEAN.ordinal()] = 1;
|
||||
} catch (NoSuchFieldError unused) {
|
||||
}
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.CHAR.ordinal()] = 2;
|
||||
} catch (NoSuchFieldError unused2) {
|
||||
}
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.FLOAT.ordinal()] = 3;
|
||||
} catch (NoSuchFieldError unused3) {
|
||||
}
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.DOUBLE.ordinal()] = 4;
|
||||
} catch (NoSuchFieldError unused4) {
|
||||
}
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.BYTE.ordinal()] = 5;
|
||||
} catch (NoSuchFieldError unused5) {
|
||||
}
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.SHORT.ordinal()] = 6;
|
||||
} catch (NoSuchFieldError unused6) {
|
||||
}
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.INT.ordinal()] = 7;
|
||||
} catch (NoSuchFieldError unused7) {
|
||||
}
|
||||
try {
|
||||
$SwitchMap$com$android$tools$perflib$heap$Type[Type.LONG.ordinal()] = 8;
|
||||
} catch (NoSuchFieldError unused8) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
for (Type type : values()) {
|
||||
sTypeMap.put(Integer.valueOf(type.mId), type);
|
||||
}
|
||||
}
|
||||
|
||||
Type(int i, int i2) {
|
||||
this.mId = i;
|
||||
this.mSize = i2;
|
||||
}
|
||||
|
||||
public static String getClassNameOfPrimitiveArray(Type type) {
|
||||
switch (AnonymousClass1.$SwitchMap$com$android$tools$perflib$heap$Type[type.ordinal()]) {
|
||||
case 1:
|
||||
return "boolean[]";
|
||||
case 2:
|
||||
return "char[]";
|
||||
case 3:
|
||||
return "float[]";
|
||||
case 4:
|
||||
return "double[]";
|
||||
case 5:
|
||||
return "byte[]";
|
||||
case 6:
|
||||
return "short[]";
|
||||
case 7:
|
||||
return "int[]";
|
||||
case 8:
|
||||
return "long[]";
|
||||
default:
|
||||
throw new IllegalArgumentException("OBJECT type is not a primitive type");
|
||||
}
|
||||
}
|
||||
|
||||
public static Type getType(int i) {
|
||||
return sTypeMap.get(Integer.valueOf(i));
|
||||
}
|
||||
|
||||
public final int getSize() {
|
||||
return this.mSize;
|
||||
}
|
||||
|
||||
public final int getTypeId() {
|
||||
return this.mId;
|
||||
}
|
||||
}
|
22
sources/com/squareup/haha/perflib/Value.java
Normal file
22
sources/com/squareup/haha/perflib/Value.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class Value {
|
||||
private final Instance instance;
|
||||
private Object mValue;
|
||||
|
||||
public Value(Instance instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return this.mValue;
|
||||
}
|
||||
|
||||
public void setValue(Object obj) {
|
||||
this.mValue = obj;
|
||||
if (obj instanceof Instance) {
|
||||
((Instance) obj).addReference(null, this.instance);
|
||||
}
|
||||
}
|
||||
}
|
14
sources/com/squareup/haha/perflib/Visitor.java
Normal file
14
sources/com/squareup/haha/perflib/Visitor.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package com.squareup.haha.perflib;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public interface Visitor {
|
||||
void visitArrayInstance(ArrayInstance arrayInstance);
|
||||
|
||||
void visitClassInstance(ClassInstance classInstance);
|
||||
|
||||
void visitClassObj(ClassObj classObj);
|
||||
|
||||
void visitLater(Instance instance, Instance instance2);
|
||||
|
||||
void visitRootObj(RootObj rootObj);
|
||||
}
|
76
sources/com/squareup/haha/perflib/analysis/Dominators.java
Normal file
76
sources/com/squareup/haha/perflib/analysis/Dominators.java
Normal file
@@ -0,0 +1,76 @@
|
||||
package com.squareup.haha.perflib.analysis;
|
||||
|
||||
import com.squareup.haha.guava.collect.ImmutableList;
|
||||
import com.squareup.haha.guava.collect.Iterables;
|
||||
import com.squareup.haha.perflib.Heap;
|
||||
import com.squareup.haha.perflib.Instance;
|
||||
import com.squareup.haha.perflib.RootObj;
|
||||
import com.squareup.haha.perflib.Snapshot;
|
||||
import java.util.Iterator;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class Dominators {
|
||||
private final Snapshot mSnapshot;
|
||||
private final ImmutableList<Instance> mTopSort;
|
||||
|
||||
public Dominators(Snapshot snapshot, ImmutableList<Instance> immutableList) {
|
||||
this.mSnapshot = snapshot;
|
||||
this.mTopSort = immutableList;
|
||||
Iterator<RootObj> it = snapshot.getGCRoots().iterator();
|
||||
while (it.hasNext()) {
|
||||
Instance referredInstance = it.next().getReferredInstance();
|
||||
if (referredInstance != null) {
|
||||
referredInstance.setImmediateDominator(Snapshot.SENTINEL_ROOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void computeDominators() {
|
||||
boolean z;
|
||||
for (boolean z2 = true; z2; z2 = z) {
|
||||
z = false;
|
||||
for (int i = 0; i < this.mTopSort.size(); i++) {
|
||||
Instance instance = this.mTopSort.get(i);
|
||||
if (instance.getImmediateDominator() != Snapshot.SENTINEL_ROOT) {
|
||||
Instance instance2 = null;
|
||||
for (int i2 = 0; i2 < instance.getHardReferences().size(); i2++) {
|
||||
Instance instance3 = instance.getHardReferences().get(i2);
|
||||
if (instance3.getImmediateDominator() != null) {
|
||||
if (instance2 == null) {
|
||||
instance2 = instance3;
|
||||
} else {
|
||||
while (instance2 != instance3) {
|
||||
if (instance2.getTopologicalOrder() < instance3.getTopologicalOrder()) {
|
||||
instance3 = instance3.getImmediateDominator();
|
||||
} else {
|
||||
instance2 = instance2.getImmediateDominator();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (instance.getImmediateDominator() != instance2) {
|
||||
instance.setImmediateDominator(instance2);
|
||||
z = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void computeRetainedSizes() {
|
||||
for (Heap heap : this.mSnapshot.getHeaps()) {
|
||||
Iterator it = Iterables.concat(heap.getClasses(), heap.getInstances()).iterator();
|
||||
while (it.hasNext()) {
|
||||
((Instance) it.next()).resetRetainedSize();
|
||||
}
|
||||
}
|
||||
computeDominators();
|
||||
for (Instance instance : this.mSnapshot.getReachableInstances()) {
|
||||
int heapIndex = this.mSnapshot.getHeapIndex(instance.getHeap());
|
||||
for (Instance immediateDominator = instance.getImmediateDominator(); immediateDominator != Snapshot.SENTINEL_ROOT; immediateDominator = immediateDominator.getImmediateDominator()) {
|
||||
immediateDominator.addRetainedSize(heapIndex, instance.getSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
package com.squareup.haha.perflib.analysis;
|
||||
|
||||
import com.ijm.dataencryption.de.DataDecryptTool;
|
||||
import com.squareup.haha.perflib.Instance;
|
||||
import com.squareup.haha.perflib.NonRecursiveVisitor;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class ShortestDistanceVisitor extends NonRecursiveVisitor {
|
||||
private PriorityQueue<Instance> mPriorityQueue = new PriorityQueue<>(DataDecryptTool.DECRYPT_SP_FILE, new Comparator<Instance>() { // from class: com.squareup.haha.perflib.analysis.ShortestDistanceVisitor.1
|
||||
@Override // java.util.Comparator
|
||||
public int compare(Instance instance, Instance instance2) {
|
||||
return instance.getDistanceToGcRoot() - instance2.getDistanceToGcRoot();
|
||||
}
|
||||
});
|
||||
private Instance mPreviousInstance = null;
|
||||
private int mVisitDistance = 0;
|
||||
|
||||
@Override // com.squareup.haha.perflib.NonRecursiveVisitor
|
||||
public void doVisit(Iterable<? extends Instance> iterable) {
|
||||
Iterator<? extends Instance> it = iterable.iterator();
|
||||
while (it.hasNext()) {
|
||||
it.next().accept(this);
|
||||
}
|
||||
while (!this.mPriorityQueue.isEmpty()) {
|
||||
Instance poll = this.mPriorityQueue.poll();
|
||||
this.mVisitDistance = poll.getDistanceToGcRoot() + 1;
|
||||
this.mPreviousInstance = poll;
|
||||
poll.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.NonRecursiveVisitor, com.squareup.haha.perflib.Visitor
|
||||
public void visitLater(Instance instance, Instance instance2) {
|
||||
if (this.mVisitDistance < instance2.getDistanceToGcRoot()) {
|
||||
if (instance == null || instance2.getSoftReferences() == null || !instance2.getSoftReferences().contains(instance) || instance2.getIsSoftReference()) {
|
||||
instance2.setDistanceToGcRoot(this.mVisitDistance);
|
||||
instance2.setNextInstanceToGcRoot(this.mPreviousInstance);
|
||||
this.mPriorityQueue.add(instance2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
package com.squareup.haha.perflib.analysis;
|
||||
|
||||
import com.squareup.haha.guava.base.Joiner;
|
||||
import com.squareup.haha.guava.collect.ImmutableList;
|
||||
import com.squareup.haha.guava.collect.UnmodifiableIterator;
|
||||
import com.squareup.haha.perflib.Instance;
|
||||
import com.squareup.haha.perflib.NonRecursiveVisitor;
|
||||
import com.squareup.haha.perflib.RootObj;
|
||||
import com.squareup.haha.perflib.Snapshot;
|
||||
import gnu.trove.TLongHashSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class TopologicalSort {
|
||||
|
||||
static class TopologicalSortVisitor extends NonRecursiveVisitor {
|
||||
private final List<Instance> mPostorder;
|
||||
private final TLongHashSet mVisited;
|
||||
|
||||
private TopologicalSortVisitor() {
|
||||
this.mVisited = new TLongHashSet();
|
||||
this.mPostorder = new ArrayList();
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.NonRecursiveVisitor
|
||||
public void doVisit(Iterable<? extends Instance> iterable) {
|
||||
Iterator<? extends Instance> it = iterable.iterator();
|
||||
while (it.hasNext()) {
|
||||
it.next().accept(this);
|
||||
}
|
||||
while (!this.mStack.isEmpty()) {
|
||||
Instance peek = this.mStack.peek();
|
||||
if (this.mSeen.add(peek.getId())) {
|
||||
peek.accept(this);
|
||||
} else {
|
||||
this.mStack.pop();
|
||||
if (this.mVisited.add(peek.getId())) {
|
||||
this.mPostorder.add(peek);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImmutableList<Instance> getOrderedInstances() {
|
||||
return ImmutableList.copyOf((Collection) Joiner.reverse(this.mPostorder));
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.NonRecursiveVisitor, com.squareup.haha.perflib.Visitor
|
||||
public void visitLater(Instance instance, Instance instance2) {
|
||||
if (this.mSeen.contains(instance2.getId())) {
|
||||
return;
|
||||
}
|
||||
this.mStack.push(instance2);
|
||||
}
|
||||
}
|
||||
|
||||
public static ImmutableList<Instance> compute(Iterable<RootObj> iterable) {
|
||||
TopologicalSortVisitor topologicalSortVisitor = new TopologicalSortVisitor();
|
||||
topologicalSortVisitor.doVisit(iterable);
|
||||
ImmutableList<Instance> orderedInstances = topologicalSortVisitor.getOrderedInstances();
|
||||
int i = 0;
|
||||
Snapshot.SENTINEL_ROOT.setTopologicalOrder(0);
|
||||
UnmodifiableIterator<Instance> it = orderedInstances.iterator();
|
||||
while (it.hasNext()) {
|
||||
i++;
|
||||
it.next().setTopologicalOrder(i);
|
||||
}
|
||||
return orderedInstances;
|
||||
}
|
||||
}
|
34
sources/com/squareup/haha/perflib/io/HprofBuffer.java
Normal file
34
sources/com/squareup/haha/perflib/io/HprofBuffer.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package com.squareup.haha.perflib.io;
|
||||
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public interface HprofBuffer {
|
||||
public static final ByteOrder HPROF_BYTE_ORDER = ByteOrder.BIG_ENDIAN;
|
||||
|
||||
boolean hasRemaining();
|
||||
|
||||
long position();
|
||||
|
||||
void read(byte[] bArr);
|
||||
|
||||
byte readByte();
|
||||
|
||||
char readChar();
|
||||
|
||||
double readDouble();
|
||||
|
||||
float readFloat();
|
||||
|
||||
int readInt();
|
||||
|
||||
long readLong();
|
||||
|
||||
short readShort();
|
||||
|
||||
void readSubSequence(byte[] bArr, int i, int i2);
|
||||
|
||||
long remaining();
|
||||
|
||||
void setPosition(long j);
|
||||
}
|
171
sources/com/squareup/haha/perflib/io/MemoryMappedFileBuffer.java
Normal file
171
sources/com/squareup/haha/perflib/io/MemoryMappedFileBuffer.java
Normal file
@@ -0,0 +1,171 @@
|
||||
package com.squareup.haha.perflib.io;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class MemoryMappedFileBuffer implements HprofBuffer {
|
||||
static final /* synthetic */ boolean $assertionsDisabled = false;
|
||||
private static final int DEFAULT_PADDING = 1024;
|
||||
private static final int DEFAULT_SIZE = 1073741824;
|
||||
private final int mBufferSize;
|
||||
private final ByteBuffer[] mByteBuffers;
|
||||
private long mCurrentPosition;
|
||||
private final long mLength;
|
||||
private final int mPadding;
|
||||
|
||||
MemoryMappedFileBuffer(File file, int i, int i2) throws IOException {
|
||||
this.mBufferSize = i;
|
||||
this.mPadding = i2;
|
||||
this.mLength = file.length();
|
||||
int i3 = ((int) (this.mLength / this.mBufferSize)) + 1;
|
||||
this.mByteBuffers = new ByteBuffer[i3];
|
||||
FileInputStream fileInputStream = new FileInputStream(file);
|
||||
long j = 0;
|
||||
for (int i4 = 0; i4 < i3; i4++) {
|
||||
try {
|
||||
this.mByteBuffers[i4] = fileInputStream.getChannel().map(FileChannel.MapMode.READ_ONLY, j, Math.min(this.mLength - j, this.mBufferSize + this.mPadding));
|
||||
this.mByteBuffers[i4].order(HprofBuffer.HPROF_BYTE_ORDER);
|
||||
j += this.mBufferSize;
|
||||
} finally {
|
||||
fileInputStream.close();
|
||||
}
|
||||
}
|
||||
this.mCurrentPosition = 0L;
|
||||
}
|
||||
|
||||
private int getIndex() {
|
||||
return (int) (this.mCurrentPosition / this.mBufferSize);
|
||||
}
|
||||
|
||||
private int getOffset() {
|
||||
return (int) (this.mCurrentPosition % this.mBufferSize);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
for (int i = 0; i < this.mByteBuffers.length; i++) {
|
||||
try {
|
||||
this.mByteBuffers[i].cleaner().clean();
|
||||
} catch (Exception unused) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.io.HprofBuffer
|
||||
public boolean hasRemaining() {
|
||||
return this.mCurrentPosition < this.mLength;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.io.HprofBuffer
|
||||
public long position() {
|
||||
return this.mCurrentPosition;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.io.HprofBuffer
|
||||
public void read(byte[] bArr) {
|
||||
int index = getIndex();
|
||||
this.mByteBuffers[index].position(getOffset());
|
||||
if (bArr.length <= this.mByteBuffers[index].remaining()) {
|
||||
this.mByteBuffers[index].get(bArr, 0, bArr.length);
|
||||
} else {
|
||||
int position = this.mBufferSize - this.mByteBuffers[index].position();
|
||||
this.mByteBuffers[index].get(bArr, 0, position);
|
||||
int i = index + 1;
|
||||
this.mByteBuffers[i].position(0);
|
||||
this.mByteBuffers[i].get(bArr, position, bArr.length - position);
|
||||
}
|
||||
this.mCurrentPosition += bArr.length;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.io.HprofBuffer
|
||||
public byte readByte() {
|
||||
byte b = this.mByteBuffers[getIndex()].get(getOffset());
|
||||
this.mCurrentPosition++;
|
||||
return b;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.io.HprofBuffer
|
||||
public char readChar() {
|
||||
char c = this.mByteBuffers[getIndex()].getChar(getOffset());
|
||||
this.mCurrentPosition += 2;
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.io.HprofBuffer
|
||||
public double readDouble() {
|
||||
double d = this.mByteBuffers[getIndex()].getDouble(getOffset());
|
||||
this.mCurrentPosition += 8;
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.io.HprofBuffer
|
||||
public float readFloat() {
|
||||
float f = this.mByteBuffers[getIndex()].getFloat(getOffset());
|
||||
this.mCurrentPosition += 4;
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.io.HprofBuffer
|
||||
public int readInt() {
|
||||
int i = this.mByteBuffers[getIndex()].getInt(getOffset());
|
||||
this.mCurrentPosition += 4;
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.io.HprofBuffer
|
||||
public long readLong() {
|
||||
long j = this.mByteBuffers[getIndex()].getLong(getOffset());
|
||||
this.mCurrentPosition += 8;
|
||||
return j;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.io.HprofBuffer
|
||||
public short readShort() {
|
||||
short s = this.mByteBuffers[getIndex()].getShort(getOffset());
|
||||
this.mCurrentPosition += 2;
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.io.HprofBuffer
|
||||
public void readSubSequence(byte[] bArr, int i, int i2) {
|
||||
this.mCurrentPosition += i;
|
||||
int index = getIndex();
|
||||
this.mByteBuffers[index].position(getOffset());
|
||||
if (bArr.length <= this.mByteBuffers[index].remaining()) {
|
||||
this.mByteBuffers[index].get(bArr, 0, bArr.length);
|
||||
} else {
|
||||
int position = this.mBufferSize - this.mByteBuffers[index].position();
|
||||
this.mByteBuffers[index].get(bArr, 0, position);
|
||||
int min = Math.min(i2 - position, bArr.length - position);
|
||||
int i3 = ((min + r3) - 1) / this.mBufferSize;
|
||||
int i4 = position;
|
||||
for (int i5 = 0; i5 < i3; i5++) {
|
||||
int min2 = Math.min(min, this.mBufferSize);
|
||||
int i6 = index + 1 + i5;
|
||||
this.mByteBuffers[i6].position(0);
|
||||
this.mByteBuffers[i6].get(bArr, i4, min2);
|
||||
i4 += min2;
|
||||
min -= min2;
|
||||
}
|
||||
}
|
||||
this.mCurrentPosition += Math.min(bArr.length, i2);
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.io.HprofBuffer
|
||||
public long remaining() {
|
||||
return this.mLength - this.mCurrentPosition;
|
||||
}
|
||||
|
||||
@Override // com.squareup.haha.perflib.io.HprofBuffer
|
||||
public void setPosition(long j) {
|
||||
this.mCurrentPosition = j;
|
||||
}
|
||||
|
||||
public MemoryMappedFileBuffer(File file) throws IOException {
|
||||
this(file, DEFAULT_SIZE, 1024);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user