| /* |
| * 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) { |
| } |
| } |