279 lines
8.8 KiB
Java
279 lines
8.8 KiB
Java
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;
|
|
}
|
|
}
|