/*
* Copyright (C) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.hit;
import java.util.ArrayList;
import java.util.HashMap;
public class Heap {
String mName;
// List of individual stack frames
HashMap<Long, StackFrame> mFrames = new HashMap<Long, StackFrame>();
// List stack traces, which are lists of stack frames
HashMap<Integer, StackTrace> mTraces = new HashMap<Integer, StackTrace>();
// Root objects such as interned strings, jni locals, etc
ArrayList<RootObj> mRoots = new ArrayList<RootObj>();
// List of threads
HashMap<Integer, ThreadObj> mThreads = new HashMap<Integer, ThreadObj>();
// Class definitions
HashMap<Long, ClassObj> mClassesById = new HashMap<Long, ClassObj>();
HashMap<String, ClassObj> mClassesByName = new HashMap<String, ClassObj>();
// List of instances of above class definitions
HashMap<Long, Instance> mInstances = new HashMap<Long, Instance>();
// The super-state that this heap is part of
State mState;
public Heap(String name) {
mName = name;
}
public final void addStackFrame(StackFrame theFrame) {
mFrames.put(theFrame.mId, theFrame);
}
public final StackFrame getStackFrame(long id) {
return mFrames.get(id);
}
public final void addStackTrace(StackTrace theTrace) {
mTraces.put(theTrace.mSerialNumber, theTrace);
}
public final StackTrace getStackTrace(int traceSerialNumber) {
return mTraces.get(traceSerialNumber);
}
public final StackTrace getStackTraceAtDepth(int traceSerialNumber,
int depth) {
StackTrace trace = mTraces.get(traceSerialNumber);
if (trace != null) {
trace = trace.fromDepth(depth);
}
return trace;
}
public final void addRoot(RootObj root) {
root.mIndex = mRoots.size();
mRoots.add(root);
}
public final void addThread(ThreadObj thread, int serialNumber) {
mThreads.put(serialNumber, thread);
}
public final ThreadObj getThread(int serialNumber) {
return mThreads.get(serialNumber);
}
public final void addInstance(long id, Instance instance) {
mInstances.put(id, instance);
}
public final Instance getInstance(long id) {
return mInstances.get(id);
}
public final void addClass(long id, ClassObj theClass) {
mClassesById.put(id, theClass);
mClassesByName.put(theClass.mClassName, theClass);
}
public final ClassObj getClass(long id) {
return mClassesById.get(id);
}
public final ClassObj getClass(String name) {
return mClassesByName.get(name);
}
public final void dumpInstanceCounts() {
for (ClassObj theClass: mClassesById.values()) {
int count = theClass.mInstances.size();
if (count > 0) {
System.out.println(theClass + ": " + count);
}
}
}
public final void dumpSubclasses() {
for (ClassObj theClass: mClassesById.values()) {
int count = theClass.mSubclasses.size();
if (count > 0) {
System.out.println(theClass);
theClass.dumpSubclasses();
}
}
}
public final void dumpSizes() {
for (ClassObj theClass: mClassesById.values()) {
int size = 0;
for (Instance instance: theClass.mInstances) {
size += instance.getCompositeSize();
}
if (size > 0) {
System.out.println(theClass + ": base " + theClass.getSize()
+ ", composite " + size);
}
}
}
/*
* Spin through all of the class instances and link them to their
* parent class definition objects. Then have each instance resolve
* its own internal object references.
*/
public final void resolveInstanceRefs(State state) {
for (Instance instance : mInstances.values()) {
ClassObj theClass = mClassesById.get(instance.mClassId);
if (theClass == null) {
continue;
}
String name = theClass.mClassName;
String superclassName = "none";
ClassObj superClass = mClassesById.get(theClass.mSuperclassId);
if (superClass != null) {
superclassName = superClass.mClassName;
}
theClass.addInstance(instance);
instance.resolveReferences(state);
}
}
public final void resolveClassStatics(State state) {
for (ClassObj theClass: mClassesById.values()) {
theClass.resolveReferences(state);
}
}
public final void resolveRoots(State state) {
for (RootObj root: mRoots) {
root.resolveReferences(state);
}
}
}
|