blob: d50409631463c6882f1a8c7afc725b3aab475795 [file] [log] [blame]
Richard Uhlerb730b782015-07-15 16:01:58 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.ahat;
18
19import com.android.tools.perflib.heap.ClassObj;
20import com.android.tools.perflib.heap.Heap;
21import com.android.tools.perflib.heap.Instance;
22import com.android.tools.perflib.heap.StackFrame;
23import java.util.ArrayList;
24import java.util.Collection;
25import java.util.HashMap;
26import java.util.Iterator;
27import java.util.List;
28import java.util.Map;
29
30class Site {
31 // The site that this site was directly called from.
32 // mParent is null for the root site.
33 private Site mParent;
34
35 // A description of the Site. Currently this is used to uniquely identify a
36 // site within its parent.
37 private String mName;
38
39 // To identify this site, we pick one stack trace where we have seen the
40 // site. mStackId is the id for that stack trace, and mStackDepth is the
41 // depth of this site in that stack trace.
42 // For the root site, mStackId is 0 and mStackDepth is 0.
43 private int mStackId;
44 private int mStackDepth;
45
46 // Mapping from heap name to the total size of objects allocated in this
47 // site (including child sites) on the given heap.
48 private Map<String, Long> mSizesByHeap;
49
50 // Mapping from child site name to child site.
51 private Map<String, Site> mChildren;
52
53 // List of all objects allocated in this site (including child sites).
54 private List<Instance> mObjects;
55 private List<ObjectsInfo> mObjectsInfos;
56 private Map<Heap, Map<ClassObj, ObjectsInfo>> mObjectsInfoMap;
57
58 public static class ObjectsInfo {
59 public Heap heap;
60 public ClassObj classObj;
61 public long numInstances;
62 public long numBytes;
63
64 public ObjectsInfo(Heap heap, ClassObj classObj, long numInstances, long numBytes) {
65 this.heap = heap;
66 this.classObj = classObj;
67 this.numInstances = numInstances;
68 this.numBytes = numBytes;
69 }
70 }
71
72 /**
73 * Construct a root site.
74 */
75 public Site(String name) {
76 this(null, name, 0, 0);
77 }
78
79 public Site(Site parent, String name, int stackId, int stackDepth) {
80 mParent = parent;
81 mName = name;
82 mStackId = stackId;
83 mStackDepth = stackDepth;
84 mSizesByHeap = new HashMap<String, Long>();
85 mChildren = new HashMap<String, Site>();
86 mObjects = new ArrayList<Instance>();
87 mObjectsInfos = new ArrayList<ObjectsInfo>();
88 mObjectsInfoMap = new HashMap<Heap, Map<ClassObj, ObjectsInfo>>();
89 }
90
91 /**
92 * Add an instance to this site.
93 * Returns the site at which the instance was allocated.
94 */
95 public Site add(int stackId, int stackDepth, Iterator<StackFrame> path, Instance inst) {
96 mObjects.add(inst);
97
98 String heap = inst.getHeap().getName();
99 mSizesByHeap.put(heap, getSize(heap) + inst.getSize());
100
101 Map<ClassObj, ObjectsInfo> classToObjectsInfo = mObjectsInfoMap.get(inst.getHeap());
102 if (classToObjectsInfo == null) {
103 classToObjectsInfo = new HashMap<ClassObj, ObjectsInfo>();
104 mObjectsInfoMap.put(inst.getHeap(), classToObjectsInfo);
105 }
106
107 ObjectsInfo info = classToObjectsInfo.get(inst.getClassObj());
108 if (info == null) {
109 info = new ObjectsInfo(inst.getHeap(), inst.getClassObj(), 0, 0);
110 mObjectsInfos.add(info);
111 classToObjectsInfo.put(inst.getClassObj(), info);
112 }
113
114 info.numInstances++;
115 info.numBytes += inst.getSize();
116
117 if (path.hasNext()) {
118 String next = path.next().toString();
119 Site child = mChildren.get(next);
120 if (child == null) {
121 child = new Site(this, next, stackId, stackDepth + 1);
122 mChildren.put(next, child);
123 }
124 return child.add(stackId, stackDepth + 1, path, inst);
125 } else {
126 return this;
127 }
128 }
129
130 // Get the size of a site for a specific heap.
131 public long getSize(String heap) {
132 Long val = mSizesByHeap.get(heap);
133 if (val == null) {
134 return 0;
135 }
136 return val;
137 }
138
139 /**
140 * Get the list of objects allocated under this site. Includes objects
141 * allocated in children sites.
142 */
143 public Collection<Instance> getObjects() {
144 return mObjects;
145 }
146
147 public List<ObjectsInfo> getObjectsInfos() {
148 return mObjectsInfos;
149 }
150
151 // Get the combined size of the site for all heaps.
152 public long getTotalSize() {
153 long size = 0;
154 for (Long val : mSizesByHeap.values()) {
155 size += val;
156 }
157 return size;
158 }
159
160 /**
161 * Return the site this site was called from.
162 * Returns null for the root site.
163 */
164 public Site getParent() {
165 return mParent;
166 }
167
168 public String getName() {
169 return mName;
170 }
171
172 // Returns the hprof id of a stack this site appears on.
173 public int getStackId() {
174 return mStackId;
175 }
176
177 // Returns the stack depth of this site in the stack whose id is returned
178 // by getStackId().
179 public int getStackDepth() {
180 return mStackDepth;
181 }
182
183 List<Site> getChildren() {
184 return new ArrayList<Site>(mChildren.values());
185 }
186
187 // Get the child at the given path relative to this site.
188 // Returns null if no such child found.
189 Site getChild(Iterator<StackFrame> path) {
190 if (path.hasNext()) {
191 String next = path.next().toString();
192 Site child = mChildren.get(next);
193 return (child == null) ? null : child.getChild(path);
194 } else {
195 return this;
196 }
197 }
198}