--- /dev/null 2017-01-22 10:16:57.869617664 -0800
+++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphEncoder.java 2017-02-15 17:06:41.358751984 -0800
@@ -0,0 +1,548 @@
+/*
+ * Copyright (c) 2015, 2015, 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 org.graalvm.compiler.nodes;
+
+import static org.graalvm.compiler.core.common.CompilationIdentifier.INVALID_COMPILATION_ID;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+
+import org.graalvm.compiler.core.common.Fields;
+import org.graalvm.compiler.core.common.util.FrequencyEncoder;
+import org.graalvm.compiler.core.common.util.TypeConversion;
+import org.graalvm.compiler.core.common.util.TypeReader;
+import org.graalvm.compiler.core.common.util.TypeWriter;
+import org.graalvm.compiler.core.common.util.UnsafeArrayTypeWriter;
+import org.graalvm.compiler.debug.Debug;
+import org.graalvm.compiler.graph.Edges;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.NodeList;
+import org.graalvm.compiler.graph.NodeMap;
+import org.graalvm.compiler.graph.iterators.NodeIterable;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.java.ExceptionObjectNode;
+
+import jdk.vm.ci.code.Architecture;
+
+/**
+ * Encodes a {@link StructuredGraph} to a compact byte[] array. All nodes of the graph and edges
+ * between the nodes are encoded. Primitive data fields of nodes are stored in the byte[] array.
+ * Object data fields of nodes are stored in a separate Object[] array.
+ *
+ * One encoder instance can be used to encode multiple graphs. This requires that {@link #prepare}
+ * is called for all graphs first, followed by one call to {@link #finishPrepare}. Then
+ * {@link #encode} can be called for all graphs. The {@link #getObjects() objects} and
+ * {@link #getNodeClasses() node classes} arrays do not change anymore after preparation.
+ *
+ * Multiple encoded graphs share the Object[] array, and elements of the Object[] array are
+ * de-duplicated using {@link Object#equals Object equality}. This uses the assumption and good
+ * coding practice that data objects are immutable if {@link Object#equals} is implemented.
+ * Unfortunately, this cannot be enforced.
+ *
+ * The Graal {@link NodeClass} does not have a unique id that allows class lookup from an id.
+ * Therefore, the encoded graph contains a {@link NodeClass}[] array for lookup, and type ids are
+ * encoding-local.
+ *
+ * The encoded graph has the following structure: First, all nodes and their edges are serialized.
+ * The start offset of every node is then known. The raw node data is followed by a "table of
+ * contents" that lists the start offset for every node.
+ *
+ * The beginning of that table of contents is the return value of {@link #encode} and stored in
+ * {@link EncodedGraph#getStartOffset()}. The order of nodes in the table of contents is the
+ * {@link NodeOrder#orderIds orderId} of a node. Note that the orderId is not the regular node id
+ * that every Graal graph node gets assigned. The orderId is computed and used just for encoding and
+ * decoding. The orderId of fixed nodes is assigned in reverse postorder. The decoder processes
+ * nodes using that order, which ensures that all predecessors of a node (including all
+ * {@link EndNode predecessors} of a {@link AbstractBeginNode block}) are decoded before the node.
+ * The order id of floating node does not matter during decoding, so floating nodes get order ids
+ * after all fixed nodes. The order id is used to encode edges between nodes
+ *
+ * Structure of an encoded node:
+ *
+ *
+ *
+ * All numbers (unsigned and signed) are stored using a variable-length encoding as defined in
+ * {@link TypeReader} and {@link TypeWriter}. Especially orderIds are small, so the variable-length
+ * encoding is important to keep the encoding compact.
+ *
+ * The properties, successors, and inputs are written in the order as defined in
+ * {@link NodeClass#getData}, {@link NodeClass#getSuccessorEdges()}, and
+ * {@link NodeClass#getInputEdges()}. For variable-length successors and input lists, first the
+ * length is written and then the orderIds. There is a distinction between null lists (encoded as
+ * length -1) and empty lists (encoded as length 0). No reverse edges are written (predecessors,
+ * usages) since that information can be easily restored during decoding.
+ *
+ * Some nodes have additional information written after the properties, successors, and inputs:
+ *
{@link AbstractEndNode}: the orderId of the merge node and then all {@link PhiNode phi
+ * mappings} from this end to the merge node are written. {@link LoopExitNode}: the orderId of
+ * all {@link ProxyNode proxy nodes} of the loop exit is written.
+ */
+public class GraphEncoder {
+
+ /** The orderId that always represents {@code null}. */
+ public static final int NULL_ORDER_ID = 0;
+ /** The orderId of the {@link StructuredGraph#start() start node} of the encoded graph. */
+ public static final int START_NODE_ORDER_ID = 1;
+ /**
+ * The orderId of the first actual node after the {@link StructuredGraph#start() start node}.
+ */
+ public static final int FIRST_NODE_ORDER_ID = 2;
+
+ /**
+ * The known offset between the orderId of a {@link AbstractBeginNode} and its
+ * {@link AbstractBeginNode#next() successor}.
+ */
+ protected static final int BEGIN_NEXT_ORDER_ID_OFFSET = 1;
+
+ protected final Architecture architecture;
+
+ /**
+ * Collects all non-primitive data referenced from nodes. The encoding uses an index into an
+ * array for decoding. Because of the variable-length encoding, it is beneficial that frequently
+ * used objects have the small indices.
+ */
+ protected final FrequencyEncoder