Mercurial > hg > truffle
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/src/share/classes/sun/jvm/hotspot/ui/ObjectListPanel.java Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,343 @@ +/* + * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package sun.jvm.hotspot.ui; + +import java.io.*; +import java.util.*; +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.table.*; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.oops.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.utilities.*; +import sun.jvm.hotspot.ui.table.*; +import sun.jvm.hotspot.ui.tree.*; + +/** Lists objects along with their types */ + +public class ObjectListPanel extends SAPanel { + private ObjectListTableModel dataModel; + private JTable table; + private java.util.List elements; + private HeapProgressThunk thunk; + private boolean checkedForArrays; + private boolean hasArrays; + private int numColumns; + // For changing the text of the "Compute Liveness" button + private JButton livenessButton; + private ActionListener livenessButtonListener; + private static final String showLivenessText = "Show Liveness"; + + /** Takes a List<Oop> in constructor, and an optional + HeapProgressThunk used if computing liveness */ + public ObjectListPanel(java.util.List els, + HeapProgressThunk thunk) { + super(); + + elements = els; + this.thunk = thunk; + computeNumColumns(); + + setLayout(new BorderLayout()); + + dataModel = new ObjectListTableModel(); + + table = new JTable(dataModel); + table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + JTableHeader header = table.getTableHeader(); + header.setDefaultRenderer(new SortHeaderCellRenderer(header, dataModel)); + header.addMouseListener(new SortHeaderMouseAdapter(table, dataModel)); + + JScrollPane scrollPane = new JScrollPane(table); + add(scrollPane, BorderLayout.CENTER); + + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); + panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + Box box = Box.createHorizontalBox(); + box.add(Box.createGlue()); + JButton button = new JButton("Inspect"); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + fireShowInspector(); + } + }); + box.add(button); + + box.add(Box.createHorizontalStrut(20)); + + // Liveness button + button = new JButton(); + livenessButton = button; + if (VM.getVM().getRevPtrs() == null) { + button.setText("Compute Liveness"); + livenessButtonListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + fireComputeLiveness(); + } + }; + } else { + button.setText("Show Liveness Path"); + livenessButtonListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + fireShowLiveness(); + } + }; + } + button.addActionListener(livenessButtonListener); + box.add(button); + box.add(Box.createGlue()); + panel.add(box); + add(panel, BorderLayout.SOUTH); + } + + //-------------------------------------------------------------------------------- + // Internals only below this point + // + + private static class AddressWrapper implements Comparable { + private Address address; + + private AddressWrapper(Address address) { + this.address = address; + } + + public String toString() { + return address.toString(); + } + + public int compareTo(Object o) { + AddressWrapper wrapper = (AddressWrapper) o; + Address addr = wrapper.address; + if (AddressOps.lessThan(address, addr)) return -1; + if (AddressOps.greaterThan(address, addr)) return 1; + return 0; + } + } + + private class ObjectListTableModel extends SortableTableModel { + public ObjectListTableModel() { + // Set the rows + this.elements = ObjectListPanel.this.elements; + setComparator(new ObjectListComparator(this)); + } + + public int getColumnCount() { return numColumns; } + public int getRowCount() { return elements.size(); } + public String getColumnName(int col) { + switch (col) { + case 0: + return "Address"; + case 1: + return "Oop"; + case 2: + if (hasArrays) { + return "Length"; + } else { + return "Class Description"; + } + case 3: + if (hasArrays) { + return "Class Description"; + } else if (VM.getVM().getRevPtrs() != null) { + return "Liveness"; + } + case 4: + if (hasArrays && (VM.getVM().getRevPtrs() != null)) { + return "Liveness"; + } + } + throw new RuntimeException("Index " + col + " out of bounds"); + } + + public Object getValueAt(int row, int col) { + Oop oop = (Oop) elements.get(row); + return getValueForColumn(oop, col); + } + + public Object getValueForColumn(Oop oop, int col) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + switch (col) { + case 0: + return new AddressWrapper(oop.getHandle()); + case 1: + oop.printValueOn(new PrintStream(bos)); + break; + case 2: + if (hasArrays) { + if (oop instanceof Array) { + return new Long(((Array) oop).getLength()); + } + return null; + } else { + oop.getKlass().printValueOn(new PrintStream(bos)); + break; + } + case 3: + if (hasArrays) { + oop.getKlass().printValueOn(new PrintStream(bos)); + break; + } else { + if (VM.getVM().getRevPtrs() != null) { + if (VM.getVM().getRevPtrs().get(oop) != null) { + return "Alive"; + } else { + return "Dead"; + } + } + } + case 4: + if (hasArrays) { + if (VM.getVM().getRevPtrs() != null) { + if (VM.getVM().getRevPtrs().get(oop) != null) { + return "Alive"; + } else { + return "Dead"; + } + } + } + default: + throw new RuntimeException("Column " + col + " out of bounds"); + } + + return bos.toString(); + } + + private class ObjectListComparator extends TableModelComparator { + public ObjectListComparator(ObjectListTableModel model) { + super(model); + } + + /** + * Returns the value for the comparing object for the + * column. + * + * @param obj Object that was passed for Comparator + * @param column the column to retrieve + */ + public Object getValueForColumn(Object obj, int column) { + ObjectListTableModel omodel = (ObjectListTableModel)model; + return omodel.getValueForColumn((Oop) obj, column); + } + } + } + + private void fireShowInspector() { + int i = table.getSelectedRow(); + if (i < 0) { + return; + } + + Oop oop = (Oop) elements.get(i); + + for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { + SAListener listener = (SAListener) iter.next(); + listener.showInspector(new OopTreeNodeAdapter(oop, null)); + } + } + + private void fireComputeLiveness() { + final Runnable cutoverButtonRunnable = new Runnable() { + public void run() { + livenessButton.removeActionListener(livenessButtonListener); + livenessButtonListener = null; + livenessButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + fireShowLiveness(); + } + }); + computeNumColumns(); + livenessButton.setEnabled(true); + livenessButton.setText(showLivenessText); + dataModel.fireTableStructureChanged(); + } + }; + + + if (VM.getVM().getRevPtrs() != null) { + cutoverButtonRunnable.run(); + } else { + final WorkerThread worker = new WorkerThread(); + worker.invokeLater(new Runnable() { + public void run() { + try { + ReversePtrsAnalysis rev = new ReversePtrsAnalysis(); + if (thunk != null) { + rev.setHeapProgressThunk(thunk); + } + rev.run(); + cutoverButtonRunnable.run(); + } finally { + worker.shutdown(); + } + } + }); + } + } + + private void fireShowLiveness() { + if (VM.getVM().getRevPtrs() == null) { + return; + } + + int i = table.getSelectedRow(); + if (i < 0) { + return; + } + + Oop oop = (Oop) elements.get(i); + LivenessPathList list = LivenessAnalysis.computeAllLivenessPaths(oop); + if (list == null) { + return; // dead object + } + + for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { + SAListener listener = (SAListener) iter.next(); + listener.showLiveness(oop, list); + } + } + + private void checkForArrays() { + if (checkedForArrays) return; + checkedForArrays = true; + for (Iterator iter = elements.iterator(); iter.hasNext(); ) { + if (iter.next() instanceof Array) { + hasArrays = true; + return; + } + } + } + + private void computeNumColumns() { + checkForArrays(); + numColumns = 3; + if (hasArrays) ++numColumns; + if (VM.getVM().getRevPtrs() != null) ++numColumns; + } +}