Choosing the best inference leaf is non-deterministic
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Tue Oct 10 00:02:58 UTC 2017
Sure - we had other issues in this vein - determinism trumps every other
possible use case in this area; dependencies should be stored in a data
structure that preserves insertion order.
That said, since the algorithm for creating an inference graph is
deterministic - and we end up adding same elements in same order - while
I buy that the iteration order of the dependencies will not reflect the
insertion order, shouldn't it at least be stable?
But then, I note that InferenceGraph.Node doesn't override
equals/hashcode, so that's definitively a possible cause for
non-determinism - if default Object.hash changes, items will be inserted
in the set in different ways, leading to different iteration orders.
Maurizio
On 09/10/17 22:37, B. Blaser wrote:
> Hi,
>
> While working on [1], I noticed that choosing the best inference leaf
> to be solved is non-deterministic because 'computeTreeToLeafs()'
> iterates on the node dependencies [2] which are stored in an 'HashSet'
> with unpredictable iteration order.
>
> I think this is a bit dangerous and could lead to unreproducible
> errors as the leaves' solving order within a subtree is unpredictable.
> I suggest to use a 'TreeSet' instead with predictable iteration order
> even if the operations are in O(log(n)) vs O(1) for the 'HashSet'.
> This shouldn't make too much difference with a low average number of
> dependencies per node.
>
> What do you think?
>
> Thanks,
> Bernard
>
> [1] http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011156.html
> [2] http://hg.openjdk.java.net/jdk10/master/file/6cb6ef406e97/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java#l1382
>
>
> diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
> @@ -59,6 +59,7 @@
> import java.util.EnumSet;
> import java.util.HashMap;
> import java.util.HashSet;
> +import java.util.TreeSet;
> import java.util.Map;
> import java.util.Optional;
> import java.util.Properties;
> @@ -1705,11 +1706,11 @@
> class Node extends
> GraphUtils.TarjanNode<ListBuffer<Type>, Node> implements
> DottableNode<ListBuffer<Type>, Node> {
>
> /** node dependencies */
> - Set<Node> deps;
> + TreeSet<Node> deps;
>
> Node(Type ivar) {
> super(ListBuffer.of(ivar));
> - this.deps = new HashSet<>();
> + this.deps = new TreeSet<>();
> }
>
> @Override
> @@ -1780,7 +1781,7 @@
> addDependencies(n.deps);
> }
> //update deps
> - Set<Node> deps2 = new HashSet<>();
> + TreeSet<Node> deps2 = new TreeSet<>();
> for (Node d : deps) {
> if (data.contains(d.data.first())) {
> deps2.add(this);
More information about the compiler-dev
mailing list