View Javadoc
1   /*
2    * Copyright (c) 2004, 2012, 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, CA 94065 USA
20   * or visit www.oracle.com if you need additional information or have any
21   * questions.
22   *
23   */
24  
25  package sun.jvm.hotspot.ui.tree;
26  
27  import java.util.*;
28  import sun.jvm.hotspot.oops.FieldIdentifier;
29  import sun.jvm.hotspot.oops.Oop;
30  import sun.jvm.hotspot.oops.UnknownOopException;
31  import sun.jvm.hotspot.debugger.*;
32  import sun.jvm.hotspot.runtime.*;
33  import sun.jvm.hotspot.types.*;
34  import sun.jvm.hotspot.utilities.CStringUtilities;
35  
36  /** Encapsulates an arbitrary type value in a tree handled by SimpleTreeModel */
37  
38  public class CTypeTreeNodeAdapter extends FieldTreeNodeAdapter {
39    final private Address addr;
40    final private Type type;
41    private CTypeFieldIdentifier[] fields = null;
42  
43    private void collectFields(Type type, ArrayList list, boolean statics, boolean recurse) {
44      Type supertype = type.getSuperclass();
45      if (supertype != null && recurse) {
46        collectFields(supertype, list, statics, recurse);
47      }
48      Iterator i = type.getFields();
49      while (i.hasNext()) {
50        Field f = (Field) i.next();
51        if (f.isStatic() == statics) {
52          list.add(new CTypeFieldIdentifier(type, f));
53        }
54      }
55    }
56  
57  
58    private CTypeFieldIdentifier[] getFields() {
59      if (fields == null) {
60        ArrayList f = new ArrayList();
61        collectFields(type, f, false, true);
62        fields = (CTypeFieldIdentifier[]) f.toArray(new CTypeFieldIdentifier[0]);
63      }
64      return fields;
65    }
66  
67    static class CTypeFieldIdentifier extends FieldIdentifier {
68      final private Field field;
69      final private Type holder;
70  
71      CTypeFieldIdentifier(Type t, Field f) {
72        holder = t;
73        field = f;
74      }
75  
76      public Field getField() {
77        return field;
78      }
79  
80      public String getName() {
81        return field.getType().getName() + " " + holder.getName() + "::" + field.getName();
82      }
83    }
84  
85  
86    public CTypeTreeNodeAdapter(Address a, Type t, FieldIdentifier id) {
87      this(a, t, id, false);
88    }
89  
90    public CTypeTreeNodeAdapter(Address a, Type t, FieldIdentifier id, boolean treeTableMode) {
91      super(id, treeTableMode);
92      type = t;
93      addr = a;
94    }
95  
96    public CTypeTreeNodeAdapter(Type t) {
97      super(null, false);
98      type = t;
99      addr = null;
100     ArrayList statics = new ArrayList();
101     collectFields(type, statics, true, false);
102     fields = (CTypeFieldIdentifier[])statics.toArray(new CTypeFieldIdentifier[0]);
103   }
104 
105   public CTypeTreeNodeAdapter(Iterator types) {
106     super(null, false);
107     addr = null;
108     type = null;
109     ArrayList statics = new ArrayList();
110     while (types.hasNext()) {
111       collectFields((Type)types.next(), statics, true, false);
112     }
113     fields = (CTypeFieldIdentifier[])statics.toArray(new CTypeFieldIdentifier[0]);
114   }
115 
116   public int getChildCount() {
117     return getFields().length;
118   }
119 
120   public SimpleTreeNode getChild(int index) {
121     CTypeFieldIdentifier cf = getFields()[index];
122     Field f = cf.getField();
123     Type t = f.getType();
124     try {
125       if (t.isOopType()) {
126         OopHandle handle;
127         if (f.isStatic()) {
128           handle = f.getOopHandle();
129         } else {
130           handle = f.getOopHandle(addr);
131         }
132         try {
133           Oop oop = VM.getVM().getObjectHeap().newOop(handle);
134           return new OopTreeNodeAdapter(oop, cf, getTreeTableMode());
135         } catch (AddressException e) {
136           return new BadAddressTreeNodeAdapter(handle,
137                                            new CTypeFieldIdentifier(type, f),
138                                            getTreeTableMode());
139         } catch (UnknownOopException e) {
140           return new BadAddressTreeNodeAdapter(handle,
141                                            new CTypeFieldIdentifier(type, f),
142                                            getTreeTableMode());
143         }
144       } else if (t.isCIntegerType()) {
145         long value = 0;
146         if (f.isStatic()) {
147           value = f.getCInteger((CIntegerType)t);
148         } else {
149           value = f.getCInteger(addr, (CIntegerType)t);
150         }
151         return new LongTreeNodeAdapter(value, cf, getTreeTableMode());
152       } else if (t.isJavaPrimitiveType()) {
153         boolean isStatic = f.isStatic();
154         if (f instanceof JByteField) {
155           long value = isStatic? f.getJByte() : f.getJByte(addr);
156           return new LongTreeNodeAdapter(value, cf, getTreeTableMode());
157         } else if (f instanceof JShortField) {
158           long value = isStatic? f.getJShort() : f.getJShort(addr);
159           return new LongTreeNodeAdapter(value, cf, getTreeTableMode());
160         } else if (f instanceof JIntField) {
161           long value = isStatic? f.getJInt() : f.getJInt(addr);
162           return new LongTreeNodeAdapter(value, cf, getTreeTableMode());
163         } else if (f instanceof JLongField) {
164           long value = isStatic? f.getJLong() : f.getJLong(addr);
165           return new LongTreeNodeAdapter(value, cf, getTreeTableMode());
166         } else if (f instanceof JCharField) {
167           char value = isStatic? f.getJChar() : f.getJChar(addr);
168           return new CharTreeNodeAdapter(value, cf, getTreeTableMode());
169         } else if (f instanceof JBooleanField) {
170           boolean value = isStatic? f.getJBoolean() : f.getJBoolean(addr);
171           return new BooleanTreeNodeAdapter(value, cf, getTreeTableMode());
172         } else if (f instanceof JFloatField) {
173           float value = isStatic? f.getJFloat() : f.getJFloat(addr);
174           return new DoubleTreeNodeAdapter(value, cf, getTreeTableMode());
175         } else if (f instanceof JDoubleField) {
176           double value = isStatic? f.getJDouble() : f.getJDouble(addr);
177           return new DoubleTreeNodeAdapter(value, cf, getTreeTableMode());
178         } else {
179           throw new RuntimeException("unhandled type: " + t.getName());
180         }
181       } else if (t.isPointerType()) {
182         Address ptr;
183         if (f.isStatic()) {
184           ptr = f.getAddress();
185         } else {
186           ptr = f.getAddress(addr);
187         }
188 
189         if (t.isCStringType()) {
190             return new CStringTreeNodeAdapter(CStringUtilities.getString(ptr), cf);
191         }
192 
193         return new CTypeTreeNodeAdapter(ptr, ((PointerType) t).getTargetType(), cf, getTreeTableMode());
194       } else {
195         if (f.isStatic()) {
196             return new CTypeTreeNodeAdapter(f.getStaticFieldAddress(), f.getType(),
197                                         cf, getTreeTableMode());
198         } else {
199             return new CTypeTreeNodeAdapter(addr.addOffsetTo(f.getOffset()), f.getType(),
200                                         cf, getTreeTableMode());
201         }
202       }
203     } catch (AddressException e) {
204       return new BadAddressTreeNodeAdapter(e.getAddress(),
205                                            new CTypeFieldIdentifier(type, f),
206                                            getTreeTableMode());
207     }
208   }
209 
210   public boolean isLeaf() {
211     return getFields().length == 0;
212   }
213 
214   public int getIndexOfChild(SimpleTreeNode child) {
215     CTypeFieldIdentifier id = (CTypeFieldIdentifier)((FieldTreeNodeAdapter) child).getID();
216     CTypeFieldIdentifier[] f = getFields();
217     for (int i = 0; i < f.length; i++) {
218       if (id == f[i]) {
219         return i;
220       }
221     }
222     return -1;
223   }
224 
225   public String getValue() {
226     if (type != null) {
227       return type.getName() + " @ " + addr;
228     } else {
229       return "<statics>";
230     }
231   }
232 }