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
*** old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java Mon Mar 20 17:38:00 2017
--- new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java Mon Mar 20 17:38:00 2017
*** 27,50 ****
--- 27,46 ----
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;
*** 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 ****
--- 66,75 ----
* {@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
*** 96,106 ****
--- 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 = Graph.Options.CloneNodesWithUnsafe.getValue();
! 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 ****
--- 238,258 ----
public Node asNode() {
return this;
}
/**
* @see CollectionsFactory#newSet()
*/
public static <E extends Node> Set<E> newSet() {
return CollectionsFactory.newSet();
}
/**
* @see #newSet()
+ * Gets the graph context of this node.
*/
! 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);
! public Graph graph() {
! return graph;
}
/**
! * Gets the graph context of this node.
! * Gets the option values associated with this node's graph.
*/
! public Graph graph() {
! return 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 ****
--- 350,371 ----
*/
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);
+ /**
+ * 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 ****
--- 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 ****
--- 798,809 ----
*/
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);
*** 889,914 ****
--- 833,847 ----
}
}
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;
*** 934,944 ****
--- 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 ****
--- 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 ****
--- 959,985 ----
public Iterable<? extends Node> cfgSuccessors() {
return successors();
}
/**
! * Nodes always use an {@linkplain System#identityHashCode(Object) identity} hash code.
! * 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() {
! return System.identityHashCode(this);
! assert !this.isUnregistered() : "node not yet constructed";
+ if (this.isDeleted()) {
+ return -id + DELETED_ID_START;
+ }
+ return id;
}
/**
* Equality tests must rely solely on identity.
+ * Do not overwrite the equality test of a node in subclasses. 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).
*/
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