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 25package sun.jvm.hotspot.ui.tree; 26 27import java.util.*; 28import sun.jvm.hotspot.oops.FieldIdentifier; 29import sun.jvm.hotspot.oops.Oop; 30import sun.jvm.hotspot.oops.UnknownOopException; 31import sun.jvm.hotspot.debugger.*; 32import sun.jvm.hotspot.runtime.*; 33import sun.jvm.hotspot.types.*; 34import sun.jvm.hotspot.utilities.CStringUtilities; 35 36/** Encapsulates an arbitrary type value in a tree handled by SimpleTreeModel */ 37 38public 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} 233