1 /* 2 * Copyright 2001-2002 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.bugspot; 26 27 import java.awt.*; 28 import javax.swing.*; 29 import java.util.*; 30 import sun.jvm.hotspot.debugger.*; 31 import sun.jvm.hotspot.debugger.cdbg.*; 32 import sun.jvm.hotspot.bugspot.tree.*; 33 import sun.jvm.hotspot.oops.*; 34 import sun.jvm.hotspot.runtime.*; 35 import sun.jvm.hotspot.ui.tree.*; 36 import sun.jvm.hotspot.ui.treetable.*; 37 38 /** Manages display of a set of local variables in a frame, or the 39 contents of the "this" pointer */ 40 41 public class VariablePanel extends JPanel { 42 private JTreeTable treeTable; 43 private SimpleTreeTableModel model; 44 private SimpleTreeGroupNode root; 45 46 public VariablePanel() { 47 super(); 48 49 model = new SimpleTreeTableModel(); 50 model.setValuesEditable(false); 51 root = new SimpleTreeGroupNode(); 52 model.setRoot(root); 53 treeTable = new JTreeTable(model); 54 treeTable.setRootVisible(false); 55 treeTable.setShowsRootHandles(true); 56 treeTable.setShowsIcons(false); 57 treeTable.setTreeEditable(false); 58 treeTable.getTableHeader().setReorderingAllowed(false); 59 treeTable.setCellSelectionEnabled(true); 60 treeTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); 61 treeTable.setDragEnabled(true); 62 JScrollPane sp = new JScrollPane(treeTable); 63 sp.getViewport().setBackground(Color.white); 64 65 setLayout(new BorderLayout()); 66 add(sp, BorderLayout.CENTER); 67 } 68 69 /** Clear the contents of this VariablePanel */ 70 public void clear() { 71 root.removeAllChildren(); 72 model.fireTreeStructureChanged(); 73 } 74 75 /** Update the contents of this VariablePanel from the given CFrame */ 76 public void update(CFrame fr) { 77 // Collect locals 78 CCollector coll = new CCollector(); 79 fr.iterateLocals(coll); 80 update(coll); 81 } 82 83 /** Update the contents of this VariablePanel from the given JavaVFrame */ 84 public void update(JavaVFrame jfr) { 85 Method m = jfr.getMethod(); 86 if (!m.hasLocalVariableTable()) { 87 return; 88 } 89 int bci = jfr.getBCI(); 90 // Get local variable table 91 LocalVariableTableElement[] locals = m.getLocalVariableTable(); 92 // Get locals as StackValueCollection 93 StackValueCollection coll = jfr.getLocals(); 94 root.removeAllChildren(); 95 // See which locals are live 96 for (int i = 0; i < locals.length; i++) { 97 LocalVariableTableElement local = locals[i]; 98 if (local.getStartBCI() <= bci && bci < local.getStartBCI() + local.getLength()) { 99 // Valid; add it 100 SimpleTreeNode node = null; 101 Symbol name = null; 102 try { 103 name = m.getConstants().getSymbolAt(local.getNameCPIndex()); 104 if (name == null) { 105 System.err.println("Null name at slot " + 106 local.getNameCPIndex() + 107 " for local variable at slot " + 108 local.getSlot()); 109 continue; 110 } 111 } catch (Exception e) { 112 System.err.println("Unable to fetch name at slot " + 113 local.getNameCPIndex() + 114 " for local variable at slot " + 115 local.getSlot()); 116 e.printStackTrace(); 117 continue; 118 } 119 sun.jvm.hotspot.oops.NamedFieldIdentifier f = 120 new sun.jvm.hotspot.oops.NamedFieldIdentifier(name.asString()); 121 Symbol descriptor = null; 122 try { 123 descriptor = m.getConstants().getSymbolAt(local.getDescriptorCPIndex()); 124 } catch (Exception e) { 125 System.err.println("Unable to fetch descriptor at slot " + 126 local.getDescriptorCPIndex() + 127 " for local variable " + f.getName() + 128 " at slot " + local.getSlot()); 129 e.printStackTrace(); 130 continue; 131 } 132 133 if (descriptor != null) { 134 switch (descriptor.getByteAt(0)) { 135 case 'F': { 136 node = new sun.jvm.hotspot.ui.tree.FloatTreeNodeAdapter(coll.floatAt(local.getSlot()), f, true); 137 break; 138 } 139 case 'D': { 140 node = new sun.jvm.hotspot.ui.tree.DoubleTreeNodeAdapter(coll.doubleAt(local.getSlot()), f, true); 141 break; 142 } 143 case 'C': { 144 node = new sun.jvm.hotspot.ui.tree.CharTreeNodeAdapter((char) coll.intAt(local.getSlot()), f, true); 145 break; 146 } 147 case 'B': 148 case 'S': 149 case 'I': { 150 node = new sun.jvm.hotspot.ui.tree.LongTreeNodeAdapter(coll.intAt(local.getSlot()), f, true); 151 break; 152 } 153 case 'Z': { 154 node = new sun.jvm.hotspot.ui.tree.BooleanTreeNodeAdapter( 155 ((coll.intAt(local.getSlot()) != 0) ? true : false), f, true 156 ); 157 break; 158 } 159 case 'J': { 160 node = new sun.jvm.hotspot.ui.tree.LongTreeNodeAdapter(coll.longAt(local.getSlot()), f, true); 161 break; 162 } 163 default: { 164 try { 165 node = new sun.jvm.hotspot.ui.tree.OopTreeNodeAdapter( 166 VM.getVM().getObjectHeap().newOop(coll.oopHandleAt(local.getSlot())), f, true 167 ); 168 } catch (AddressException e) { 169 node = new sun.jvm.hotspot.ui.tree.FieldTreeNodeAdapter(f, true) { 170 public int getChildCount() { return 0; } 171 public SimpleTreeNode getChild(int i) { return null; } 172 public boolean isLeaf() { return false; } 173 public int getIndexOfChild(SimpleTreeNode child) { return 0; } 174 public String getValue() { 175 return "<Bad oop>"; 176 } 177 }; 178 } 179 break; 180 } 181 } 182 if (node != null) { 183 root.addChild(node); 184 } 185 } 186 } 187 } 188 189 model.fireTreeStructureChanged(); 190 } 191 192 /** Update the contents of this VariablePanel from the given "this" 193 pointer of the given type */ 194 public void update(Address thisAddr, Type type) { 195 // Collect fields 196 CCollector coll = new CCollector(); 197 type.iterateObject(thisAddr, coll); 198 update(coll); 199 } 200 201 private void update(CCollector coll) { 202 root.removeAllChildren(); 203 for (int i = 0; i < coll.getNumChildren(); i++) { 204 root.addChild(coll.getChild(i)); 205 } 206 model.fireTreeStructureChanged(); 207 } 208 209 static class CCollector extends DefaultObjectVisitor { 210 private java.util.List children; 211 212 public CCollector() { 213 children = new ArrayList(); 214 } 215 216 public int getNumChildren() { 217 return children.size(); 218 } 219 220 public SimpleTreeNode getChild(int i) { 221 return (SimpleTreeNode) children.get(i); 222 } 223 224 public void doBit(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, long val) { 225 children.add(new sun.jvm.hotspot.bugspot.tree.LongTreeNodeAdapter(val, f, true)); 226 } 227 public void doInt(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, long val) { 228 children.add(new sun.jvm.hotspot.bugspot.tree.LongTreeNodeAdapter(val, f, true)); 229 } 230 public void doEnum(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, long val, String enumName) { 231 children.add(new sun.jvm.hotspot.bugspot.tree.EnumTreeNodeAdapter(enumName, val, f, true)); 232 } 233 public void doFloat(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, float val) { 234 children.add(new sun.jvm.hotspot.bugspot.tree.FloatTreeNodeAdapter(val, f, true)); 235 } 236 public void doDouble(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, double val) { 237 children.add(new sun.jvm.hotspot.bugspot.tree.DoubleTreeNodeAdapter(val, f, true)); 238 } 239 public void doPointer(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) { 240 children.add(new sun.jvm.hotspot.bugspot.tree.AddressTreeNodeAdapter(val, f, true)); 241 } 242 public void doArray(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) { 243 children.add(new sun.jvm.hotspot.bugspot.tree.AddressTreeNodeAdapter(val, f, true)); 244 } 245 public void doRef(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) { 246 children.add(new sun.jvm.hotspot.bugspot.tree.AddressTreeNodeAdapter(val, f, true)); 247 } 248 public void doCompound(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) { 249 children.add(new sun.jvm.hotspot.bugspot.tree.ObjectTreeNodeAdapter(val, f, true)); 250 } 251 } 252 }