0
|
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.tree;
|
|
26
|
|
27 import java.io.*;
|
|
28 import sun.jvm.hotspot.oops.*;
|
|
29 import sun.jvm.hotspot.debugger.*;
|
|
30 import sun.jvm.hotspot.runtime.*;
|
|
31
|
|
32 /** An adapter class which allows oops to be displayed in a tree via
|
|
33 the SimpleTreeNode interface. FIXME: must attach this to some sort
|
|
34 of policy object which determines how to display names and whether
|
|
35 VM fields should be shown. (Must also fix oop visitation mechanism
|
|
36 in oops package.) */
|
|
37
|
|
38 public class OopTreeNodeAdapter extends FieldTreeNodeAdapter {
|
|
39 private Oop oop;
|
|
40
|
|
41 /** The oop may be null (for oop fields of oops which are null); the
|
|
42 FieldIdentifier may also be null (for the root node).
|
|
43 treeTableMode defaults to false. */
|
|
44 public OopTreeNodeAdapter(Oop oop, FieldIdentifier id) {
|
|
45 this(oop, id, false);
|
|
46 }
|
|
47
|
|
48 /** The oop may be null (for oop fields of oops which are null); the
|
|
49 FieldIdentifier may also be null (for the root node). */
|
|
50 public OopTreeNodeAdapter(Oop oop, FieldIdentifier id, boolean treeTableMode) {
|
|
51 super(id, treeTableMode);
|
|
52 this.oop = oop;
|
|
53 }
|
|
54
|
|
55 public Oop getOop() {
|
|
56 return oop;
|
|
57 }
|
|
58
|
|
59 public int getChildCount() {
|
|
60 if (oop == null) {
|
|
61 return 0;
|
|
62 }
|
|
63
|
|
64 Counter c = new Counter();
|
|
65 oop.iterate(c, true);
|
|
66 return c.getNumFields() + (VM.getVM().getRevPtrs() == null ? 0 : 1);
|
|
67 }
|
|
68
|
|
69 public SimpleTreeNode getChild(int index) {
|
|
70 if (oop == null) {
|
|
71 return null;
|
|
72 }
|
|
73 if (VM.getVM().getRevPtrs() != null) {
|
|
74 if (index == 0) {
|
|
75 return new RevPtrsTreeNodeAdapter(oop, getTreeTableMode());
|
|
76 } else {
|
|
77 index -= 1;
|
|
78 }
|
|
79 }
|
|
80
|
|
81 Fetcher f = new Fetcher(index);
|
|
82 oop.iterate(f, true);
|
|
83 return f.getChild();
|
|
84 }
|
|
85
|
|
86 public boolean isLeaf() {
|
|
87 return (oop == null);
|
|
88 }
|
|
89
|
|
90 public int getIndexOfChild(SimpleTreeNode child) {
|
|
91 if (child instanceof RevPtrsTreeNodeAdapter) {
|
|
92 // assert(VM.getVM().getRevPtrs() != null, "Only created from revptrs");
|
|
93 return 0;
|
|
94 }
|
|
95 FieldIdentifier id = ((FieldTreeNodeAdapter) child).getID();
|
|
96 Finder f = new Finder(id);
|
|
97 oop.iterate(f, true);
|
|
98 return f.getIndex() + (VM.getVM().getRevPtrs() == null ? 0 : 1);
|
|
99 }
|
|
100
|
|
101 public String getValue() {
|
|
102 if (oop != null) {
|
|
103 // FIXME: choose style of printing depending on whether we're
|
|
104 // displaying VM fields? Want to make Java objects look like
|
|
105 // Java objects.
|
|
106 ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
|
107 Oop.printOopValueOn(oop, new PrintStream(bos));
|
|
108 return bos.toString();
|
|
109 }
|
|
110 return "null";
|
|
111 }
|
|
112
|
|
113 /** Should be applied to one oop at a time, then have the number of
|
|
114 fields fetched. FIXME: want this to distinguish between VM and
|
|
115 non-VM fields. */
|
|
116 static class Counter extends DefaultOopVisitor {
|
|
117 private int numFields;
|
|
118
|
|
119 public int getNumFields() {
|
|
120 return numFields;
|
|
121 }
|
|
122
|
|
123 public void prologue() {
|
|
124 numFields = 0;
|
|
125 }
|
|
126
|
|
127 public void doOop(OopField field, boolean isVMField) { ++numFields; }
|
|
128 public void doByte(ByteField field, boolean isVMField) { ++numFields; }
|
|
129 public void doChar(CharField field, boolean isVMField) { ++numFields; }
|
|
130 public void doBoolean(BooleanField field, boolean isVMField) { ++numFields; }
|
|
131 public void doShort(ShortField field, boolean isVMField) { ++numFields; }
|
|
132 public void doInt(IntField field, boolean isVMField) { ++numFields; }
|
|
133 public void doLong(LongField field, boolean isVMField) { ++numFields; }
|
|
134 public void doFloat(FloatField field, boolean isVMField) { ++numFields; }
|
|
135 public void doDouble(DoubleField field, boolean isVMField) { ++numFields; }
|
|
136 public void doCInt(CIntField field, boolean isVMField) { ++numFields; }
|
|
137 }
|
|
138
|
|
139 /** Creates a new SimpleTreeNode for the given field. FIXME: want
|
|
140 this to distinguish between VM and non-VM fields. */
|
|
141 class Fetcher extends DefaultOopVisitor {
|
|
142 private int index;
|
|
143 private int curField;
|
|
144 private SimpleTreeNode child;
|
|
145
|
|
146 public Fetcher(int index) {
|
|
147 this.index = index;
|
|
148 }
|
|
149
|
|
150 public SimpleTreeNode getChild() {
|
|
151 return child;
|
|
152 }
|
|
153
|
|
154 public void prologue() {
|
|
155 curField = 0;
|
|
156 }
|
|
157
|
|
158 public void doOop(OopField field, boolean isVMField) {
|
|
159 if (curField == index) {
|
|
160 try {
|
|
161 child = new OopTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode());
|
|
162 } catch (AddressException e) {
|
|
163 child = new BadOopTreeNodeAdapter(field.getValueAsOopHandle(getObj()), field.getID(), getTreeTableMode());
|
|
164 }
|
|
165 }
|
|
166 ++curField;
|
|
167 }
|
|
168
|
|
169 public void doByte(ByteField field, boolean isVMField) {
|
|
170 if (curField == index) {
|
|
171 child = new LongTreeNodeAdapter(field.getValue(getObj()) & 0xFF, field.getID(), getTreeTableMode());
|
|
172 }
|
|
173 ++curField;
|
|
174 }
|
|
175
|
|
176 public void doChar(CharField field, boolean isVMField) {
|
|
177 if (curField == index) {
|
|
178 child = new CharTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode());
|
|
179 }
|
|
180 ++curField;
|
|
181 }
|
|
182
|
|
183 public void doBoolean(BooleanField field, boolean isVMField) {
|
|
184 if (curField == index) {
|
|
185 child = new BooleanTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode());
|
|
186 }
|
|
187 ++curField;
|
|
188 }
|
|
189
|
|
190 public void doShort(ShortField field, boolean isVMField) {
|
|
191 if (curField == index) {
|
|
192 child = new LongTreeNodeAdapter(field.getValue(getObj()) & 0xFFFF, field.getID(), getTreeTableMode());
|
|
193 }
|
|
194 ++curField;
|
|
195 }
|
|
196
|
|
197 public void doInt(IntField field, boolean isVMField) {
|
|
198 if (curField == index) {
|
|
199 child = new LongTreeNodeAdapter(field.getValue(getObj()) & 0xFFFFFFFF, field.getID(), getTreeTableMode());
|
|
200 }
|
|
201 ++curField;
|
|
202 }
|
|
203
|
|
204 public void doLong(LongField field, boolean isVMField) {
|
|
205 if (curField == index) {
|
|
206 child = new LongTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode());
|
|
207 }
|
|
208 ++curField;
|
|
209 }
|
|
210
|
|
211 public void doFloat(FloatField field, boolean isVMField) {
|
|
212 if (curField == index) {
|
|
213 child = new FloatTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode());
|
|
214 }
|
|
215 ++curField;
|
|
216 }
|
|
217
|
|
218 public void doDouble(DoubleField field, boolean isVMField) {
|
|
219 if (curField == index) {
|
|
220 child = new DoubleTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode());
|
|
221 }
|
|
222 ++curField;
|
|
223 }
|
|
224
|
|
225 public void doCInt(CIntField field, boolean isVMField) {
|
|
226 if (curField == index) {
|
|
227 child = new LongTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode());
|
|
228 }
|
|
229 ++curField;
|
|
230 }
|
|
231 }
|
|
232
|
|
233 /** Finds the index of the given FieldIdentifier. */
|
|
234 static class Finder extends DefaultOopVisitor {
|
|
235 private FieldIdentifier id;
|
|
236 private int curField;
|
|
237 private int index;
|
|
238
|
|
239 public Finder(FieldIdentifier id) {
|
|
240 this.id = id;
|
|
241 }
|
|
242
|
|
243 /** Returns -1 if not found */
|
|
244 public int getIndex() {
|
|
245 return index;
|
|
246 }
|
|
247
|
|
248 public void prologue() {
|
|
249 curField = 0;
|
|
250 index = -1;
|
|
251 }
|
|
252
|
|
253 public void doOop(OopField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; }
|
|
254 public void doByte(ByteField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; }
|
|
255 public void doChar(CharField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; }
|
|
256 public void doBoolean(BooleanField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; }
|
|
257 public void doShort(ShortField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; }
|
|
258 public void doInt(IntField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; }
|
|
259 public void doLong(LongField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; }
|
|
260 public void doFloat(FloatField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; }
|
|
261 public void doDouble(DoubleField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; }
|
|
262 public void doCInt(CIntField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; }
|
|
263 }
|
|
264 }
|