1 /* 2 * Copyright (c) 2001, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, 20 * CA 94065 USA or visit www.oracle.com if you need additional information or 21 * have any questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.bugspot.tree; 26 27 import java.io.*; 28 import sun.jvm.hotspot.debugger.*; 29 import sun.jvm.hotspot.debugger.cdbg.*; 30 import sun.jvm.hotspot.ui.tree.SimpleTreeNode; 31 32 /** An adapter class which allows C/C++ objects to be displayed in a 33 tree via the SimpleTreeNode interface. */ 34 35 public class ObjectTreeNodeAdapter extends FieldTreeNodeAdapter { 36 // Address of object 37 private Address addr; 38 39 /** The address may be null (for object fields of objcets which are 40 null). The FieldIdentifier should not be null. treeTableMode 41 defaults to false. */ 42 public ObjectTreeNodeAdapter(Address addr, FieldIdentifier id) { 43 this(addr, id, false); 44 } 45 46 /** The address may be null (for object fields of objcets which are 47 null). The FieldIdentifier should not be null. */ 48 public ObjectTreeNodeAdapter(Address addr, FieldIdentifier id, boolean treeTableMode) { 49 super(id, treeTableMode); 50 this.addr = addr; 51 } 52 53 public int getChildCount() { 54 if (addr == null) { 55 return 0; 56 } 57 58 Counter c = new Counter(); 59 getType().iterateObject(addr, c); 60 return c.getNumFields(); 61 } 62 63 public SimpleTreeNode getChild(int index) { 64 if (addr == null) { 65 return null; 66 } 67 68 Fetcher f = new Fetcher(index); 69 getType().iterateObject(addr, f); 70 return f.getChild(); 71 } 72 73 public boolean isLeaf() { 74 return (addr == null); 75 } 76 77 public int getIndexOfChild(SimpleTreeNode child) { 78 FieldIdentifier id = ((FieldTreeNodeAdapter) child).getID(); 79 Finder f = new Finder(id); 80 getType().iterateObject(addr, f); 81 return f.getIndex(); 82 } 83 84 public String getValue() { 85 if (addr != null) { 86 return addr.toString(); 87 } 88 return "NULL"; 89 } 90 91 /** Should be used only once, then have the number of fields 92 fetched. */ 93 static class Counter extends DefaultObjectVisitor { 94 private int numFields; 95 96 public int getNumFields() { 97 return numFields; 98 } 99 100 public void doBit(FieldIdentifier f, long val) { ++numFields; } 101 public void doInt(FieldIdentifier f, long val) { ++numFields; } 102 public void doEnum(FieldIdentifier f, long val, String enumName) { ++numFields; } 103 public void doFloat(FieldIdentifier f, float val) { ++numFields; } 104 public void doDouble(FieldIdentifier f, double val) { ++numFields; } 105 public void doPointer(FieldIdentifier f, Address val) { ++numFields; } 106 public void doArray(FieldIdentifier f, Address val) { ++numFields; } 107 public void doRef(FieldIdentifier f, Address val) { ++numFields; } 108 public void doCompound(FieldIdentifier f, Address addr) { ++numFields; } 109 } 110 111 /** Creates a new SimpleTreeNode for the given field. */ 112 class Fetcher extends DefaultObjectVisitor { 113 private int index; 114 private int curField; 115 private SimpleTreeNode child; 116 117 public Fetcher(int index) { 118 this.index = index; 119 } 120 121 public SimpleTreeNode getChild() { 122 return child; 123 } 124 125 public void doBit(FieldIdentifier f, long val) { 126 if (curField == index) { 127 child = new LongTreeNodeAdapter(val, f, getTreeTableMode()); 128 } 129 ++curField; 130 } 131 132 public void doInt(FieldIdentifier f, long val) { 133 if (curField == index) { 134 child = new LongTreeNodeAdapter(val, f, getTreeTableMode()); 135 } 136 ++curField; 137 } 138 139 public void doEnum(FieldIdentifier f, long val, String enumName) { 140 if (curField == index) { 141 child = new EnumTreeNodeAdapter(enumName, val, f, getTreeTableMode()); 142 } 143 ++curField; 144 } 145 146 public void doFloat(FieldIdentifier f, float val) { 147 if (curField == index) { 148 child = new FloatTreeNodeAdapter(val, f, getTreeTableMode()); 149 } 150 ++curField; 151 } 152 153 public void doDouble(FieldIdentifier f, double val) { 154 if (curField == index) { 155 child = new DoubleTreeNodeAdapter(val, f, getTreeTableMode()); 156 } 157 ++curField; 158 } 159 160 public void doPointer(FieldIdentifier f, Address val) { 161 if (curField == index) { 162 child = new AddressTreeNodeAdapter(val, f, getTreeTableMode()); 163 } 164 ++curField; 165 } 166 167 public void doArray(FieldIdentifier f, Address val) { 168 if (curField == index) { 169 child = new AddressTreeNodeAdapter(val, f, getTreeTableMode()); 170 } 171 ++curField; 172 } 173 174 public void doRef(FieldIdentifier f, Address val) { 175 if (curField == index) { 176 child = new AddressTreeNodeAdapter(val, f, getTreeTableMode()); 177 } 178 ++curField; 179 } 180 181 public void doCompound(FieldIdentifier f, Address val) { 182 if (curField == index) { 183 child = new ObjectTreeNodeAdapter(val, f, getTreeTableMode()); 184 } 185 ++curField; 186 } 187 } 188 189 /** Finds the index of the given FieldIdentifier. */ 190 static class Finder extends DefaultObjectVisitor { 191 private FieldIdentifier id; 192 private int curField; 193 private int index = -1; 194 195 public Finder(FieldIdentifier id) { 196 this.id = id; 197 } 198 199 /** Returns -1 if not found */ 200 public int getIndex() { 201 return index; 202 } 203 204 public void doBit(FieldIdentifier f, long val) { if (f.equals(id)) { index = curField; } ++curField; } 205 public void doInt(FieldIdentifier f, long val) { if (f.equals(id)) { index = curField; } ++curField; } 206 public void doEnum(FieldIdentifier f, long val, 207 String enumName) { if (f.equals(id)) { index = curField; } ++curField; } 208 public void doFloat(FieldIdentifier f, float val) { if (f.equals(id)) { index = curField; } ++curField; } 209 public void doDouble(FieldIdentifier f, double val) { if (f.equals(id)) { index = curField; } ++curField; } 210 public void doPointer(FieldIdentifier f, Address val) { if (f.equals(id)) { index = curField; } ++curField; } 211 public void doArray(FieldIdentifier f, Address val) { if (f.equals(id)) { index = curField; } ++curField; } 212 public void doRef(FieldIdentifier f, Address val) { if (f.equals(id)) { index = curField; } ++curField; } 213 public void doCompound(FieldIdentifier f, 214 Address val) { if (f.equals(id)) { index = curField; } ++curField; } 215 } 216 }