2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.ddmuilib;
19 import com.android.ddmlib.HeapSegment;
20 import com.android.ddmlib.ClientData.HeapData;
21 import com.android.ddmlib.HeapSegment.HeapSegmentElement;
23 import org.eclipse.swt.graphics.ImageData;
24 import org.eclipse.swt.graphics.PaletteData;
26 import java.io.ByteArrayOutputStream;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.Iterator;
32 import java.util.TreeMap;
36 * Base Panel for heap panels.
38 public abstract class BaseHeapPanel extends TablePanel {
40 /** store the processed heap segment, so that we don't recompute Image for nothing */
41 protected byte[] mProcessedHeapData;
42 private Map<Integer, ArrayList<HeapSegmentElement>> mHeapMap;
45 * Serialize the heap data into an array. The resulting array is available through
46 * <code>getSerializedData()</code>.
47 * @param heapData The heap data to serialize
48 * @return true if the data changed.
50 protected boolean serializeHeapData(HeapData heapData) {
51 Collection<HeapSegment> heapSegments;
53 // Atomically get and clear the heap data.
54 synchronized (heapData) {
56 heapSegments = heapData.getHeapSegments();
59 if (heapSegments != null) {
60 // if they are not null, we never processed them.
61 // Before we process then, we drop them from the HeapData
62 heapData.clearHeapData();
64 // process them into a linear byte[]
65 doSerializeHeapData(heapSegments);
66 heapData.setProcessedHeapData(mProcessedHeapData);
67 heapData.setProcessedHeapMap(mHeapMap);
70 // the heap segments are null. Let see if the heapData contains a
71 // list that is already processed.
73 byte[] pixData = heapData.getProcessedHeapData();
75 // and compare it to the one we currently have in the panel.
76 if (pixData == mProcessedHeapData) {
77 // looks like its the same
80 mProcessedHeapData = pixData;
83 Map<Integer, ArrayList<HeapSegmentElement>> heapMap =
84 heapData.getProcessedHeapMap();
93 * Returns the serialized heap data
95 protected byte[] getSerializedData() {
96 return mProcessedHeapData;
100 * Processes and serialize the heapData.
102 * The resulting serialized array is {@link #mProcessedHeapData}.
104 * the resulting map is {@link #mHeapMap}.
105 * @param heapData the collection of {@link HeapSegment} that forms the heap data.
107 private void doSerializeHeapData(Collection<HeapSegment> heapData) {
108 mHeapMap = new TreeMap<Integer, ArrayList<HeapSegmentElement>>();
110 Iterator<HeapSegment> iterator;
111 ByteArrayOutputStream out;
113 out = new ByteArrayOutputStream(4 * 1024);
115 iterator = heapData.iterator();
116 while (iterator.hasNext()) {
117 HeapSegment hs = iterator.next();
119 HeapSegmentElement e = null;
123 e = hs.getNextElement(null);
128 if (e.getSolidity() == HeapSegmentElement.SOLIDITY_FREE) {
134 // put the element in the map
135 ArrayList<HeapSegmentElement> elementList = mHeapMap.get(v);
136 if (elementList == null) {
137 elementList = new ArrayList<HeapSegmentElement>();
138 mHeapMap.put(v, elementList);
143 int len = e.getLength() / 8;
150 mProcessedHeapData = out.toByteArray();
152 // sort the segment element in the heap info.
153 Collection<ArrayList<HeapSegmentElement>> elementLists = mHeapMap.values();
154 for (ArrayList<HeapSegmentElement> elementList : elementLists) {
155 Collections.sort(elementList);
160 * Creates a linear image of the heap data.
166 protected ImageData createLinearHeapImage(byte[] pixData, int h, PaletteData palette) {
167 int w = pixData.length / h;
168 if (pixData.length % h != 0) {
172 // Create the heap image.
173 ImageData id = new ImageData(w, h, 8, palette);
177 for (byte b : pixData) {
179 id.setPixel(x, y, b);