< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java

Print this page

        

@@ -50,10 +50,11 @@
     private static final int POOL_NULL = 0x05;
     private static final int POOL_NODE_CLASS = 0x06;
     private static final int POOL_FIELD = 0x07;
     private static final int POOL_SIGNATURE = 0x08;
     private static final int POOL_NODE_SOURCE_POSITION = 0x09;
+    private static final int POOL_NODE = 0x0a;
 
     private static final int PROPERTY_POOL = 0x00;
     private static final int PROPERTY_INT = 0x01;
     private static final int PROPERTY_LONG = 0x02;
     private static final int PROPERTY_DOUBLE = 0x03;

@@ -69,32 +70,33 @@
     private static final byte[] MAGIC_BYTES = {'B', 'I', 'G', 'V'};
 
     private final ConstantPool constantPool;
     private final ByteBuffer buffer;
     private final WritableByteChannel channel;
-    private final int versionMajor;
-    private final int versionMinor;
+    final int versionMajor;
+    final int versionMinor;
 
-    protected GraphProtocol(WritableByteChannel channel) throws IOException {
-        this(channel, 4, 0);
-    }
-
-    private GraphProtocol(WritableByteChannel channel, int major, int minor) throws IOException {
-        if (major > 4) {
-            throw new IllegalArgumentException();
-        }
-        if (major == 4 && minor > 0) {
-            throw new IllegalArgumentException();
+    GraphProtocol(WritableByteChannel channel, int major, int minor) throws IOException {
+        if (major > 5 || (major == 5 && minor > 0)) {
+            throw new IllegalArgumentException("Unrecognized version " + major + "." + minor);
         }
         this.versionMajor = major;
         this.versionMinor = minor;
         this.constantPool = new ConstantPool();
         this.buffer = ByteBuffer.allocateDirect(256 * 1024);
         this.channel = channel;
         writeVersion();
     }
 
+    GraphProtocol(GraphProtocol<?, ?, ?, ?, ?, ?, ?, ?, ?> parent) {
+        this.versionMajor = parent.versionMajor;
+        this.versionMinor = parent.versionMinor;
+        this.constantPool = parent.constantPool;
+        this.buffer = parent.buffer;
+        this.channel = parent.channel;
+    }
+
     @SuppressWarnings("all")
     public final void print(Graph graph, Map<? extends Object, ? extends Object> properties, int id, String format, Object... args) throws IOException {
         writeByte(BEGIN_GRAPH);
         if (versionMajor >= 3) {
             writeInt(id);

@@ -135,13 +137,37 @@
 
     protected abstract Graph findGraph(Graph current, Object obj);
 
     protected abstract ResolvedJavaMethod findMethod(Object obj);
 
+    /**
+     * Attempts to recognize the provided object as a node. Used to encode it with
+     * {@link #POOL_NODE} pool type.
+     * 
+     * @param obj any object
+     * @return <code>null</code> if it is not a node object, non-null otherwise
+     */
+    protected abstract Node findNode(Object obj);
+
+    /**
+     * Determines whether the provided object is node class or not.
+     *
+     * @param obj object to check
+     * @return {@code null} if {@code obj} does not represent a NodeClass otherwise the NodeClass
+     *         represented by {@code obj}
+     */
     protected abstract NodeClass findNodeClass(Object obj);
 
     /**
+     * Returns the NodeClass for a given Node {@code obj}.
+     * 
+     * @param obj instance of node
+     * @return non-{@code null} instance of the node's class object
+     */
+    protected abstract NodeClass findClassForNode(Node obj);
+
+    /**
      * Find a Java class. The returned object must be acceptable by
      * {@link #findJavaTypeName(java.lang.Object)} and return valid name for the class.
      *
      * @param clazz node class object
      * @return object representing the class, for example {@link Class}

@@ -237,11 +263,11 @@
     }
 
     private void flush() throws IOException {
         buffer.flip();
         /*
-         * Try not to let interrupted threads aborting the write. There's still a race here but an
+         * Try not to let interrupted threads abort the write. There's still a race here but an
          * interrupt that's been pending for a long time shouldn't stop this writing.
          */
         boolean interrupted = Thread.interrupted();
         try {
             channel.write(buffer);

@@ -336,38 +362,47 @@
             buffer.asDoubleBuffer().put(b);
             buffer.position(buffer.position() + sizeInBytes);
         }
     }
 
-    private void writePoolObject(Object object) throws IOException {
+    private void writePoolObject(Object obj) throws IOException {
+        Object object = obj;
         if (object == null) {
             writeByte(POOL_NULL);
             return;
         }
         Character id = constantPool.get(object);
         if (id == null) {
             addPoolEntry(object);
         } else {
-            if (object instanceof Enum<?> || findEnumOrdinal(object) >= 0) {
-                writeByte(POOL_ENUM);
-            } else if (object instanceof Class<?> || findJavaTypeName(object) != null) {
-                writeByte(POOL_CLASS);
-            } else if (findJavaField(object) != null) {
+            if (findJavaField(object) != null) {
                 writeByte(POOL_FIELD);
             } else if (findSignature(object) != null) {
                 writeByte(POOL_SIGNATURE);
             } else if (versionMajor >= 4 && findNodeSourcePosition(object) != null) {
                 writeByte(POOL_NODE_SOURCE_POSITION);
             } else {
+                final Node node = findNode(object);
+                if (versionMajor == 4 && node != null) {
+                    object = classForNode(node);
+                }
                 if (findNodeClass(object) != null) {
                     writeByte(POOL_NODE_CLASS);
+                } else if (versionMajor >= 5 && node != null) {
+                    writeByte(POOL_NODE);
                 } else if (findMethod(object) != null) {
                     writeByte(POOL_METHOD);
                 } else {
+                    if (object instanceof Enum<?> || findEnumOrdinal(object) >= 0) {
+                        writeByte(POOL_ENUM);
+                    } else if (object instanceof Class<?> || findJavaTypeName(object) != null) {
+                        writeByte(POOL_CLASS);
+                    } else {
                     writeByte(POOL_STRING);
                 }
             }
+            }
             writeShort(id.charValue());
         }
     }
 
     private void writeGraph(Graph graph, Map<? extends Object, ? extends Object> properties) throws IOException {

@@ -381,14 +416,11 @@
 
         final int size = findNodesCount(info);
         writeInt(size);
         int cnt = 0;
         for (Node node : findNodes(info)) {
-            NodeClass nodeClass = findNodeClass(node);
-            if (nodeClass == null) {
-                throw new IOException("No class for " + node);
-            }
+            NodeClass nodeClass = classForNode(node);
             findNodeProperties(node, props, info);
 
             writeInt(findNodeId(node));
             writePoolObject(nodeClass);
             writeByte(hasPredecessor(node) ? 1 : 0);

@@ -403,11 +435,11 @@
             throw new IOException("Expecting " + size + " nodes, but found " + cnt);
         }
     }
 
     private void writeEdges(Graph graph, Node node, boolean dumpInputs) throws IOException {
-        NodeClass clazz = findNodeClass(node);
+        NodeClass clazz = classForNode(node);
         Edges edges = findClassEdges(clazz, dumpInputs);
         int size = findSize(edges);
         for (int i = 0; i < size; i++) {
             Collection<? extends Node> list = findNodes(graph, node, edges, i);
             if (isDirect(edges, i)) {

@@ -432,10 +464,18 @@
                 }
             }
         }
     }
 
+    private NodeClass classForNode(Node node) throws IOException {
+        NodeClass clazz = findClassForNode(node);
+        if (clazz == null) {
+            throw new IOException("No class for " + node);
+        }
+        return clazz;
+    }
+
     private void writeNodeRef(Node node) throws IOException {
         writeInt(findNodeId(node));
     }
 
     private void writeBlocks(Collection<? extends Block> blocks, Graph info) throws IOException {

@@ -478,37 +518,21 @@
             }
         }
     }
 
     @SuppressWarnings("all")
-    private void addPoolEntry(Object object) throws IOException {
+    private void addPoolEntry(Object obj) throws IOException {
+        Object object = obj;
         ResolvedJavaField field;
         String typeName;
         Signature signature;
         NodeSourcePosition pos;
         int enumOrdinal;
         char index = constantPool.add(object);
         writeByte(POOL_NEW);
         writeShort(index);
-        if ((typeName = findJavaTypeName(object)) != null) {
-            writeByte(POOL_CLASS);
-            writeString(typeName);
-            String[] enumValueNames = findEnumTypeValues(object);
-            if (enumValueNames != null) {
-                writeByte(ENUM_KLASS);
-                writeInt(enumValueNames.length);
-                for (String o : enumValueNames) {
-                    writePoolObject(o);
-                }
-            } else {
-                writeByte(KLASS);
-            }
-        } else if ((enumOrdinal = findEnumOrdinal(object)) >= 0) {
-            writeByte(POOL_ENUM);
-            writePoolObject(findEnumClass(object));
-            writeInt(enumOrdinal);
-        } else if ((field = findJavaField(object)) != null) {
+        if ((field = findJavaField(object)) != null) {
             writeByte(POOL_FIELD);
             writePoolObject(findFieldDeclaringClass(field));
             writePoolObject(findFieldName(field));
             writePoolObject(findFieldTypeName(field));
             writeInt(findFieldModifiers(field));

@@ -533,10 +557,22 @@
             } else {
                 writePoolObject(null);
             }
             writePoolObject(findNodeSourcePositionCaller(pos));
         } else {
+            Node node = findNode(object);
+            if (node != null) {
+                if (versionMajor >= 5) {
+                    writeByte(POOL_NODE);
+                    writeInt(findNodeId(node));
+                    writePoolObject(classForNode(node));
+                    return;
+                }
+                if (versionMajor == 4) {
+                    object = classForNode(node);
+                }
+            }
             NodeClass nodeClass = findNodeClass(object);
             if (nodeClass != null) {
                 writeByte(POOL_NODE_CLASS);
                 final Object clazz = findJavaClass(nodeClass);
                 if (versionMajor >= 3) {

@@ -551,12 +587,31 @@
                 writeEdgesInfo(nodeClass, false);
                 return;
             }
             ResolvedJavaMethod method = findMethod(object);
             if (method == null) {
+                if ((typeName = findJavaTypeName(object)) != null) {
+                    writeByte(POOL_CLASS);
+                    writeString(typeName);
+                    String[] enumValueNames = findEnumTypeValues(object);
+                    if (enumValueNames != null) {
+                        writeByte(ENUM_KLASS);
+                        writeInt(enumValueNames.length);
+                        for (String o : enumValueNames) {
+                            writePoolObject(o);
+                        }
+                    } else {
+                        writeByte(KLASS);
+                    }
+                } else if ((enumOrdinal = findEnumOrdinal(object)) >= 0) {
+                    writeByte(POOL_ENUM);
+                    writePoolObject(findEnumClass(object));
+                    writeInt(enumOrdinal);
+                } else {
                 writeByte(POOL_STRING);
                 writeString(object.toString());
+                }
                 return;
             }
             writeByte(POOL_METHOD);
             writePoolObject(findMethodDeclaringClass(method));
             writePoolObject(findMethodName(method));
< prev index next >