Mercurial > hg > graal-compiler
diff graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java @ 18383:1518c3296cc8
use deterministic iteration order Set and Map data structures when in the scope of a replay compilation context
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Sun, 16 Nov 2014 09:44:04 +0100 |
parents | 3aaf2747961c |
children | 86269e451920 |
line wrap: on
line diff
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Sat Nov 15 23:19:58 2014 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Sun Nov 16 09:44:04 2014 +0100 @@ -51,8 +51,18 @@ * * <h1>Replay Compilation</h1> * - * To enable deterministic replay compilation, node hash set creation within a compilation scope - * must {@link #newNodeHashSet()} or {@link #newNodeHashSet(Collection)}. + * 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> * @@ -199,21 +209,58 @@ } /** - * 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. + * Creates a {@link Node} set. If the current thread has a non-null + * {@linkplain Context#getCurrent() compilation replay scope}, the returned set will have a + * deterministic iteration order determined by the order in which elements are inserted in the + * map. */ - public static <E extends Node> HashSet<E> newNodeHashSet() { + public static <E extends Node> Set<E> newSet() { return Context.getCurrent() == null ? new HashSet<>() : new LinkedHashSet<>(); } /** - * @see #newNodeHashSet() + * @see #newSet() */ - public static <E extends Node> HashSet<E> newNodeHashSet(Collection<? extends E> c) { + public static <E extends Node> Set<E> newSet(Collection<? extends E> c) { return Context.getCurrent() == null ? new HashSet<>(c) : new LinkedHashSet<>(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 Context.newIdentityMap(); + } + + public static <K extends Node, V> Map<K, V> newIdentityMap(Map<K, V> m) { + return Context.newIdentityMap(m); + } + + public static <K extends Node, V> Map<K, V> newIdentityMap(int expectedMaxSize) { + return Context.newIdentityMap(expectedMaxSize); + } + /** * Gets the graph context of this node. */