• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 
17 package com.android.ddmlib;
18 
19 import java.util.Comparator;
20 
21 /**
22  * Holds an Allocation information.
23  */
24 public class AllocationInfo implements IStackTraceInfo {
25     private final String mAllocatedClass;
26     private final int mAllocNumber;
27     private final int mAllocationSize;
28     private final short mThreadId;
29     private final StackTraceElement[] mStackTrace;
30 
31     public static enum SortMode {
32         NUMBER, SIZE, CLASS, THREAD, IN_CLASS, IN_METHOD;
33     }
34 
35     public final static class AllocationSorter implements Comparator<AllocationInfo> {
36 
37         private SortMode mSortMode = SortMode.SIZE;
38         private boolean mDescending = true;
39 
AllocationSorter()40         public AllocationSorter() {
41         }
42 
setSortMode(SortMode mode)43         public void setSortMode(SortMode mode) {
44             if (mSortMode == mode) {
45                 mDescending = !mDescending;
46             } else {
47                 mSortMode = mode;
48             }
49         }
50 
getSortMode()51         public SortMode getSortMode() {
52             return mSortMode;
53         }
54 
isDescending()55         public boolean isDescending() {
56             return mDescending;
57         }
58 
compare(AllocationInfo o1, AllocationInfo o2)59         public int compare(AllocationInfo o1, AllocationInfo o2) {
60             int diff = 0;
61             switch (mSortMode) {
62                 case NUMBER:
63                     diff = o1.mAllocNumber - o2.mAllocNumber;
64                     break;
65                 case SIZE:
66                     // pass, since diff is init with 0, we'll use SIZE compare below
67                     // as a back up anyway.
68                     break;
69                 case CLASS:
70                     diff = o1.mAllocatedClass.compareTo(o2.mAllocatedClass);
71                     break;
72                 case THREAD:
73                     diff = o1.mThreadId - o2.mThreadId;
74                     break;
75                 case IN_CLASS:
76                     String class1 = o1.getFirstTraceClassName();
77                     String class2 = o2.getFirstTraceClassName();
78                     diff = compareOptionalString(class1, class2);
79                     break;
80                 case IN_METHOD:
81                     String method1 = o1.getFirstTraceMethodName();
82                     String method2 = o2.getFirstTraceMethodName();
83                     diff = compareOptionalString(method1, method2);
84                     break;
85             }
86 
87             if (diff == 0) {
88                 // same? compare on size
89                 diff = o1.mAllocationSize - o2.mAllocationSize;
90             }
91 
92             if (mDescending) {
93                 diff = -diff;
94             }
95 
96             return diff;
97         }
98 
99         /** compares two strings that could be null */
compareOptionalString(String str1, String str2)100         private int compareOptionalString(String str1, String str2) {
101             if (str1 != null) {
102                 if (str2 == null) {
103                     return -1;
104                 } else {
105                     return str1.compareTo(str2);
106                 }
107             } else {
108                 if (str2 == null) {
109                     return 0;
110                 } else {
111                     return 1;
112                 }
113             }
114         }
115     }
116 
117     /*
118      * Simple constructor.
119      */
AllocationInfo(int allocNumber, String allocatedClass, int allocationSize, short threadId, StackTraceElement[] stackTrace)120     AllocationInfo(int allocNumber, String allocatedClass, int allocationSize,
121         short threadId, StackTraceElement[] stackTrace) {
122         mAllocNumber = allocNumber;
123         mAllocatedClass = allocatedClass;
124         mAllocationSize = allocationSize;
125         mThreadId = threadId;
126         mStackTrace = stackTrace;
127     }
128 
129     /**
130      * Returns the allocation number. Allocations are numbered as they happen with the most
131      * recent one having the highest number
132      */
getAllocNumber()133     public int getAllocNumber() {
134         return mAllocNumber;
135     }
136 
137     /**
138      * Returns the name of the allocated class.
139      */
getAllocatedClass()140     public String getAllocatedClass() {
141         return mAllocatedClass;
142     }
143 
144     /**
145      * Returns the size of the allocation.
146      */
getSize()147     public int getSize() {
148         return mAllocationSize;
149     }
150 
151     /**
152      * Returns the id of the thread that performed the allocation.
153      */
getThreadId()154     public short getThreadId() {
155         return mThreadId;
156     }
157 
158     /*
159      * (non-Javadoc)
160      * @see com.android.ddmlib.IStackTraceInfo#getStackTrace()
161      */
getStackTrace()162     public StackTraceElement[] getStackTrace() {
163         return mStackTrace;
164     }
165 
compareTo(AllocationInfo otherAlloc)166     public int compareTo(AllocationInfo otherAlloc) {
167         return otherAlloc.mAllocationSize - mAllocationSize;
168     }
169 
getFirstTraceClassName()170     public String getFirstTraceClassName() {
171         if (mStackTrace.length > 0) {
172             return mStackTrace[0].getClassName();
173         }
174 
175         return null;
176     }
177 
getFirstTraceMethodName()178     public String getFirstTraceMethodName() {
179         if (mStackTrace.length > 0) {
180             return mStackTrace[0].getMethodName();
181         }
182 
183         return null;
184     }
185 
filter(String filter, boolean fullTrace)186     public boolean filter(String filter, boolean fullTrace) {
187         if (mAllocatedClass.toLowerCase().contains(filter)) {
188             return true;
189         }
190 
191         if (mStackTrace.length > 0) {
192             // check the top of the stack trace always
193             final int length = fullTrace ? mStackTrace.length : 1;
194 
195             for (int i = 0 ; i < length ; i++) {
196                 if (mStackTrace[i].getClassName().toLowerCase().contains(filter)) {
197                     return true;
198                 }
199 
200                 if (mStackTrace[i].getMethodName().toLowerCase().contains(filter)) {
201                     return true;
202                 }
203             }
204         }
205 
206         return false;
207     }
208 }
209