# HG changeset patch # User Tom Rodriguez # Date 1406162175 25200 # Node ID c62c1e0060cce9bb09ac9465d3a97f55b87254a7 # Parent 6bdd2ec553eb4879c483570389f4c756b296b157 Don't allow infinite loops to explode loop frequencies diff -r 6bdd2ec553eb -r c62c1e0060cc graal/com.oracle.graal.java/src/com/oracle/graal/java/ComputeLoopFrequenciesClosure.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/ComputeLoopFrequenciesClosure.java Wed Jul 23 15:01:58 2014 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/ComputeLoopFrequenciesClosure.java Wed Jul 23 17:36:15 2014 -0700 @@ -22,6 +22,8 @@ */ package com.oracle.graal.java; +import static com.oracle.graal.nodes.cfg.ControlFlowGraph.*; + import java.util.*; import java.util.stream.*; @@ -30,7 +32,6 @@ public class ComputeLoopFrequenciesClosure extends ReentrantNodeIterator.NodeIteratorClosure { - private static final double EPSILON = Double.MIN_NORMAL; private static final ComputeLoopFrequenciesClosure INSTANCE = new ComputeLoopFrequenciesClosure(); private ComputeLoopFrequenciesClosure() { @@ -62,8 +63,8 @@ double exitProbability = exitStates.values().stream().mapToDouble(d -> d).sum(); assert exitProbability <= 1D && exitProbability >= 0D; - if (exitProbability < EPSILON) { - exitProbability = EPSILON; + if (exitProbability < MIN_PROBABILITY) { + exitProbability = MIN_PROBABILITY; } double loopFrequency = 1D / exitProbability; loop.setLoopFrequency(loopFrequency); @@ -75,14 +76,14 @@ } /** - * Multiplies a and b and saturates the result to 1/{@link Double#MIN_NORMAL}. + * Multiplies a and b and saturates the result to 1/{@link #MIN_PROBABILITY}. * - * @return a times b saturated to 1/{@link Double#MIN_NORMAL} + * @return a times b saturated to 1/{@link #MIN_PROBABILITY} */ public static double multiplySaturate(double a, double b) { double r = a * b; - if (r > 1 / Double.MIN_NORMAL) { - return 1 / Double.MIN_NORMAL; + if (r > 1 / MIN_PROBABILITY) { + return 1 / MIN_PROBABILITY; } return r; } diff -r 6bdd2ec553eb -r c62c1e0060cc graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Wed Jul 23 15:01:58 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Wed Jul 23 17:36:15 2014 -0700 @@ -31,6 +31,12 @@ import com.oracle.graal.nodes.*; public class ControlFlowGraph implements AbstractControlFlowGraph { + /** + * Don't allow probability values to be become too small as this makes frequency calculations + * large enough that they can overflow the range of a double. This commonly happens with + * infinite loops within infinite loops. + */ + public static final double MIN_PROBABILITY = 0.000001; public final StructuredGraph graph; @@ -221,8 +227,8 @@ } } } - if (probability > 1. / Double.MIN_NORMAL) { - probability = 1. / Double.MIN_NORMAL; + if (probability > 1. / MIN_PROBABILITY) { + probability = 1. / MIN_PROBABILITY; } block.setPredecessors(predecessors); block.setProbability(probability); diff -r 6bdd2ec553eb -r c62c1e0060cc graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/FixedNodeProbabilityCache.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/FixedNodeProbabilityCache.java Wed Jul 23 15:01:58 2014 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/FixedNodeProbabilityCache.java Wed Jul 23 17:36:15 2014 -0700 @@ -114,6 +114,7 @@ ControlSplitNode split = (ControlSplitNode) current.predecessor(); probability = split.probability((BeginNode) current) * applyAsDouble(split); } + assert !Double.isNaN(probability) && !Double.isInfinite(probability) : current + " " + probability; cache.put(current, probability); return probability; } diff -r 6bdd2ec553eb -r c62c1e0060cc graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Wed Jul 23 15:01:58 2014 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Wed Jul 23 17:36:15 2014 -0700 @@ -410,7 +410,11 @@ NodeClass nodeClass = node.getNodeClass(); node.getDebugProperties(props); if (probabilities != null && node instanceof FixedNode) { - props.put("probability", probabilities.applyAsDouble((FixedNode) node)); + try { + props.put("probability", probabilities.applyAsDouble((FixedNode) node)); + } catch (Throwable t) { + props.put("probability", t); + } } writeInt(getNodeId(node)); writePoolObject(nodeClass);