src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphEncoder.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphEncoder.java

Print this page




  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.graalvm.compiler.nodes;
  24 
  25 import java.util.ArrayDeque;
  26 import java.util.Deque;
  27 import java.util.Iterator;
  28 import java.util.Objects;
  29 
  30 import org.graalvm.compiler.core.common.Fields;
  31 import org.graalvm.compiler.core.common.util.FrequencyEncoder;
  32 import org.graalvm.compiler.core.common.util.TypeConversion;
  33 import org.graalvm.compiler.core.common.util.TypeReader;
  34 import org.graalvm.compiler.core.common.util.TypeWriter;
  35 import org.graalvm.compiler.core.common.util.UnsafeArrayTypeWriter;
  36 import org.graalvm.compiler.debug.Debug;
  37 import org.graalvm.compiler.graph.Edges;
  38 import org.graalvm.compiler.graph.Node;
  39 import org.graalvm.compiler.graph.NodeClass;
  40 import org.graalvm.compiler.graph.NodeList;
  41 import org.graalvm.compiler.graph.NodeMap;
  42 import org.graalvm.compiler.graph.iterators.NodeIterable;
  43 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
  44 import org.graalvm.compiler.nodes.java.ExceptionObjectNode;
  45 import org.graalvm.util.UnmodifiableMapCursor;
  46 import org.graalvm.util.Pair;

  47 
  48 import jdk.vm.ci.code.Architecture;
  49 
  50 /**
  51  * Encodes a {@link StructuredGraph} to a compact byte[] array. All nodes of the graph and edges
  52  * between the nodes are encoded. Primitive data fields of nodes are stored in the byte[] array.
  53  * Object data fields of nodes are stored in a separate Object[] array.
  54  *
  55  * One encoder instance can be used to encode multiple graphs. This requires that {@link #prepare}
  56  * is called for all graphs first, followed by one call to {@link #finishPrepare}. Then
  57  * {@link #encode} can be called for all graphs. The {@link #getObjects() objects} and
  58  * {@link #getNodeClasses() node classes} arrays do not change anymore after preparation.
  59  *
  60  * Multiple encoded graphs share the Object[] array, and elements of the Object[] array are
  61  * de-duplicated using {@link Object#equals Object equality}. This uses the assumption and good
  62  * coding practice that data objects are immutable if {@link Object#equals} is implemented.
  63  * Unfortunately, this cannot be enforced.
  64  *
  65  * The Graal {@link NodeClass} does not have a unique id that allows class lookup from an id.
  66  * Therefore, the encoded graph contains a {@link NodeClass}[] array for lookup, and type ids are


 401                 }
 402             }
 403         }
 404 
 405     }
 406 
 407     protected void writeOrderId(Node node, NodeOrder nodeOrder) {
 408         writer.putUV(node == null ? NULL_ORDER_ID : nodeOrder.orderIds.get(node));
 409     }
 410 
 411     protected void writeObjectId(Object object) {
 412         writer.putUV(objects.getIndex(object));
 413     }
 414 
 415     /**
 416      * Verification code that checks that the decoding of an encode graph is the same as the
 417      * original graph.
 418      */
 419     @SuppressWarnings("try")
 420     public static boolean verifyEncoding(StructuredGraph originalGraph, EncodedGraph encodedGraph, Architecture architecture) {
 421         StructuredGraph decodedGraph = new StructuredGraph.Builder(originalGraph.getOptions(), AllowAssumptions.YES).method(originalGraph.method()).build();

 422         GraphDecoder decoder = new GraphDecoder(architecture, decodedGraph);
 423         decoder.decode(encodedGraph);
 424 
 425         decodedGraph.verify();
 426         try {
 427             GraphComparison.verifyGraphsEqual(originalGraph, decodedGraph);
 428         } catch (Throwable ex) {
 429             try (Debug.Scope scope = Debug.scope("GraphEncoder")) {
 430                 Debug.dump(Debug.VERBOSE_LEVEL, originalGraph, "Original Graph");
 431                 Debug.dump(Debug.VERBOSE_LEVEL, decodedGraph, "Decoded Graph");

 432             }
 433             throw ex;
 434         }
 435         return true;
 436     }
 437 }
 438 
 439 class GraphComparison {
 440     public static boolean verifyGraphsEqual(StructuredGraph expectedGraph, StructuredGraph actualGraph) {
 441         NodeMap<Node> nodeMapping = new NodeMap<>(expectedGraph);
 442         Deque<Pair<Node, Node>> workList = new ArrayDeque<>();
 443 
 444         pushToWorklist(expectedGraph.start(), actualGraph.start(), nodeMapping, workList);
 445         while (!workList.isEmpty()) {
 446             Pair<Node, Node> pair = workList.removeFirst();
 447             Node expectedNode = pair.getLeft();
 448             Node actualNode = pair.getRight();
 449             assert expectedNode.getClass() == actualNode.getClass();
 450 
 451             NodeClass<?> nodeClass = expectedNode.getNodeClass();




  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.graalvm.compiler.nodes;
  24 
  25 import java.util.ArrayDeque;
  26 import java.util.Deque;
  27 import java.util.Iterator;
  28 import java.util.Objects;
  29 
  30 import org.graalvm.compiler.core.common.Fields;
  31 import org.graalvm.compiler.core.common.util.FrequencyEncoder;
  32 import org.graalvm.compiler.core.common.util.TypeConversion;
  33 import org.graalvm.compiler.core.common.util.TypeReader;
  34 import org.graalvm.compiler.core.common.util.TypeWriter;
  35 import org.graalvm.compiler.core.common.util.UnsafeArrayTypeWriter;
  36 import org.graalvm.compiler.debug.DebugContext;
  37 import org.graalvm.compiler.graph.Edges;
  38 import org.graalvm.compiler.graph.Node;
  39 import org.graalvm.compiler.graph.NodeClass;
  40 import org.graalvm.compiler.graph.NodeList;
  41 import org.graalvm.compiler.graph.NodeMap;
  42 import org.graalvm.compiler.graph.iterators.NodeIterable;
  43 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
  44 import org.graalvm.compiler.nodes.java.ExceptionObjectNode;

  45 import org.graalvm.util.Pair;
  46 import org.graalvm.util.UnmodifiableMapCursor;
  47 
  48 import jdk.vm.ci.code.Architecture;
  49 
  50 /**
  51  * Encodes a {@link StructuredGraph} to a compact byte[] array. All nodes of the graph and edges
  52  * between the nodes are encoded. Primitive data fields of nodes are stored in the byte[] array.
  53  * Object data fields of nodes are stored in a separate Object[] array.
  54  *
  55  * One encoder instance can be used to encode multiple graphs. This requires that {@link #prepare}
  56  * is called for all graphs first, followed by one call to {@link #finishPrepare}. Then
  57  * {@link #encode} can be called for all graphs. The {@link #getObjects() objects} and
  58  * {@link #getNodeClasses() node classes} arrays do not change anymore after preparation.
  59  *
  60  * Multiple encoded graphs share the Object[] array, and elements of the Object[] array are
  61  * de-duplicated using {@link Object#equals Object equality}. This uses the assumption and good
  62  * coding practice that data objects are immutable if {@link Object#equals} is implemented.
  63  * Unfortunately, this cannot be enforced.
  64  *
  65  * The Graal {@link NodeClass} does not have a unique id that allows class lookup from an id.
  66  * Therefore, the encoded graph contains a {@link NodeClass}[] array for lookup, and type ids are


 401                 }
 402             }
 403         }
 404 
 405     }
 406 
 407     protected void writeOrderId(Node node, NodeOrder nodeOrder) {
 408         writer.putUV(node == null ? NULL_ORDER_ID : nodeOrder.orderIds.get(node));
 409     }
 410 
 411     protected void writeObjectId(Object object) {
 412         writer.putUV(objects.getIndex(object));
 413     }
 414 
 415     /**
 416      * Verification code that checks that the decoding of an encode graph is the same as the
 417      * original graph.
 418      */
 419     @SuppressWarnings("try")
 420     public static boolean verifyEncoding(StructuredGraph originalGraph, EncodedGraph encodedGraph, Architecture architecture) {
 421         DebugContext debug = originalGraph.getDebug();
 422         StructuredGraph decodedGraph = new StructuredGraph.Builder(originalGraph.getOptions(), debug, AllowAssumptions.YES).method(originalGraph.method()).build();
 423         GraphDecoder decoder = new GraphDecoder(architecture, decodedGraph);
 424         decoder.decode(encodedGraph);
 425 
 426         decodedGraph.verify();
 427         try {
 428             GraphComparison.verifyGraphsEqual(originalGraph, decodedGraph);
 429         } catch (Throwable ex) {
 430             originalGraph.getDebug();
 431             try (DebugContext.Scope scope = debug.scope("GraphEncoder")) {
 432                 debug.dump(DebugContext.VERBOSE_LEVEL, originalGraph, "Original Graph");
 433                 debug.dump(DebugContext.VERBOSE_LEVEL, decodedGraph, "Decoded Graph");
 434             }
 435             throw ex;
 436         }
 437         return true;
 438     }
 439 }
 440 
 441 class GraphComparison {
 442     public static boolean verifyGraphsEqual(StructuredGraph expectedGraph, StructuredGraph actualGraph) {
 443         NodeMap<Node> nodeMapping = new NodeMap<>(expectedGraph);
 444         Deque<Pair<Node, Node>> workList = new ArrayDeque<>();
 445 
 446         pushToWorklist(expectedGraph.start(), actualGraph.start(), nodeMapping, workList);
 447         while (!workList.isEmpty()) {
 448             Pair<Node, Node> pair = workList.removeFirst();
 449             Node expectedNode = pair.getLeft();
 450             Node actualNode = pair.getRight();
 451             assert expectedNode.getClass() == actualNode.getClass();
 452 
 453             NodeClass<?> nodeClass = expectedNode.getNodeClass();


src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphEncoder.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File