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

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java

Print this page

        

*** 27,50 **** import static org.graalvm.compiler.graph.Graph.isModificationCountsEnabled; import static org.graalvm.compiler.graph.UnsafeAccess.UNSAFE; import java.lang.annotation.ElementType; import java.lang.annotation.RetentionPolicy; - import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.Formattable; import java.util.FormattableFlags; import java.util.Formatter; import java.util.HashMap; - import java.util.List; import java.util.Map; import java.util.Objects; - import java.util.Set; import java.util.function.Predicate; - import org.graalvm.compiler.core.common.CollectionsFactory; import org.graalvm.compiler.core.common.Fields; import org.graalvm.compiler.debug.DebugCloseable; import org.graalvm.compiler.debug.Fingerprint; import org.graalvm.compiler.graph.Graph.NodeEvent; import org.graalvm.compiler.graph.Graph.NodeEventListener; --- 27,46 ----
*** 54,63 **** --- 50,60 ---- import org.graalvm.compiler.graph.spi.Simplifiable; import org.graalvm.compiler.graph.spi.SimplifierTool; import org.graalvm.compiler.nodeinfo.InputType; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodeinfo.Verbosity; + import org.graalvm.compiler.options.OptionValues; import sun.misc.Unsafe; /** * This class is the base class for all nodes. It represents a node that can be inserted in a
*** 69,93 **** * {@link Input} and {@link Successor} is not null, then there is an edge from this node to the node * this field points to. * <p> * Nodes which are be value numberable should implement the {@link ValueNumberable} interface. * - * <h1>Replay Compilation</h1> - * - * To enable deterministic replay compilation, node sets and node maps should be instantiated with - * the following methods: - * <ul> - * <li>{@link #newSet()}</li> - * <li>{@link #newSet(Collection)}</li> - * <li>{@link #newMap()}</li> - * <li>{@link #newMap(int)}</li> - * <li>{@link #newMap(Map)}</li> - * <li>{@link #newIdentityMap()}</li> - * <li>{@link #newIdentityMap(int)}</li> - * <li>{@link #newIdentityMap(Map)}</li> - * </ul> - * * <h1>Assertions and Verification</h1> * * The Node class supplies the {@link #assertTrue(boolean, String, Object...)} and * {@link #assertFalse(boolean, String, Object...)} methods, which will check the supplied boolean * and throw a VerificationError if it has the wrong value. Both methods will always either throw an --- 66,75 ----
*** 96,106 **** */ @NodeInfo public abstract class Node implements Cloneable, Formattable, NodeInterface { public static final NodeClass<?> TYPE = null; ! public static final boolean USE_UNSAFE_TO_CLONE = Graph.Options.CloneNodesWithUnsafe.getValue(); static final int DELETED_ID_START = -1000000000; static final int INITIAL_ID = -1; static final int ALIVE_ID_START = 0; --- 78,88 ---- */ @NodeInfo public abstract class Node implements Cloneable, Formattable, NodeInterface { public static final NodeClass<?> TYPE = null; ! public static final boolean USE_UNSAFE_TO_CLONE = true; static final int DELETED_ID_START = -1000000000; static final int INITIAL_ID = -1; static final int ALIVE_ID_START = 0;
*** 256,319 **** public Node asNode() { return this; } /** ! * @see CollectionsFactory#newSet() ! */ ! public static <E extends Node> Set<E> newSet() { ! return CollectionsFactory.newSet(); ! } ! ! /** ! * @see #newSet() */ ! public static <E extends Node> Set<E> newSet(Collection<? extends E> c) { ! return CollectionsFactory.newSet(c); ! } ! ! public static <K extends Node, V> Map<K, V> newMap() { ! // Node.equals() and Node.hashCode() are final and are implemented ! // purely in terms of identity so HashMap and IdentityHashMap with ! // Node's as keys will behave the same. We choose to use the latter ! // due to its lighter memory footprint. ! return newIdentityMap(); ! } ! ! public static <K extends Node, V> Map<K, V> newMap(Map<K, V> m) { ! // Node.equals() and Node.hashCode() are final and are implemented ! // purely in terms of identity so HashMap and IdentityHashMap with ! // Node's as keys will behave the same. We choose to use the latter ! // due to its lighter memory footprint. ! return newIdentityMap(m); ! } ! ! public static <K extends Node, V> Map<K, V> newMap(int expectedMaxSize) { ! // Node.equals() and Node.hashCode() are final and are implemented ! // purely in terms of identity so HashMap and IdentityHashMap with ! // Node's as keys will behave the same. We choose to use the latter ! // due to its lighter memory footprint. ! return newIdentityMap(expectedMaxSize); ! } ! ! public static <K extends Node, V> Map<K, V> newIdentityMap() { ! return CollectionsFactory.newIdentityMap(); ! } ! ! public static <K extends Node, V> Map<K, V> newIdentityMap(Map<K, V> m) { ! return CollectionsFactory.newIdentityMap(m); ! } ! ! public static <K extends Node, V> Map<K, V> newIdentityMap(int expectedMaxSize) { ! return CollectionsFactory.newIdentityMap(expectedMaxSize); } /** ! * Gets the graph context of this node. */ ! public Graph graph() { ! return graph; } /** * Returns an {@link NodeIterable iterable} which can be used to traverse all non-null input * edges of this node. --- 238,258 ---- public Node asNode() { return this; } /** ! * Gets the graph context of this node. */ ! public Graph graph() { ! return graph; } /** ! * Gets the option values associated with this node's graph. */ ! public final OptionValues getOptions() { ! return graph == null ? null : graph.getOptions(); } /** * Returns an {@link NodeIterable iterable} which can be used to traverse all non-null input * edges of this node.
*** 411,429 **** */ public final boolean hasUsages() { return this.usage0 != null; } ! void reverseUsageOrder() { ! List<Node> snapshot = this.usages().snapshot(); ! for (Node n : snapshot) { ! this.removeUsage(n); ! } ! Collections.reverse(snapshot); ! for (Node n : snapshot) { ! this.addUsage(n); } } /** * Adds a given node to this node's {@linkplain #usages() usages}. * --- 350,371 ---- */ public final boolean hasUsages() { return this.usage0 != null; } ! /** ! * Checks whether this node has more than one usages. ! */ ! public final boolean hasMoreThanOneUsage() { ! return this.usage1 != null; } + + /** + * Checks whether this node has exactly one usgae. + */ + public final boolean hasExactlyOneUsage() { + return hasUsages() && !hasMoreThanOneUsage(); } /** * Adds a given node to this node's {@linkplain #usages() usages}. *
*** 531,548 **** if (isModificationCountsEnabled() && graph != null) { graph.incUsageModCount(this); } } ! public boolean isDeleted() { return id <= DELETED_ID_START; } ! public boolean isAlive() { return id >= ALIVE_ID_START; } /** * Updates the usages sets of the given nodes after an input slot is changed from * {@code oldInput} to {@code newInput} by removing this node from {@code oldInput}'s usages and * adds this node to {@code newInput}'s usages. */ --- 473,494 ---- if (isModificationCountsEnabled() && graph != null) { graph.incUsageModCount(this); } } ! public final boolean isDeleted() { return id <= DELETED_ID_START; } ! public final boolean isAlive() { return id >= ALIVE_ID_START; } + public final boolean isUnregistered() { + return id == INITIAL_ID; + } + /** * Updates the usages sets of the given nodes after an input slot is changed from * {@code oldInput} to {@code newInput} by removing this node from {@code oldInput}'s usages and * adds this node to {@code newInput}'s usages. */
*** 759,769 **** --- 705,717 ---- } public void replaceAndDelete(Node other) { assert checkReplaceWith(other); assert other != null; + if (this.hasUsages()) { replaceAtUsages(other); + } replaceAtPredecessor(other); this.safeDelete(); } public void replaceFirstSuccessor(Node oldSuccessor, Node newSuccessor) {
*** 850,865 **** */ private void copyOrClearEdgesForClone(Node newNode, Edges.Type type, EnumSet<Edges.Type> edgesToCopy) { if (edgesToCopy.contains(type)) { getNodeClass().getEdges(type).copy(this, newNode); } else { - if (USE_UNSAFE_TO_CLONE) { // The direct edges are already null getNodeClass().getEdges(type).initializeLists(newNode, this); - } else { - getNodeClass().getEdges(type).clear(newNode); - } } } public static final EnumSet<Edges.Type> WithNoEdges = EnumSet.noneOf(Edges.Type.class); public static final EnumSet<Edges.Type> WithAllEdges = EnumSet.allOf(Edges.Type.class); --- 798,809 ----
*** 889,914 **** } } Node newNode = null; try { - if (USE_UNSAFE_TO_CLONE) { newNode = (Node) UNSAFE.allocateInstance(getClass()); newNode.nodeClass = nodeClassTmp; nodeClassTmp.getData().copy(this, newNode); copyOrClearEdgesForClone(newNode, Inputs, edgesToCopy); copyOrClearEdgesForClone(newNode, Successors, edgesToCopy); - } else { - newNode = (Node) this.clone(); - newNode.typeCacheNext = null; - newNode.usage0 = null; - newNode.usage1 = null; - newNode.predecessor = null; - newNode.extraUsagesCount = 0; - copyOrClearEdgesForClone(newNode, Inputs, edgesToCopy); - copyOrClearEdgesForClone(newNode, Successors, edgesToCopy); - } } catch (Exception e) { throw new GraalGraphError(e).addContext(this); } newNode.graph = into; newNode.id = INITIAL_ID; --- 833,847 ----
*** 934,944 **** for (Position pos : inputPositions()) { Node input = pos.get(this); if (input == null) { assertTrue(pos.isInputOptional(), "non-optional input %s cannot be null in %s (fix nullness or use @OptionalInput)", pos, this); } else { ! assertFalse(input.isDeleted(), "input was deleted"); assertTrue(input.isAlive(), "input is not alive yet, i.e., it was not yet added to the graph"); assertTrue(pos.getInputType() == InputType.Unchecked || input.isAllowedUsageType(pos.getInputType()), "invalid usage type %s %s", input, pos.getInputType()); } } return true; --- 867,877 ---- for (Position pos : inputPositions()) { Node input = pos.get(this); if (input == null) { assertTrue(pos.isInputOptional(), "non-optional input %s cannot be null in %s (fix nullness or use @OptionalInput)", pos, this); } else { ! assertFalse(input.isDeleted(), "input was deleted %s", input); assertTrue(input.isAlive(), "input is not alive yet, i.e., it was not yet added to the graph"); assertTrue(pos.getInputType() == InputType.Unchecked || input.isAllowedUsageType(pos.getInputType()), "invalid usage type %s %s", input, pos.getInputType()); } } return true;
*** 946,956 **** public boolean verify() { assertTrue(isAlive(), "cannot verify inactive nodes (id=%d)", id); assertTrue(graph() != null, "null graph"); verifyInputs(); ! if (Options.VerifyGraalGraphEdges.getValue()) { verifyEdges(); } return true; } --- 879,889 ---- public boolean verify() { assertTrue(isAlive(), "cannot verify inactive nodes (id=%d)", id); assertTrue(graph() != null, "null graph"); verifyInputs(); ! if (Options.VerifyGraalGraphEdges.getValue(getOptions())) { verifyEdges(); } return true; }
*** 1026,1049 **** public Iterable<? extends Node> cfgSuccessors() { return successors(); } /** ! * Nodes always use an {@linkplain System#identityHashCode(Object) identity} hash code. */ @Override public final int hashCode() { ! return System.identityHashCode(this); } /** ! * Equality tests must rely solely on identity. */ - @Override - public final boolean equals(Object obj) { - return super.equals(obj); - } /** * Provides a {@link Map} of properties of this node for use in debugging (e.g., to view in the * ideal graph visualizer). */ --- 959,985 ---- public Iterable<? extends Node> cfgSuccessors() { return successors(); } /** ! * Nodes using their {@link #id} as the hash code. This works very well when nodes of the same ! * graph are stored in sets. It can give bad behavior when storing nodes of different graphs in ! * the same set. */ @Override public final int hashCode() { ! assert !this.isUnregistered() : "node not yet constructed"; ! if (this.isDeleted()) { ! return -id + DELETED_ID_START; ! } ! return id; } /** ! * Do not overwrite the equality test of a node in subclasses. Equality tests must rely solely ! * on identity. */ /** * Provides a {@link Map} of properties of this node for use in debugging (e.g., to view in the * ideal graph visualizer). */
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File