8158650: [jittester] when generating tests with default parameters, generation hangs after 98 test
authordpochepk
Thu, 23 Jun 2016 17:39:06 +0300
changeset 39445 0ff6e5517504
parent 39443 ca6dfb34e46c
child 39446 690677aa4a48
8158650: [jittester] when generating tests with default parameters, generation hangs after 98 test Reviewed-by: kvn, iignatyev
hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/IRNode.java
hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ClassDefinitionBlockFactory.java
hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/MainKlassFactory.java
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/IRNode.java	Thu Jun 23 05:13:55 2016 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/IRNode.java	Thu Jun 23 17:39:06 2016 +0300
@@ -198,6 +198,31 @@
         return result;
     }
 
+    public static long getModifiableNodesCount(List<IRNode> nodes) {
+        return nodes.stream()
+                .map(IRNode::getStackableLeaves)
+                .mapToInt(List::size)
+                .filter(i -> i > 0)
+                .count();
+    }
+
+    public static boolean tryToReduceNodesDepth(List<IRNode> nodes, int maxDepth) {
+        boolean allSucceed = true;
+        for (IRNode child : nodes) {
+            for (IRNode leaf : child.getDeviantBlocks(Math.max(child.countDepth(), maxDepth + 1))) {
+                if (child.countDepth() > maxDepth) {
+                    // doesn't remove control deviation block. Just some parts.
+                    leaf.removeSelf();
+                    boolean successfull = child.countDepth() > maxDepth;
+                    allSucceed &= successfull;
+                } else {
+                    break;
+                }
+            }
+        }
+        return allSucceed;
+    }
+
     // TODO: add field instead this function
     public boolean isCFDeviation() {
         return this instanceof If || this instanceof Switch
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ClassDefinitionBlockFactory.java	Thu Jun 23 05:13:55 2016 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ClassDefinitionBlockFactory.java	Thu Jun 23 17:39:06 2016 +0300
@@ -102,11 +102,16 @@
         addMoreChildren(childs, content, minDepth);
     }
 
-    private void addMoreChildren(List<IRNode> childs, Collection<IRNode> content, int minDepth)
-        throws ProductionFailedException {
-        while (!childs.isEmpty() && IRNode.countDepth(content) < minDepth) {
-            PseudoRandom.shuffle(childs);
-            IRNode randomChild = childs.get(0);
+    private void addMoreChildren(List<IRNode> children, Collection<IRNode> content, int minDepth)
+            throws ProductionFailedException {
+        /* check situation when no stackable leaves available in all children */
+        if (IRNode.getModifiableNodesCount(children) == 0L) {
+            return;
+        }
+        /* now let's try to add children */
+        while (!children.isEmpty() && IRNode.countDepth(content) < minDepth) {
+            PseudoRandom.shuffle(children);
+            IRNode randomChild = children.get(0);
             List<IRNode> leaves = randomChild.getStackableLeaves();
             if (!leaves.isEmpty()) {
                 Block randomLeaf = (Block) leaves.get(PseudoRandom.randomNotNegative(leaves.size()));
@@ -131,18 +136,11 @@
 
     private void ensureMaxDepth(Collection<IRNode> content) {
         int maxDepth = ProductionParams.maxCfgDepth.value();
-        List<IRNode> childs = content.stream()
+        List<IRNode> childrenClasses = content.stream()
                 .filter(c -> c instanceof Klass && c.countDepth() > maxDepth)
                 .collect(Collectors.toList());
-        for (IRNode ch : childs) {
-            List<IRNode> leaves;
-            do {
-                long depth = Math.max(ch.countDepth(), maxDepth + 1);
-                leaves = ch.getDeviantBlocks(depth);
-                if(leaves.size() > 0) {
-                    leaves.get(0).removeSelf();
-                }
-            } while (!leaves.isEmpty() && ch.countDepth() > maxDepth);
-        }
+        /* now attempt to reduce depth by removing optional parts of control deviation
+           blocks in case IRTree has oversized depth */
+        IRNode.tryToReduceNodesDepth(childrenClasses, maxDepth);
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/MainKlassFactory.java	Thu Jun 23 05:13:55 2016 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/MainKlassFactory.java	Thu Jun 23 17:39:06 2016 +0300
@@ -112,19 +112,14 @@
                 functionDefinitions, testFunction, printVariables);
     }
 
-    private void ensureMaxDepth(List<IRNode> childs) {
+    private void ensureMaxDepth(List<IRNode> children) {
         int maxDepth = ProductionParams.maxCfgDepth.value();
-        List<IRNode> filtered = childs.stream()
-            .filter(c -> c.isCFDeviation() && c.countDepth() > maxDepth)
-            .collect(Collectors.toList());
-        for (IRNode child : filtered) {
-            List<IRNode> leaves;
-            do {
-                long depth = Math.max(child.countDepth(), maxDepth + 1);
-                leaves = child.getDeviantBlocks(depth);
-                leaves.get(0).removeSelf();
-            } while (!leaves.isEmpty() && child.countDepth() > maxDepth);
-        }
+        List<IRNode> filtered = children.stream()
+                .filter(c -> c.isCFDeviation() && c.countDepth() > maxDepth)
+                .collect(Collectors.toList());
+        /* Now attempt to reduce depth by removing optional parts of control deviation
+           blocks in case IRTree has oversized depth */
+        IRNode.tryToReduceNodesDepth(filtered, maxDepth);
     }
 
     private void ensureMinDepth(List<IRNode> childs, IRNodeBuilder builder)
@@ -134,10 +129,15 @@
         addMoreChildren(filtered, minDepth, builder);
     }
 
-    private void addMoreChildren(List<IRNode> childs, int minDepth, IRNodeBuilder builder)
+    private void addMoreChildren(List<IRNode> children, int minDepth, IRNodeBuilder builder)
             throws ProductionFailedException {
-        while (!childs.isEmpty() && IRNode.countDepth(childs) < minDepth) {
-            IRNode randomChild = childs.get(PseudoRandom.randomNotNegative(childs.size()));
+        /* check situation when no stackable leaves available in all children */
+        if (IRNode.getModifiableNodesCount(children) == 0L) {
+            return;
+        }
+        /* now let's try to add children */
+        while (!children.isEmpty() && IRNode.countDepth(children) < minDepth) {
+            IRNode randomChild = children.get(PseudoRandom.randomNotNegative(children.size()));
             List<IRNode> leaves = randomChild.getStackableLeaves();
             if (!leaves.isEmpty()) {
                 Block randomLeaf = (Block) leaves.get(PseudoRandom.randomNotNegative(leaves.size()));