comparison agent/src/share/classes/sun/jvm/hotspot/ui/ObjectListPanel.java @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children c18cbe5936b8
comparison
equal deleted inserted replaced
-1:000000000000 0:a61af66fc99e
1 /*
2 * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
24
25 package sun.jvm.hotspot.ui;
26
27 import java.io.*;
28 import java.util.*;
29 import java.awt.*;
30 import java.awt.event.*;
31 import javax.swing.*;
32 import javax.swing.table.*;
33
34 import sun.jvm.hotspot.debugger.*;
35 import sun.jvm.hotspot.oops.*;
36 import sun.jvm.hotspot.runtime.*;
37 import sun.jvm.hotspot.utilities.*;
38 import sun.jvm.hotspot.ui.table.*;
39 import sun.jvm.hotspot.ui.tree.*;
40
41 /** Lists objects along with their types */
42
43 public class ObjectListPanel extends SAPanel {
44 private ObjectListTableModel dataModel;
45 private JTable table;
46 private java.util.List elements;
47 private HeapProgressThunk thunk;
48 private boolean checkedForArrays;
49 private boolean hasArrays;
50 private int numColumns;
51 // For changing the text of the "Compute Liveness" button
52 private JButton livenessButton;
53 private ActionListener livenessButtonListener;
54 private static final String showLivenessText = "Show Liveness";
55
56 /** Takes a List<Oop> in constructor, and an optional
57 HeapProgressThunk used if computing liveness */
58 public ObjectListPanel(java.util.List els,
59 HeapProgressThunk thunk) {
60 super();
61
62 elements = els;
63 this.thunk = thunk;
64 computeNumColumns();
65
66 setLayout(new BorderLayout());
67
68 dataModel = new ObjectListTableModel();
69
70 table = new JTable(dataModel);
71 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
72 JTableHeader header = table.getTableHeader();
73 header.setDefaultRenderer(new SortHeaderCellRenderer(header, dataModel));
74 header.addMouseListener(new SortHeaderMouseAdapter(table, dataModel));
75
76 JScrollPane scrollPane = new JScrollPane(table);
77 add(scrollPane, BorderLayout.CENTER);
78
79 JPanel panel = new JPanel();
80 panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
81 panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
82 Box box = Box.createHorizontalBox();
83 box.add(Box.createGlue());
84 JButton button = new JButton("Inspect");
85 button.addActionListener(new ActionListener() {
86 public void actionPerformed(ActionEvent e) {
87 fireShowInspector();
88 }
89 });
90 box.add(button);
91
92 box.add(Box.createHorizontalStrut(20));
93
94 // Liveness button
95 button = new JButton();
96 livenessButton = button;
97 if (VM.getVM().getRevPtrs() == null) {
98 button.setText("Compute Liveness");
99 livenessButtonListener = new ActionListener() {
100 public void actionPerformed(ActionEvent e) {
101 fireComputeLiveness();
102 }
103 };
104 } else {
105 button.setText("Show Liveness Path");
106 livenessButtonListener = new ActionListener() {
107 public void actionPerformed(ActionEvent e) {
108 fireShowLiveness();
109 }
110 };
111 }
112 button.addActionListener(livenessButtonListener);
113 box.add(button);
114 box.add(Box.createGlue());
115 panel.add(box);
116 add(panel, BorderLayout.SOUTH);
117 }
118
119 //--------------------------------------------------------------------------------
120 // Internals only below this point
121 //
122
123 private static class AddressWrapper implements Comparable {
124 private Address address;
125
126 private AddressWrapper(Address address) {
127 this.address = address;
128 }
129
130 public String toString() {
131 return address.toString();
132 }
133
134 public int compareTo(Object o) {
135 AddressWrapper wrapper = (AddressWrapper) o;
136 Address addr = wrapper.address;
137 if (AddressOps.lessThan(address, addr)) return -1;
138 if (AddressOps.greaterThan(address, addr)) return 1;
139 return 0;
140 }
141 }
142
143 private class ObjectListTableModel extends SortableTableModel {
144 public ObjectListTableModel() {
145 // Set the rows
146 this.elements = ObjectListPanel.this.elements;
147 setComparator(new ObjectListComparator(this));
148 }
149
150 public int getColumnCount() { return numColumns; }
151 public int getRowCount() { return elements.size(); }
152 public String getColumnName(int col) {
153 switch (col) {
154 case 0:
155 return "Address";
156 case 1:
157 return "Oop";
158 case 2:
159 if (hasArrays) {
160 return "Length";
161 } else {
162 return "Class Description";
163 }
164 case 3:
165 if (hasArrays) {
166 return "Class Description";
167 } else if (VM.getVM().getRevPtrs() != null) {
168 return "Liveness";
169 }
170 case 4:
171 if (hasArrays && (VM.getVM().getRevPtrs() != null)) {
172 return "Liveness";
173 }
174 }
175 throw new RuntimeException("Index " + col + " out of bounds");
176 }
177
178 public Object getValueAt(int row, int col) {
179 Oop oop = (Oop) elements.get(row);
180 return getValueForColumn(oop, col);
181 }
182
183 public Object getValueForColumn(Oop oop, int col) {
184 ByteArrayOutputStream bos = new ByteArrayOutputStream();
185
186 switch (col) {
187 case 0:
188 return new AddressWrapper(oop.getHandle());
189 case 1:
190 oop.printValueOn(new PrintStream(bos));
191 break;
192 case 2:
193 if (hasArrays) {
194 if (oop instanceof Array) {
195 return new Long(((Array) oop).getLength());
196 }
197 return null;
198 } else {
199 oop.getKlass().printValueOn(new PrintStream(bos));
200 break;
201 }
202 case 3:
203 if (hasArrays) {
204 oop.getKlass().printValueOn(new PrintStream(bos));
205 break;
206 } else {
207 if (VM.getVM().getRevPtrs() != null) {
208 if (VM.getVM().getRevPtrs().get(oop) != null) {
209 return "Alive";
210 } else {
211 return "Dead";
212 }
213 }
214 }
215 case 4:
216 if (hasArrays) {
217 if (VM.getVM().getRevPtrs() != null) {
218 if (VM.getVM().getRevPtrs().get(oop) != null) {
219 return "Alive";
220 } else {
221 return "Dead";
222 }
223 }
224 }
225 default:
226 throw new RuntimeException("Column " + col + " out of bounds");
227 }
228
229 return bos.toString();
230 }
231
232 private class ObjectListComparator extends TableModelComparator {
233 public ObjectListComparator(ObjectListTableModel model) {
234 super(model);
235 }
236
237 /**
238 * Returns the value for the comparing object for the
239 * column.
240 *
241 * @param obj Object that was passed for Comparator
242 * @param column the column to retrieve
243 */
244 public Object getValueForColumn(Object obj, int column) {
245 ObjectListTableModel omodel = (ObjectListTableModel)model;
246 return omodel.getValueForColumn((Oop) obj, column);
247 }
248 }
249 }
250
251 private void fireShowInspector() {
252 int i = table.getSelectedRow();
253 if (i < 0) {
254 return;
255 }
256
257 Oop oop = (Oop) elements.get(i);
258
259 for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
260 SAListener listener = (SAListener) iter.next();
261 listener.showInspector(new OopTreeNodeAdapter(oop, null));
262 }
263 }
264
265 private void fireComputeLiveness() {
266 final Runnable cutoverButtonRunnable = new Runnable() {
267 public void run() {
268 livenessButton.removeActionListener(livenessButtonListener);
269 livenessButtonListener = null;
270 livenessButton.addActionListener(new ActionListener() {
271 public void actionPerformed(ActionEvent e) {
272 fireShowLiveness();
273 }
274 });
275 computeNumColumns();
276 livenessButton.setEnabled(true);
277 livenessButton.setText(showLivenessText);
278 dataModel.fireTableStructureChanged();
279 }
280 };
281
282
283 if (VM.getVM().getRevPtrs() != null) {
284 cutoverButtonRunnable.run();
285 } else {
286 final WorkerThread worker = new WorkerThread();
287 worker.invokeLater(new Runnable() {
288 public void run() {
289 try {
290 ReversePtrsAnalysis rev = new ReversePtrsAnalysis();
291 if (thunk != null) {
292 rev.setHeapProgressThunk(thunk);
293 }
294 rev.run();
295 cutoverButtonRunnable.run();
296 } finally {
297 worker.shutdown();
298 }
299 }
300 });
301 }
302 }
303
304 private void fireShowLiveness() {
305 if (VM.getVM().getRevPtrs() == null) {
306 return;
307 }
308
309 int i = table.getSelectedRow();
310 if (i < 0) {
311 return;
312 }
313
314 Oop oop = (Oop) elements.get(i);
315 LivenessPathList list = LivenessAnalysis.computeAllLivenessPaths(oop);
316 if (list == null) {
317 return; // dead object
318 }
319
320 for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
321 SAListener listener = (SAListener) iter.next();
322 listener.showLiveness(oop, list);
323 }
324 }
325
326 private void checkForArrays() {
327 if (checkedForArrays) return;
328 checkedForArrays = true;
329 for (Iterator iter = elements.iterator(); iter.hasNext(); ) {
330 if (iter.next() instanceof Array) {
331 hasArrays = true;
332 return;
333 }
334 }
335 }
336
337 private void computeNumColumns() {
338 checkForArrays();
339 numColumns = 3;
340 if (hasArrays) ++numColumns;
341 if (VM.getVM().getRevPtrs() != null) ++numColumns;
342 }
343 }