changeset 12483:134671fbf973

Optimize Binary Graph format for more compact size
author Gilles Duboscq <duboscq@ssw.jku.at>
date Thu, 17 Oct 2013 18:18:05 +0200
parents f8c99c2bbb37
children 2d8a8980eda8
files graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java
diffstat 3 files changed, 172 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- 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<Position> getFirstLevelInputPositions() {
-        List<Position> 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<Position> getFirstLevelInputPositions() {
+        return new AbstractCollection<Position>() {
+            @Override
+            public Iterator<Position> iterator() {
+                return new Iterator<NodeClass.Position>() {
+                    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<Position> getFirstLevelSuccessorPositions() {
-        List<Position> 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<Position> getFirstLevelSuccessorPositions() {
+        return new AbstractCollection<Position>() {
+            @Override
+            public Iterator<Position> iterator() {
+                return new Iterator<NodeClass.Position>() {
+                    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() {
--- 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<Position> directInputPositions = nodeClass.getFirstLevelInputPositions();
+            Collection<Position> directInputPositions = nodeClass.getFirstLevelInputPositions();
             writeShort((char) directInputPositions.size());
             for (Position pos : directInputPositions) {
+                writeByte(pos.subIndex == NodeClass.NOT_ITERABLE ? 0 : 1);
                 writePoolObject(nodeClass.getName(pos));
             }
-            List<Position> directSuccessorPositions = nodeClass.getFirstLevelSuccessorPositions();
+            Collection<Position> 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<Position> 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<Position> 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();
         }
--- 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<String> inputs;
-        public final List<String> sux;
-        private NodeClass(String className, String nameTemplate, List<String> inputs, List<String> sux) {
+        public final List<Port> inputs;
+        public final List<Port> sux;
+        private NodeClass(String className, String nameTemplate, List<Port> inputs, List<Port> sux) {
             this.className = className;
             this.nameTemplate = nameTemplate;
             this.inputs = inputs;
@@ -440,14 +449,18 @@
                 String className = readString();
                 String nameTemplate = readString();
                 int inputCount = readShort();
-                List<String> inputs = new ArrayList<>(inputCount);
+                List<Port> 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<String> sux = new ArrayList<>(suxCount);
+                List<Port> 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);