| /* |
| * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| * |
| */ |
| |
| package sun.jvm.hotspot.ui.tree; |
| |
| import java.util.*; |
| import sun.jvm.hotspot.oops.FieldIdentifier; |
| import sun.jvm.hotspot.oops.Oop; |
| import sun.jvm.hotspot.oops.UnknownOopException; |
| import sun.jvm.hotspot.debugger.*; |
| import sun.jvm.hotspot.runtime.*; |
| import sun.jvm.hotspot.types.*; |
| import sun.jvm.hotspot.utilities.CStringUtilities; |
| |
| /** Encapsulates an arbitrary type value in a tree handled by SimpleTreeModel */ |
| |
| public class CTypeTreeNodeAdapter extends FieldTreeNodeAdapter { |
| final private Address addr; |
| final private Type type; |
| private CTypeFieldIdentifier[] fields = null; |
| |
| private void collectFields(Type type, ArrayList list, boolean statics, boolean recurse) { |
| Type supertype = type.getSuperclass(); |
| if (supertype != null && recurse) { |
| collectFields(supertype, list, statics, recurse); |
| } |
| Iterator i = type.getFields(); |
| while (i.hasNext()) { |
| Field f = (Field) i.next(); |
| if (f.isStatic() == statics) { |
| list.add(new CTypeFieldIdentifier(type, f)); |
| } |
| } |
| } |
| |
| |
| private CTypeFieldIdentifier[] getFields() { |
| if (fields == null) { |
| ArrayList f = new ArrayList(); |
| collectFields(type, f, false, true); |
| fields = (CTypeFieldIdentifier[]) f.toArray(new CTypeFieldIdentifier[0]); |
| } |
| return fields; |
| } |
| |
| static class CTypeFieldIdentifier extends FieldIdentifier { |
| final private Field field; |
| final private Type holder; |
| |
| CTypeFieldIdentifier(Type t, Field f) { |
| holder = t; |
| field = f; |
| } |
| |
| public Field getField() { |
| return field; |
| } |
| |
| public String getName() { |
| return field.getType().getName() + " " + holder.getName() + "::" + field.getName(); |
| } |
| } |
| |
| |
| public CTypeTreeNodeAdapter(Address a, Type t, FieldIdentifier id) { |
| this(a, t, id, false); |
| } |
| |
| public CTypeTreeNodeAdapter(Address a, Type t, FieldIdentifier id, boolean treeTableMode) { |
| super(id, treeTableMode); |
| type = t; |
| addr = a; |
| } |
| |
| public CTypeTreeNodeAdapter(Type t) { |
| super(null, false); |
| type = t; |
| addr = null; |
| ArrayList statics = new ArrayList(); |
| collectFields(type, statics, true, false); |
| fields = (CTypeFieldIdentifier[])statics.toArray(new CTypeFieldIdentifier[0]); |
| } |
| |
| public CTypeTreeNodeAdapter(Iterator types) { |
| super(null, false); |
| addr = null; |
| type = null; |
| ArrayList statics = new ArrayList(); |
| while (types.hasNext()) { |
| collectFields((Type)types.next(), statics, true, false); |
| } |
| fields = (CTypeFieldIdentifier[])statics.toArray(new CTypeFieldIdentifier[0]); |
| } |
| |
| public int getChildCount() { |
| return getFields().length; |
| } |
| |
| public SimpleTreeNode getChild(int index) { |
| CTypeFieldIdentifier cf = getFields()[index]; |
| Field f = cf.getField(); |
| Type t = f.getType(); |
| try { |
| if (t.isOopType()) { |
| OopHandle handle; |
| if (f.isStatic()) { |
| handle = f.getOopHandle(); |
| } else { |
| handle = f.getOopHandle(addr); |
| } |
| try { |
| Oop oop = VM.getVM().getObjectHeap().newOop(handle); |
| return new OopTreeNodeAdapter(oop, cf, getTreeTableMode()); |
| } catch (AddressException e) { |
| return new BadAddressTreeNodeAdapter(handle, |
| new CTypeFieldIdentifier(type, f), |
| getTreeTableMode()); |
| } catch (UnknownOopException e) { |
| return new BadAddressTreeNodeAdapter(handle, |
| new CTypeFieldIdentifier(type, f), |
| getTreeTableMode()); |
| } |
| } else if (t.isCIntegerType()) { |
| long value = 0; |
| if (f.isStatic()) { |
| value = f.getCInteger((CIntegerType)t); |
| } else { |
| value = f.getCInteger(addr, (CIntegerType)t); |
| } |
| return new LongTreeNodeAdapter(value, cf, getTreeTableMode()); |
| } else if (t.isJavaPrimitiveType()) { |
| boolean isStatic = f.isStatic(); |
| if (f instanceof JByteField) { |
| long value = isStatic? f.getJByte() : f.getJByte(addr); |
| return new LongTreeNodeAdapter(value, cf, getTreeTableMode()); |
| } else if (f instanceof JShortField) { |
| long value = isStatic? f.getJShort() : f.getJShort(addr); |
| return new LongTreeNodeAdapter(value, cf, getTreeTableMode()); |
| } else if (f instanceof JIntField) { |
| long value = isStatic? f.getJInt() : f.getJInt(addr); |
| return new LongTreeNodeAdapter(value, cf, getTreeTableMode()); |
| } else if (f instanceof JLongField) { |
| long value = isStatic? f.getJLong() : f.getJLong(addr); |
| return new LongTreeNodeAdapter(value, cf, getTreeTableMode()); |
| } else if (f instanceof JCharField) { |
| char value = isStatic? f.getJChar() : f.getJChar(addr); |
| return new CharTreeNodeAdapter(value, cf, getTreeTableMode()); |
| } else if (f instanceof JBooleanField) { |
| boolean value = isStatic? f.getJBoolean() : f.getJBoolean(addr); |
| return new BooleanTreeNodeAdapter(value, cf, getTreeTableMode()); |
| } else if (f instanceof JFloatField) { |
| float value = isStatic? f.getJFloat() : f.getJFloat(addr); |
| return new DoubleTreeNodeAdapter(value, cf, getTreeTableMode()); |
| } else if (f instanceof JDoubleField) { |
| double value = isStatic? f.getJDouble() : f.getJDouble(addr); |
| return new DoubleTreeNodeAdapter(value, cf, getTreeTableMode()); |
| } else { |
| throw new RuntimeException("unhandled type: " + t.getName()); |
| } |
| } else if (t.isPointerType()) { |
| Address ptr; |
| if (f.isStatic()) { |
| ptr = f.getAddress(); |
| } else { |
| ptr = f.getAddress(addr); |
| } |
| |
| if (t.isCStringType()) { |
| return new CStringTreeNodeAdapter(CStringUtilities.getString(ptr), cf); |
| } |
| |
| return new CTypeTreeNodeAdapter(ptr, ((PointerType) t).getTargetType(), cf, getTreeTableMode()); |
| } else { |
| if (f.isStatic()) { |
| return new CTypeTreeNodeAdapter(f.getStaticFieldAddress(), f.getType(), |
| cf, getTreeTableMode()); |
| } else { |
| return new CTypeTreeNodeAdapter(addr.addOffsetTo(f.getOffset()), f.getType(), |
| cf, getTreeTableMode()); |
| } |
| } |
| } catch (AddressException e) { |
| return new BadAddressTreeNodeAdapter(e.getAddress(), |
| new CTypeFieldIdentifier(type, f), |
| getTreeTableMode()); |
| } |
| } |
| |
| public boolean isLeaf() { |
| return getFields().length == 0; |
| } |
| |
| public int getIndexOfChild(SimpleTreeNode child) { |
| CTypeFieldIdentifier id = (CTypeFieldIdentifier)((FieldTreeNodeAdapter) child).getID(); |
| CTypeFieldIdentifier[] f = getFields(); |
| for (int i = 0; i < f.length; i++) { |
| if (id == f[i]) { |
| return i; |
| } |
| } |
| return -1; |
| } |
| |
| public String getValue() { |
| if (type != null) { |
| return type.getName() + " @ " + addr; |
| } else { |
| return "<statics>"; |
| } |
| } |
| } |