0
|
1 /*
|
|
2 * Copyright 2001 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.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 }
|