# HG changeset patch # User Gilles Duboscq # Date 1382026685 -7200 # Node ID 134671fbf9735045091f99a2e0b60d8d83cf1ca6 # Parent f8c99c2bbb37fe07259d004f079823ae8bc19041 Optimize Binary Graph format for more compact size diff -r f8c99c2bbb37 -r 134671fbf973 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Thu Oct 17 18:23:20 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Thu Oct 17 18:18:05 2013 +0200 @@ -125,7 +125,8 @@ return registry.make(key); } - static final int NOT_ITERABLE = -1; + public static final int NOT_ITERABLE = -1; + public static final int NODE_LIST = -2; private static final Class NODE_CLASS = Node.class; private static final Class INPUT_LIST_CLASS = NodeInputList.class; @@ -817,6 +818,12 @@ } } + public NodeList getNodeList(Node node, Position pos) { + long offset = pos.input ? inputOffsets[pos.index] : successorOffsets[pos.index]; + assert pos.subIndex == NODE_LIST; + return getNodeList(node, offset); + } + public String getName(Position pos) { return fieldNames.get(pos.input ? inputOffsets[pos.index] : successorOffsets[pos.index]); } @@ -1175,20 +1182,64 @@ return false; } - public List getFirstLevelInputPositions() { - List positions = new ArrayList<>(inputOffsets.length); - for (int i = 0; i < inputOffsets.length; i++) { - positions.add(new Position(true, i, NOT_ITERABLE)); - } - return positions; + public Collection getFirstLevelInputPositions() { + return new AbstractCollection() { + @Override + public Iterator iterator() { + return new Iterator() { + int i = 0; + + public void remove() { + throw new UnsupportedOperationException(); + } + + public Position next() { + Position pos = new Position(true, i, i >= directInputCount ? 0 : NOT_ITERABLE); + i++; + return pos; + } + + public boolean hasNext() { + return i < inputOffsets.length; + } + }; + } + + @Override + public int size() { + return inputOffsets.length; + } + }; } - public List getFirstLevelSuccessorPositions() { - List positions = new ArrayList<>(successorOffsets.length); - for (int i = 0; i < successorOffsets.length; i++) { - positions.add(new Position(false, i, NOT_ITERABLE)); - } - return positions; + public Collection getFirstLevelSuccessorPositions() { + return new AbstractCollection() { + @Override + public Iterator iterator() { + return new Iterator() { + int i = 0; + + public void remove() { + throw new UnsupportedOperationException(); + } + + public Position next() { + Position pos = new Position(false, i, i >= directSuccessorCount ? 0 : NOT_ITERABLE); + i++; + return pos; + } + + public boolean hasNext() { + return i < successorOffsets.length; + } + }; + } + + @Override + public int size() { + return successorOffsets.length; + } + }; } public Class getJavaClass() { diff -r f8c99c2bbb37 -r 134671fbf973 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Thu Oct 17 18:23:20 2013 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Thu Oct 17 18:18:05 2013 +0200 @@ -32,7 +32,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; -import com.oracle.graal.graph.NodeClass.NodeClassIterator; import com.oracle.graal.graph.NodeClass.Position; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; @@ -42,7 +41,7 @@ public class BinaryGraphPrinter implements GraphPrinter { - private static final int CONSTANT_POOL_MAX_SIZE = 2000; + private static final int CONSTANT_POOL_MAX_SIZE = 8000; private static final int BEGIN_GROUP = 0x00; private static final int BEGIN_GRAPH = 0x01; @@ -294,14 +293,16 @@ writeByte(POOL_NODE_CLASS); writeString(nodeClass.getJavaClass().getSimpleName()); writeString(nodeClass.getNameTemplate()); - List directInputPositions = nodeClass.getFirstLevelInputPositions(); + Collection directInputPositions = nodeClass.getFirstLevelInputPositions(); writeShort((char) directInputPositions.size()); for (Position pos : directInputPositions) { + writeByte(pos.subIndex == NodeClass.NOT_ITERABLE ? 0 : 1); writePoolObject(nodeClass.getName(pos)); } - List directSuccessorPositions = nodeClass.getFirstLevelSuccessorPositions(); + Collection directSuccessorPositions = nodeClass.getFirstLevelSuccessorPositions(); writeShort((char) directSuccessorPositions.size()); for (Position pos : directSuccessorPositions) { + writeByte(pos.subIndex == NodeClass.NOT_ITERABLE ? 0 : 1); writePoolObject(nodeClass.getName(pos)); } } else if (object instanceof ResolvedJavaMethod) { @@ -412,25 +413,53 @@ writePoolObject(key); writePropertyObject(entry.getValue()); } - // successors - NodeClassIterable successors = node.successors(); - writeShort((char) successors.count()); - NodeClassIterator suxIt = successors.iterator(); - while (suxIt.hasNext()) { - Position pos = suxIt.nextPosition(); - Node sux = nodeClass.get(node, pos); - writeInt(sux.getId()); - writeShort((char) pos.index); + // inputs + Collection directInputPositions = nodeClass.getFirstLevelInputPositions(); + for (Position pos : directInputPositions) { + if (pos.subIndex == NodeClass.NOT_ITERABLE) { + Node in = nodeClass.get(node, pos); + if (in != null) { + writeInt(in.getId()); + } else { + writeInt(-1); + } + } else { + NodeList list = nodeClass.getNodeList(node, pos); + int listSize = list.count(); + assert listSize == ((char) listSize); + writeShort((char) listSize); + for (Node in : list) { + if (in != null) { + writeInt(in.getId()); + } else { + writeInt(-1); + } + } + } } - // inputs - NodeClassIterable inputs = node.inputs(); - writeShort((char) inputs.count()); - NodeClassIterator inIt = inputs.iterator(); - while (inIt.hasNext()) { - Position pos = inIt.nextPosition(); - Node in = nodeClass.get(node, pos); - writeInt(in.getId()); - writeShort((char) pos.index); + // successors + Collection directSuccessorPositions = nodeClass.getFirstLevelSuccessorPositions(); + for (Position pos : directSuccessorPositions) { + if (pos.subIndex == NodeClass.NOT_ITERABLE) { + Node sux = nodeClass.get(node, pos); + if (sux != null) { + writeInt(sux.getId()); + } else { + writeInt(-1); + } + } else { + NodeList list = nodeClass.getNodeList(node, pos); + int listSize = list.count(); + assert listSize == ((char) listSize); + writeShort((char) listSize); + for (Node sux : list) { + if (sux != null) { + writeInt(sux.getId()); + } else { + writeInt(-1); + } + } + } } props.clear(); } diff -r f8c99c2bbb37 -r 134671fbf973 src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java Thu Oct 17 18:23:20 2013 +0200 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java Thu Oct 17 18:18:05 2013 +0200 @@ -201,12 +201,21 @@ } } + private static class Port { + public final boolean isList; + public final String name; + private Port(boolean isList, String name) { + this.isList = isList; + this.name = name; + } + } + private static class NodeClass { public final String className; public final String nameTemplate; - public final List inputs; - public final List sux; - private NodeClass(String className, String nameTemplate, List inputs, List sux) { + public final List inputs; + public final List sux; + private NodeClass(String className, String nameTemplate, List inputs, List sux) { this.className = className; this.nameTemplate = nameTemplate; this.inputs = inputs; @@ -440,14 +449,18 @@ String className = readString(); String nameTemplate = readString(); int inputCount = readShort(); - List inputs = new ArrayList<>(inputCount); + List inputs = new ArrayList<>(inputCount); for (int i = 0; i < inputCount; i++) { - inputs.add(readPoolObject(String.class)); + boolean isList = readByte() != 0; + String name = readPoolObject(String.class); + inputs.add(new Port(isList, name)); } int suxCount = readShort(); - List sux = new ArrayList<>(suxCount); + List sux = new ArrayList<>(suxCount); for (int i = 0; i < suxCount; i++) { - sux.add(readPoolObject(String.class)); + boolean isList = readByte() != 0; + String name = readPoolObject(String.class); + sux.add(new Port(isList, name)); } obj = new NodeClass(className, nameTemplate, inputs, sux); break; @@ -684,17 +697,44 @@ } } int edgesStart = edges.size(); - int suxCount = readShort(); - for (int j = 0; j < suxCount; j++) { - int sux = readInt(); - int index = readShort(); - edges.add(new Edge(id, sux, (char) j, nodeClass.sux.get(index), false)); + int portNum = 0; + for (Port p : nodeClass.inputs) { + if (p.isList) { + int size = readShort(); + for (int j = 0; j < size; j++) { + int in = readInt(); + if (in >= 0) { + edges.add(new Edge(in, id, (char) (preds + portNum), p.name + "[" + j + "]", true)); + portNum++; + } + } + } else { + int in = readInt(); + if (in >= 0) { + edges.add(new Edge(in, id, (char) (preds + portNum), p.name, true)); + portNum++; + } + } + } - int inputCount = readShort(); - for (int j = 0; j < inputCount; j++) { - int in = readInt(); - int index = readShort(); - edges.add(new Edge(in, id, (char) (preds + j), nodeClass.inputs.get(index), true)); + portNum = 0; + for (Port p : nodeClass.sux) { + if (p.isList) { + int size = readShort(); + for (int j = 0; j < size; j++) { + int sux = readInt(); + if (sux >= 0) { + edges.add(new Edge(id, sux, (char) portNum, p.name + "[" + j + "]", false)); + portNum++; + } + } + } else { + int sux = readInt(); + if (sux >= 0) { + edges.add(new Edge(id, sux, (char) portNum, p.name, false)); + portNum++; + } + } } properties.setProperty("name", createName(edges.subList(edgesStart, edges.size()), props, nodeClass.nameTemplate)); properties.setProperty("class", nodeClass.className);