blob: dbb84f600e9c7d42365c9e63852b0280e46aa3f3 [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;
Gus Smithe6a63872016-06-09 16:50:44 -070023
Richard Uhlerb730b782015-07-15 16:01:58 -070024import java.util.ArrayList;
25import java.util.Collection;
26import java.util.HashMap;
27import java.util.Iterator;
28import java.util.List;
29import java.util.Map;
30
31class Site {
32 // The site that this site was directly called from.
33 // mParent is null for the root site.
34 private Site mParent;
35
36 // A description of the Site. Currently this is used to uniquely identify a
37 // site within its parent.
38 private String mName;
39
40 // To identify this site, we pick one stack trace where we have seen the
41 // site. mStackId is the id for that stack trace, and mStackDepth is the
42 // depth of this site in that stack trace.
43 // For the root site, mStackId is 0 and mStackDepth is 0.
44 private int mStackId;
45 private int mStackDepth;
46
47 // Mapping from heap name to the total size of objects allocated in this
48 // site (including child sites) on the given heap.
49 private Map<String, Long> mSizesByHeap;
50
51 // Mapping from child site name to child site.
52 private Map<String, Site> mChildren;
53
54 // List of all objects allocated in this site (including child sites).
55 private List<Instance> mObjects;
56 private List<ObjectsInfo> mObjectsInfos;
57 private Map<Heap, Map<ClassObj, ObjectsInfo>> mObjectsInfoMap;
58
59 public static class ObjectsInfo {
60 public Heap heap;
61 public ClassObj classObj;
62 public long numInstances;
63 public long numBytes;
64
65 public ObjectsInfo(Heap heap, ClassObj classObj, long numInstances, long numBytes) {
66 this.heap = heap;
67 this.classObj = classObj;
68 this.numInstances = numInstances;
69 this.numBytes = numBytes;
70 }
71 }
72
73 /**
74 * Construct a root site.
75 */
76 public Site(String name) {
77 this(null, name, 0, 0);
78 }
79
80 public Site(Site parent, String name, int stackId, int stackDepth) {
81 mParent = parent;
82 mName = name;
83 mStackId = stackId;
84 mStackDepth = stackDepth;
85 mSizesByHeap = new HashMap<String, Long>();
86 mChildren = new HashMap<String, Site>();
87 mObjects = new ArrayList<Instance>();
88 mObjectsInfos = new ArrayList<ObjectsInfo>();
89 mObjectsInfoMap = new HashMap<Heap, Map<ClassObj, ObjectsInfo>>();
90 }
91
92 /**
93 * Add an instance to this site.
94 * Returns the site at which the instance was allocated.
95 */
96 public Site add(int stackId, int stackDepth, Iterator<StackFrame> path, Instance inst) {
97 mObjects.add(inst);
98
99 String heap = inst.getHeap().getName();
100 mSizesByHeap.put(heap, getSize(heap) + inst.getSize());
101
102 Map<ClassObj, ObjectsInfo> classToObjectsInfo = mObjectsInfoMap.get(inst.getHeap());
103 if (classToObjectsInfo == null) {
104 classToObjectsInfo = new HashMap<ClassObj, ObjectsInfo>();
105 mObjectsInfoMap.put(inst.getHeap(), classToObjectsInfo);
106 }
107
108 ObjectsInfo info = classToObjectsInfo.get(inst.getClassObj());
109 if (info == null) {
110 info = new ObjectsInfo(inst.getHeap(), inst.getClassObj(), 0, 0);
111 mObjectsInfos.add(info);
112 classToObjectsInfo.put(inst.getClassObj(), info);
113 }
114
115 info.numInstances++;
116 info.numBytes += inst.getSize();
117
118 if (path.hasNext()) {
119 String next = path.next().toString();
120 Site child = mChildren.get(next);
121 if (child == null) {
122 child = new Site(this, next, stackId, stackDepth + 1);
123 mChildren.put(next, child);
124 }
125 return child.add(stackId, stackDepth + 1, path, inst);
126 } else {
127 return this;
128 }
129 }
130
131 // Get the size of a site for a specific heap.
132 public long getSize(String heap) {
133 Long val = mSizesByHeap.get(heap);
134 if (val == null) {
135 return 0;
136 }
137 return val;
138 }
139
140 /**
141 * Get the list of objects allocated under this site. Includes objects
142 * allocated in children sites.
143 */
144 public Collection<Instance> getObjects() {
145 return mObjects;
146 }
147
148 public List<ObjectsInfo> getObjectsInfos() {
149 return mObjectsInfos;
150 }
151
152 // Get the combined size of the site for all heaps.
153 public long getTotalSize() {
154 long size = 0;
155 for (Long val : mSizesByHeap.values()) {
156 size += val;
157 }
158 return size;
159 }
160
161 /**
162 * Return the site this site was called from.
163 * Returns null for the root site.
164 */
165 public Site getParent() {
166 return mParent;
167 }
168
169 public String getName() {
170 return mName;
171 }
172
173 // Returns the hprof id of a stack this site appears on.
174 public int getStackId() {
175 return mStackId;
176 }
177
178 // Returns the stack depth of this site in the stack whose id is returned
179 // by getStackId().
180 public int getStackDepth() {
181 return mStackDepth;
182 }
183
184 List<Site> getChildren() {
185 return new ArrayList<Site>(mChildren.values());
186 }
187
188 // Get the child at the given path relative to this site.
189 // Returns null if no such child found.
190 Site getChild(Iterator<StackFrame> path) {
191 if (path.hasNext()) {
192 String next = path.next().toString();
193 Site child = mChildren.get(next);
194 return (child == null) ? null : child.getChild(path);
195 } else {
196 return this;
197 }
198 }
199}