OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / sdk / ddms / libs / ddmlib / src / com / android / ddmlib / log / GcEventContainer.java
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.log;
18
19 import com.android.ddmlib.log.EventValueDescription.ValueType;
20 import com.android.ddmlib.log.LogReceiver.LogEntry;
21
22 /**
23  * Custom Event Container for the Gc event since this event doesn't simply output data in
24  * int or long format, but encodes several values on 4 longs.
25  * <p/>
26  * The array of {@link EventValueDescription}s parsed from the "event-log-tags" file must
27  * be ignored, and instead, the array returned from {@link #getValueDescriptions()} must be used. 
28  */
29 final class GcEventContainer extends EventContainer {
30     
31     public final static int GC_EVENT_TAG = 20001;
32
33     private String processId;
34     private long gcTime;
35     private long bytesFreed;
36     private long objectsFreed;
37     private long actualSize;
38     private long allowedSize;
39     private long softLimit;
40     private long objectsAllocated;
41     private long bytesAllocated;
42     private long zActualSize;
43     private long zAllowedSize;
44     private long zObjectsAllocated;
45     private long zBytesAllocated;
46     private long dlmallocFootprint;
47     private long mallinfoTotalAllocatedSpace;
48     private long externalLimit;
49     private long externalBytesAllocated;
50
51     GcEventContainer(LogEntry entry, int tag, Object data) {
52         super(entry, tag, data);
53         init(data);
54     }
55
56     GcEventContainer(int tag, int pid, int tid, int sec, int nsec, Object data) {
57         super(tag, pid, tid, sec, nsec, data);
58         init(data);
59     }
60
61     /**
62      * @param data
63      */
64     private void init(Object data) {
65         if (data instanceof Object[]) {
66             Object[] values = (Object[])data;
67             for (int i = 0; i < values.length; i++) {
68                 if (values[i] instanceof Long) {
69                     parseDvmHeapInfo((Long)values[i], i);
70                 }
71             }
72         }
73     }
74     
75     @Override
76     public EventValueType getType() {
77         return EventValueType.LIST;
78     }
79
80     @Override
81     public boolean testValue(int index, Object value, CompareMethod compareMethod)
82             throws InvalidTypeException {
83         // do a quick easy check on the type.
84         if (index == 0) {
85             if ((value instanceof String) == false) {
86                 throw new InvalidTypeException();
87             }
88         } else if ((value instanceof Long) == false) {
89             throw new InvalidTypeException();
90         }
91         
92         switch (compareMethod) {
93             case EQUAL_TO:
94                 if (index == 0) {
95                     return processId.equals(value);
96                 } else {
97                     return getValueAsLong(index) == ((Long)value).longValue();
98                 }
99             case LESSER_THAN:
100                 return getValueAsLong(index) <= ((Long)value).longValue();
101             case LESSER_THAN_STRICT:
102                 return getValueAsLong(index) < ((Long)value).longValue();
103             case GREATER_THAN:
104                 return getValueAsLong(index) >= ((Long)value).longValue();
105             case GREATER_THAN_STRICT:
106                 return getValueAsLong(index) > ((Long)value).longValue();
107             case BIT_CHECK:
108                 return (getValueAsLong(index) & ((Long)value).longValue()) != 0;
109         }
110
111         throw new ArrayIndexOutOfBoundsException();
112     }
113
114     @Override
115     public Object getValue(int valueIndex) {
116         if (valueIndex == 0) {
117             return processId;
118         }
119         
120         try {
121             return new Long(getValueAsLong(valueIndex));
122         } catch (InvalidTypeException e) {
123             // this would only happened if valueIndex was 0, which we test above.
124         }
125         
126         return null;
127     }
128
129     @Override
130     public double getValueAsDouble(int valueIndex) throws InvalidTypeException {
131         return (double)getValueAsLong(valueIndex);
132     }
133
134     @Override
135     public String getValueAsString(int valueIndex) {
136         switch (valueIndex) {
137             case 0:
138                 return processId;
139             default:
140                 try {
141                     return Long.toString(getValueAsLong(valueIndex));
142                 } catch (InvalidTypeException e) {
143                     // we shouldn't stop there since we test, in this method first.
144                 }
145         }
146
147         throw new ArrayIndexOutOfBoundsException();
148     }
149     
150     /**
151      * Returns a custom array of {@link EventValueDescription} since the actual content of this
152      * event (list of (long, long) does not match the values encoded into those longs.
153      */
154     static EventValueDescription[] getValueDescriptions() {
155         try {
156             return new EventValueDescription[] {
157                     new EventValueDescription("Process Name", EventValueType.STRING),
158                     new EventValueDescription("GC Time", EventValueType.LONG,
159                             ValueType.MILLISECONDS),
160                     new EventValueDescription("Freed Objects", EventValueType.LONG,
161                             ValueType.OBJECTS),
162                     new EventValueDescription("Freed Bytes", EventValueType.LONG, ValueType.BYTES),
163                     new EventValueDescription("Soft Limit", EventValueType.LONG, ValueType.BYTES),
164                     new EventValueDescription("Actual Size (aggregate)", EventValueType.LONG,
165                             ValueType.BYTES),
166                     new EventValueDescription("Allowed Size (aggregate)", EventValueType.LONG,
167                             ValueType.BYTES),
168                     new EventValueDescription("Allocated Objects (aggregate)",
169                             EventValueType.LONG, ValueType.OBJECTS),
170                     new EventValueDescription("Allocated Bytes (aggregate)", EventValueType.LONG,
171                             ValueType.BYTES),
172                     new EventValueDescription("Actual Size", EventValueType.LONG, ValueType.BYTES),
173                     new EventValueDescription("Allowed Size", EventValueType.LONG, ValueType.BYTES),
174                     new EventValueDescription("Allocated Objects", EventValueType.LONG,
175                             ValueType.OBJECTS),
176                     new EventValueDescription("Allocated Bytes", EventValueType.LONG,
177                             ValueType.BYTES),
178                     new EventValueDescription("Actual Size (zygote)", EventValueType.LONG,
179                             ValueType.BYTES),
180                     new EventValueDescription("Allowed Size (zygote)", EventValueType.LONG,
181                             ValueType.BYTES),
182                     new EventValueDescription("Allocated Objects (zygote)", EventValueType.LONG,
183                             ValueType.OBJECTS),
184                     new EventValueDescription("Allocated Bytes (zygote)", EventValueType.LONG,
185                             ValueType.BYTES),
186                     new EventValueDescription("External Allocation Limit", EventValueType.LONG,
187                             ValueType.BYTES),
188                     new EventValueDescription("External Bytes Allocated", EventValueType.LONG,
189                             ValueType.BYTES),
190                     new EventValueDescription("dlmalloc Footprint", EventValueType.LONG,
191                             ValueType.BYTES),
192                     new EventValueDescription("Malloc Info: Total Allocated Space",
193                             EventValueType.LONG, ValueType.BYTES),
194                   };
195         } catch (InvalidValueTypeException e) {
196             // this shouldn't happen since we control manual the EventValueType and the ValueType
197             // values. For development purpose, we assert if this happens.
198             assert false;
199         }
200
201         // this shouldn't happen, but the compiler complains otherwise.
202         return null;
203     }
204
205     private void parseDvmHeapInfo(long data, int index) {
206         switch (index) {
207             case 0:
208                 //    [63   ] Must be zero
209                 //    [62-24] ASCII process identifier
210                 //    [23-12] GC time in ms
211                 //    [11- 0] Bytes freed
212                 
213                 gcTime = float12ToInt((int)((data >> 12) & 0xFFFL));
214                 bytesFreed = float12ToInt((int)(data & 0xFFFL));
215                 
216                 // convert the long into an array, in the proper order so that we can convert the
217                 // first 5 char into a string.
218                 byte[] dataArray = new byte[8];
219                 put64bitsToArray(data, dataArray, 0);
220                 
221                 // get the name from the string
222                 processId = new String(dataArray, 0, 5);
223                 break;
224             case 1:
225                 //    [63-62] 10
226                 //    [61-60] Reserved; must be zero
227                 //    [59-48] Objects freed
228                 //    [47-36] Actual size (current footprint)
229                 //    [35-24] Allowed size (current hard max)
230                 //    [23-12] Objects allocated
231                 //    [11- 0] Bytes allocated
232                 objectsFreed = float12ToInt((int)((data >> 48) & 0xFFFL));
233                 actualSize = float12ToInt((int)((data >> 36) & 0xFFFL));
234                 allowedSize = float12ToInt((int)((data >> 24) & 0xFFFL));
235                 objectsAllocated = float12ToInt((int)((data >> 12) & 0xFFFL));
236                 bytesAllocated = float12ToInt((int)(data & 0xFFFL));
237                 break;
238             case 2:
239                 //    [63-62] 11
240                 //    [61-60] Reserved; must be zero
241                 //    [59-48] Soft limit (current soft max)
242                 //    [47-36] Actual size (current footprint)
243                 //    [35-24] Allowed size (current hard max)
244                 //    [23-12] Objects allocated
245                 //    [11- 0] Bytes allocated
246                 softLimit = float12ToInt((int)((data >> 48) & 0xFFFL));
247                 zActualSize = float12ToInt((int)((data >> 36) & 0xFFFL));
248                 zAllowedSize = float12ToInt((int)((data >> 24) & 0xFFFL));
249                 zObjectsAllocated = float12ToInt((int)((data >> 12) & 0xFFFL));
250                 zBytesAllocated = float12ToInt((int)(data & 0xFFFL));
251                 break;
252             case 3:
253                 //    [63-48] Reserved; must be zero
254                 //    [47-36] dlmallocFootprint
255                 //    [35-24] mallinfo: total allocated space
256                 //    [23-12] External byte limit
257                 //    [11- 0] External bytes allocated
258                 dlmallocFootprint = float12ToInt((int)((data >> 36) & 0xFFFL));
259                 mallinfoTotalAllocatedSpace = float12ToInt((int)((data >> 24) & 0xFFFL));
260                 externalLimit = float12ToInt((int)((data >> 12) & 0xFFFL));
261                 externalBytesAllocated = float12ToInt((int)(data & 0xFFFL));
262                 break;
263             default:
264                 break;
265         }
266     }
267     
268     /**
269      * Converts a 12 bit float representation into an unsigned int (returned as a long)
270      * @param f12
271      */
272     private static long float12ToInt(int f12) {
273         return (f12 & 0x1FF) << ((f12 >>> 9) * 4);
274     }
275     
276     /**
277      * puts an unsigned value in an array.
278      * @param value The value to put.
279      * @param dest the destination array
280      * @param offset the offset in the array where to put the value.
281      *      Array length must be at least offset + 8
282      */
283     private static void put64bitsToArray(long value, byte[] dest, int offset) {
284         dest[offset + 7] = (byte)(value & 0x00000000000000FFL);
285         dest[offset + 6] = (byte)((value & 0x000000000000FF00L) >> 8);
286         dest[offset + 5] = (byte)((value & 0x0000000000FF0000L) >> 16);
287         dest[offset + 4] = (byte)((value & 0x00000000FF000000L) >> 24);
288         dest[offset + 3] = (byte)((value & 0x000000FF00000000L) >> 32);
289         dest[offset + 2] = (byte)((value & 0x0000FF0000000000L) >> 40);
290         dest[offset + 1] = (byte)((value & 0x00FF000000000000L) >> 48);
291         dest[offset + 0] = (byte)((value & 0xFF00000000000000L) >> 56);
292     }
293     
294     /**
295      * Returns the long value of the <code>valueIndex</code>-th value.
296      * @param valueIndex the index of the value.
297      * @throws InvalidTypeException if index is 0 as it is a string value.
298      */
299     private final long getValueAsLong(int valueIndex) throws InvalidTypeException {
300         switch (valueIndex) {
301             case 0:
302                 throw new InvalidTypeException();
303             case 1:
304                 return gcTime;
305             case 2:
306                 return objectsFreed;
307             case 3:
308                 return bytesFreed;
309             case 4:
310                 return softLimit;
311             case 5:
312                 return actualSize;
313             case 6:
314                 return allowedSize;
315             case 7:
316                 return objectsAllocated;
317             case 8:
318                 return bytesAllocated;
319             case 9:
320                 return actualSize - zActualSize;
321             case 10:
322                 return allowedSize - zAllowedSize;
323             case 11:
324                 return objectsAllocated - zObjectsAllocated;
325             case 12:
326                 return bytesAllocated - zBytesAllocated;
327             case 13:
328                return zActualSize;
329             case 14:
330                 return zAllowedSize;
331             case 15:
332                 return zObjectsAllocated;
333             case 16:
334                 return zBytesAllocated;
335             case 17:
336                 return externalLimit;
337             case 18:
338                 return externalBytesAllocated;
339             case 19:
340                 return dlmallocFootprint;
341             case 20:
342                 return mallinfoTotalAllocatedSpace;
343         }
344
345         throw new ArrayIndexOutOfBoundsException();
346     }
347 }