Mercurial > hg > graal-jvmci-8
diff agent/src/share/classes/sun/jvm/hotspot/ui/tree/MetadataTreeNodeAdapter.java @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/src/share/classes/sun/jvm/hotspot/ui/tree/MetadataTreeNodeAdapter.java Sat Sep 01 13:25:18 2012 -0400 @@ -0,0 +1,274 @@ +/* + * Copyright (c) 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.io.*; +import sun.jvm.hotspot.oops.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; + +/** An adapter class which allows oops to be displayed in a tree via + the SimpleTreeNode interface. FIXME: must attach this to some sort + of policy object which determines how to display names and whether + VM fields should be shown. (Must also fix oop visitation mechanism + in oops package.) */ + +public class MetadataTreeNodeAdapter extends FieldTreeNodeAdapter { + private Metadata metadata; + + /** The metadata may be null (for metadata fields of metadatas which are null); the + FieldIdentifier may also be null (for the root node). + treeTableMode defaults to false. */ + public MetadataTreeNodeAdapter(Metadata metadata, FieldIdentifier id) { + this(metadata, id, false); + } + + /** The metadata may be null (for metadata fields of metadatas which are null); the + FieldIdentifier may also be null (for the root node). */ + public MetadataTreeNodeAdapter(Metadata metadata, FieldIdentifier id, boolean treeTableMode) { + super(id, treeTableMode); + this.metadata = metadata; + } + + public Metadata getMetadata() { + return metadata; + } + + public int getChildCount() { + if (metadata == null) { + return 0; + } + + Counter c = new Counter(); + metadata.iterate(c); + return c.getNumFields() + (VM.getVM().getRevPtrs() == null ? 0 : 1); + } + + public SimpleTreeNode getChild(int index) { + if (metadata == null) { + return null; + } + + Fetcher f = new Fetcher(index); + metadata.iterate(f); + return f.getChild(); + } + + public boolean isLeaf() { + return (metadata == null); + } + + public int getIndexOfChild(SimpleTreeNode child) { + if (child instanceof RevPtrsTreeNodeAdapter) { + // assert(VM.getVM().getRevPtrs() != null, "Only created from revptrs"); + return 0; + } + FieldIdentifier id = ((FieldTreeNodeAdapter) child).getID(); + Finder f = new Finder(id); + metadata.iterate(f); + return f.getIndex() + (VM.getVM().getRevPtrs() == null ? 0 : 1); + } + + public String getValue() { + if (metadata != null) { + // FIXME: choose style of printing depending on whether we're + // displaying VM fields? Want to make Java objects look like + // Java objects. + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + metadata.printValueOn(new PrintStream(bos)); + return bos.toString(); + } + return "null"; + } + + /** Should be applied to one metadata at a time, then have the number of + fields fetched. FIXME: want this to distinguish between VM and + non-VM fields. */ + static class Counter extends DefaultMetadataVisitor { + private int numFields; + + public int getNumFields() { + return numFields; + } + + public void prologue() { + numFields = 0; + } + + public void doMetadata(MetadataField field, boolean isVMField) { ++numFields; } + public void doOop(OopField field, boolean isVMField) { ++numFields; } + public void doByte(ByteField field, boolean isVMField) { ++numFields; } + public void doChar(CharField field, boolean isVMField) { ++numFields; } + public void doBoolean(BooleanField field, boolean isVMField) { ++numFields; } + public void doShort(ShortField field, boolean isVMField) { ++numFields; } + public void doInt(IntField field, boolean isVMField) { ++numFields; } + public void doLong(LongField field, boolean isVMField) { ++numFields; } + public void doFloat(FloatField field, boolean isVMField) { ++numFields; } + public void doDouble(DoubleField field, boolean isVMField) { ++numFields; } + public void doCInt(CIntField field, boolean isVMField) { ++numFields; } + } + + /** Creates a new SimpleTreeNode for the given field. FIXME: want + this to distinguish between VM and non-VM fields. */ + class Fetcher extends DefaultMetadataVisitor { + private int index; + private int curField; + private SimpleTreeNode child; + + public Fetcher(int index) { + this.index = index; + } + + public SimpleTreeNode getChild() { + return child; + } + + public void prologue() { + curField = 0; + } + + public void doMetadata(MetadataField field, boolean isVMField) { + if (curField == index) { + try { + child = new MetadataTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode()); + } catch (AddressException e) { + child = new BadAddressTreeNodeAdapter(getObj().getAddress().getAddressAt(field.getOffset()), field, getTreeTableMode()); + } catch (UnknownOopException e) { + child = new BadAddressTreeNodeAdapter(getObj().getAddress().getAddressAt(field.getOffset()), field, getTreeTableMode()); + } + } + ++curField; + } + + public void doOop(OopField field, boolean isVMField) { + if (curField == index) { + try { + child = new OopTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode()); + } catch (AddressException e) { + child = new BadAddressTreeNodeAdapter(field.getValueAsOopHandle(getObj()), field, getTreeTableMode()); + } catch (UnknownOopException e) { + child = new BadAddressTreeNodeAdapter(field.getValueAsOopHandle(getObj()), field, getTreeTableMode()); + } + } + ++curField; + } + + public void doByte(ByteField field, boolean isVMField) { + if (curField == index) { + child = new LongTreeNodeAdapter(field.getValue(getObj()) & 0xFF, field.getID(), getTreeTableMode()); + } + ++curField; + } + + public void doChar(CharField field, boolean isVMField) { + if (curField == index) { + child = new CharTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode()); + } + ++curField; + } + + public void doBoolean(BooleanField field, boolean isVMField) { + if (curField == index) { + child = new BooleanTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode()); + } + ++curField; + } + + public void doShort(ShortField field, boolean isVMField) { + if (curField == index) { + child = new LongTreeNodeAdapter(field.getValue(getObj()) & 0xFFFF, field.getID(), getTreeTableMode()); + } + ++curField; + } + + public void doInt(IntField field, boolean isVMField) { + if (curField == index) { + child = new LongTreeNodeAdapter(field.getValue(getObj()) & 0xFFFFFFFF, field.getID(), getTreeTableMode()); + } + ++curField; + } + + public void doLong(LongField field, boolean isVMField) { + if (curField == index) { + child = new LongTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode()); + } + ++curField; + } + + public void doFloat(FloatField field, boolean isVMField) { + if (curField == index) { + child = new FloatTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode()); + } + ++curField; + } + + public void doDouble(DoubleField field, boolean isVMField) { + if (curField == index) { + child = new DoubleTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode()); + } + ++curField; + } + + public void doCInt(CIntField field, boolean isVMField) { + if (curField == index) { + child = new LongTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode()); + } + ++curField; + } + } + + /** Finds the index of the given FieldIdentifier. */ + static class Finder extends DefaultMetadataVisitor { + private FieldIdentifier id; + private int curField; + private int index; + + public Finder(FieldIdentifier id) { + this.id = id; + } + + /** Returns -1 if not found */ + public int getIndex() { + return index; + } + + public void prologue() { + curField = 0; + index = -1; + } + + public void doMetadata(MetadataField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; } + public void doOop(OopField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; } + public void doByte(ByteField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; } + public void doChar(CharField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; } + public void doBoolean(BooleanField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; } + public void doShort(ShortField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; } + public void doInt(IntField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; } + public void doLong(LongField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; } + public void doFloat(FloatField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; } + public void doDouble(DoubleField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; } + public void doCInt(CIntField field, boolean isVMField) { if (field.getID().equals(id)) { index = curField; } ++curField; } + } +}