/* * 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>"; } } }