changeset 18379:3aaf2747961c

use LinkedHashSets for node sets when created within the scope of a replay compilation context
author Doug Simon <doug.simon@oracle.com>
date Fri, 14 Nov 2014 19:16:08 +0100
parents c57c3777fa72
children 601dfbdcc5bf
files graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ValueAnchorCleanupPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/util/HashSetNodeEventListener.java graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java
diffstat 6 files changed, 51 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Fri Nov 14 16:26:38 2014 +0100
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Fri Nov 14 19:16:08 2014 +0100
@@ -31,13 +31,14 @@
 import sun.misc.*;
 
 import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.compiler.common.remote.*;
 import com.oracle.graal.graph.Graph.NodeEventListener;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodeinfo.*;
 
 /**
- * This class is the base class for all nodes, it represent a node which can be inserted in a
+ * This class is the base class for all nodes. It represents a node that can be inserted in a
  * {@link Graph}.
  * <p>
  * Once a node has been added to a graph, it has a graph-unique {@link #id()}. Edges in the
@@ -48,6 +49,11 @@
  * <p>
  * Nodes which are be value numberable should implement the {@link ValueNumberable} interface.
  *
+ * <h1>Replay Compilation</h1>
+ *
+ * To enable deterministic replay compilation, node hash set creation within a compilation scope
+ * must {@link #newNodeHashSet()} or {@link #newNodeHashSet(Collection)}.
+ *
  * <h1>Assertions and Verification</h1>
  *
  * The Node class supplies the {@link #assertTrue(boolean, String, Object...)} and
@@ -193,6 +199,22 @@
     }
 
     /**
+     * Creates a {@link Node} hash set. The return set will be a {@link LinkedHashSet} if the
+     * current thread has an active compilation replay scope. This is requires to make replay
+     * compilations deterministic.
+     */
+    public static <E extends Node> HashSet<E> newNodeHashSet() {
+        return Context.getCurrent() == null ? new HashSet<>() : new LinkedHashSet<>();
+    }
+
+    /**
+     * @see #newNodeHashSet()
+     */
+    public static <E extends Node> HashSet<E> newNodeHashSet(Collection<? extends E> c) {
+        return Context.getCurrent() == null ? new HashSet<>(c) : new LinkedHashSet<>(c);
+    }
+
+    /**
      * Gets the graph context of this node.
      */
     public Graph graph() {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Fri Nov 14 16:26:38 2014 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Fri Nov 14 19:16:08 2014 +0100
@@ -434,7 +434,7 @@
 
             // build the intersection
             belowBound.intersect(aboveBound);
-            HashSet<Node> result = new HashSet<>();
+            HashSet<Node> result = Node.newNodeHashSet();
             for (Node node : belowBound) {
                 result.add(node);
             }
@@ -491,7 +491,7 @@
         }
 
         private void processUsages(Node duplicated, HashSet<Node> duplicatedNodes, MergeNode newBottomMerge, Deque<Node> worklist) {
-            HashSet<Node> unique = new HashSet<>();
+            HashSet<Node> unique = Node.newNodeHashSet();
             duplicated.usages().snapshotTo(unique);
             Node newOutsideClone = null;
             for (Node usage : unique) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ValueAnchorCleanupPhase.java	Fri Nov 14 16:26:38 2014 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ValueAnchorCleanupPhase.java	Fri Nov 14 19:16:08 2014 +0100
@@ -42,11 +42,11 @@
         private final HashSet<Node> anchoredValues;
 
         public State() {
-            anchoredValues = new HashSet<>();
+            anchoredValues = Node.newNodeHashSet();
         }
 
         public State(State other) {
-            anchoredValues = new HashSet<>(other.anchoredValues);
+            anchoredValues = Node.newNodeHashSet(other.anchoredValues);
         }
 
         @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Fri Nov 14 16:26:38 2014 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Fri Nov 14 19:16:08 2014 +0100
@@ -22,37 +22,28 @@
  */
 package com.oracle.graal.phases.common.inlining.walker;
 
-import com.oracle.graal.api.code.Assumptions;
-import com.oracle.graal.api.code.BailoutException;
-import com.oracle.graal.api.meta.JavaTypeProfile;
-import com.oracle.graal.api.meta.ResolvedJavaMethod;
-import com.oracle.graal.api.meta.ResolvedJavaType;
-import com.oracle.graal.compiler.common.GraalInternalError;
-import com.oracle.graal.compiler.common.type.ObjectStamp;
-import com.oracle.graal.debug.Debug;
-import com.oracle.graal.debug.DebugMetric;
-import com.oracle.graal.graph.Graph;
-import com.oracle.graal.graph.Node;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.AbstractNewObjectNode;
-import com.oracle.graal.nodes.java.MethodCallTargetNode;
-import com.oracle.graal.nodes.virtual.AllocatedObjectNode;
-import com.oracle.graal.nodes.virtual.VirtualObjectNode;
-import com.oracle.graal.phases.OptimisticOptimizations;
-import com.oracle.graal.phases.common.CanonicalizerPhase;
-import com.oracle.graal.phases.common.inlining.InliningUtil;
-import com.oracle.graal.phases.common.inlining.info.*;
-import com.oracle.graal.phases.common.inlining.info.elem.Inlineable;
-import com.oracle.graal.phases.common.inlining.info.elem.InlineableGraph;
-import com.oracle.graal.phases.common.inlining.info.elem.InlineableMacroNode;
-import com.oracle.graal.phases.common.inlining.policy.InliningPolicy;
-import com.oracle.graal.phases.tiers.HighTierContext;
-import com.oracle.graal.phases.util.Providers;
+import static com.oracle.graal.compiler.common.GraalOptions.*;
+import static com.oracle.graal.phases.common.inlining.walker.CallsiteHolderDummy.*;
 
 import java.util.*;
 
-import static com.oracle.graal.compiler.common.GraalOptions.*;
-import static com.oracle.graal.phases.common.inlining.walker.CallsiteHolderDummy.DUMMY_CALLSITE_HOLDER;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.virtual.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.common.inlining.*;
+import com.oracle.graal.phases.common.inlining.info.*;
+import com.oracle.graal.phases.common.inlining.info.elem.*;
+import com.oracle.graal.phases.common.inlining.policy.*;
+import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 
 /**
  * <p>
@@ -368,7 +359,7 @@
         InlineInfo calleeInfo = calleeInvocation.callee();
         try {
             try (Debug.Scope scope = Debug.scope("doInline", callerGraph)) {
-                Set<Node> canonicalizedNodes = new HashSet<>();
+                Set<Node> canonicalizedNodes = Node.newNodeHashSet();
                 calleeInfo.invoke().asNode().usages().snapshotTo(canonicalizedNodes);
                 Collection<Node> parameterUsages = calleeInfo.inline(new Providers(context), callerAssumptions);
                 canonicalizedNodes.addAll(parameterUsages);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/util/HashSetNodeEventListener.java	Fri Nov 14 16:26:38 2014 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/util/HashSetNodeEventListener.java	Fri Nov 14 19:16:08 2014 +0100
@@ -40,7 +40,7 @@
      * Creates a {@link NodeEventListener} that collects nodes from all events.
      */
     public HashSetNodeEventListener() {
-        this.nodes = new HashSet<>();
+        this.nodes = Node.newNodeHashSet();
         this.filter = EnumSet.allOf(NodeEvent.class);
     }
 
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java	Fri Nov 14 16:26:38 2014 +0100
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java	Fri Nov 14 19:16:08 2014 +0100
@@ -84,7 +84,7 @@
     @Override
     public void print(Graph graph, String title, SchedulePhase predefinedSchedule) {
         beginGraph(title);
-        Set<Node> noBlockNodes = new HashSet<>();
+        Set<Node> noBlockNodes = Node.newNodeHashSet();
         SchedulePhase schedule = predefinedSchedule;
         if (schedule == null && tryToSchedule) {
             if (PrintIdealGraphSchedule.getValue()) {
@@ -249,7 +249,7 @@
         endSuccessors();
         beginBlockNodes();
 
-        Set<Node> nodes = new HashSet<>();
+        Set<Node> nodes = Node.newNodeHashSet();
 
         if (nodeToBlock != null) {
             for (Node n : graph.getNodes()) {
@@ -270,7 +270,7 @@
                 }
             }
 
-            Set<Node> snapshot = new HashSet<>(nodes);
+            Set<Node> snapshot = Node.newNodeHashSet(nodes);
             // add all framestates and phis to their blocks
             for (Node node : snapshot) {
                 if (node instanceof StateSplit && ((StateSplit) node).stateAfter() != null) {