/* * Copyright (c) 2011, 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.opto; import java.io.*; import java.lang.reflect.Constructor; import java.util.*; import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.types.*; public class Node extends VMObject { static { VM.registerVMInitializedObserver(new Observer() { public void update(Observable o, Object data) { initialize(VM.getVM().getTypeDataBase()); } }); } private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { Type type = db.lookupType("Node"); outmaxField = new CIntField(type.getCIntegerField("_outmax"), 0); outcntField = new CIntField(type.getCIntegerField("_outcnt"), 0); maxField = new CIntField(type.getCIntegerField("_max"), 0); cntField = new CIntField(type.getCIntegerField("_cnt"), 0); idxField = new CIntField(type.getCIntegerField("_idx"), 0); outField = type.getAddressField("_out"); inField = type.getAddressField("_in"); nodeType = db.lookupType("Node"); virtualConstructor = new VirtualBaseConstructor(db, nodeType, "sun.jvm.hotspot.opto", Node.class); } private static CIntField outmaxField; private static CIntField outcntField; private static CIntField maxField; private static CIntField cntField; private static CIntField idxField; private static AddressField outField; private static AddressField inField; private static VirtualBaseConstructor virtualConstructor; private static Type nodeType; static HashMap nodes = new HashMap(); static HashMap constructors = new HashMap(); static abstract class Instantiator { abstract Node create(Address addr); } static public Node create(Address addr) { if (addr == null) return null; Node result = (Node)nodes.get(addr); if (result == null) { result = (Node)virtualConstructor.instantiateWrapperFor(addr); nodes.put(addr, result); } return result; } public Node(Address addr) { super(addr); } public int outcnt() { return (int)outcntField.getValue(this.getAddress()); } public int req() { return (int)cntField.getValue(this.getAddress()); } public int len() { return (int)maxField.getValue(this.getAddress()); } public int idx() { return (int)idxField.getValue(this.getAddress()); } private Node[] _out; private Node[] _in; public Node rawOut(int i) { if (_out == null) { int addressSize = (int)VM.getVM().getAddressSize(); _out = new Node[outcnt()]; Address ptr = outField.getValue(this.getAddress()); for (int j = 0; j < outcnt(); j++) { _out[j] = Node.create(ptr.getAddressAt(j * addressSize)); } } return _out[i]; } public Node in(int i) { if (_in == null) { int addressSize = (int)VM.getVM().getAddressSize(); _in = new Node[len()]; Address ptr = inField.getValue(this.getAddress()); for (int j = 0; j < len(); j++) { _in[j] = Node.create(ptr.getAddressAt(j * addressSize)); } } return _in[i]; } public ArrayList collect(int d, boolean onlyCtrl) { int depth = Math.abs(d); ArrayList nstack = new ArrayList(); BitSet set = new BitSet(); nstack.add(this); set.set(idx()); int begin = 0; int end = 0; for (int i = 0; i < depth; i++) { end = nstack.size(); for(int j = begin; j < end; j++) { Node tp = (Node)nstack.get(j); int limit = d > 0 ? tp.len() : tp.outcnt(); for(int k = 0; k < limit; k++) { Node n = d > 0 ? tp.in(k) : tp.rawOut(k); // if (NotANode(n)) continue; if (n == null) continue; // do not recurse through top or the root (would reach unrelated stuff) // if (n.isRoot() || n.isTop()) continue; // if (onlyCtrl && !n.isCfg()) continue; if (!set.get(n.idx())) { nstack.add(n); set.set(n.idx()); } } } begin = end; } return nstack; } protected void dumpNodes(Node s, int d, boolean onlyCtrl, PrintStream out) { if (s == null) return; ArrayList nstack = s.collect(d, onlyCtrl); int end = nstack.size(); if (d > 0) { for(int j = end-1; j >= 0; j--) { ((Node)nstack.get(j)).dump(out); } } else { for(int j = 0; j < end; j++) { ((Node)nstack.get(j)).dump(out); } } } public void dump(int depth, PrintStream out) { dumpNodes(this, depth, false, out); } public String Name() { Type t = VM.getVM().getTypeDataBase().findDynamicTypeForAddress(getAddress(), nodeType); String name = null; if (t != null) { name = t.toString(); } else { Class c = getClass(); if (c == Node.class) { // couldn't identify class type return "UnknownNode<" + getAddress().getAddressAt(0) + ">"; } name = getClass().getName(); if (name.startsWith("sun.jvm.hotspot.opto.")) { name = name.substring("sun.jvm.hotspot.opto.".length()); } } if (name.endsWith("Node")) { return name.substring(0, name.length() - 4); } return name; } public void dump(PrintStream out) { out.print(" "); out.print(idx()); out.print("\t"); out.print(Name()); out.print("\t=== "); int i = 0; for (i = 0; i < req(); i++) { Node n = in(i); if (n != null) { out.print(' '); out.print(in(i).idx()); } else { out.print("_"); } out.print(" "); } if (len() != req()) { int prec = 0; for (; i < len(); i++) { Node n = in(i); if (n != null) { if (prec++ == 0) { out.print("| "); } out.print(in(i).idx()); } out.print(" "); } } dumpOut(out); dumpSpec(out); out.println(); } void dumpOut(PrintStream out) { // Delimit the output edges out.print(" [["); // Dump the output edges for (int i = 0; i < outcnt(); i++) { // For all outputs Node u = rawOut(i); if (u == null) { out.print("_ "); // } else if (NotANode(u)) { // out.print("NotANode "); } else { // out.print("%c%d ", Compile::current()->nodeArena()->contains(u) ? ' ' : 'o', u->_idx); out.print(' '); out.print(u.idx()); out.print(' '); } } out.print("]] "); } public void dumpSpec(PrintStream out) { } }