changeset 22636:96e21d85bea9

improve GraphPE error reporting add an approximate stack trace to partial evaluation exceptions add missing check for maximum loop explosion iteration count
author Andreas Woess <andreas.woess@oracle.com>
date Tue, 15 Sep 2015 21:10:57 +0200
parents d3506b8c85b6
children 4dab2545d435
files graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphDecoder.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java
diffstat 4 files changed, 37 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java	Tue Sep 15 17:05:35 2015 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java	Tue Sep 15 21:10:57 2015 +0200
@@ -2083,12 +2083,7 @@
                 }
                 context.targetPeelIteration[context.targetPeelIteration.length - 1] = nextPeelIteration++;
                 if (nextPeelIteration > MaximumLoopExplosionCount.getValue()) {
-                    String message = "too many loop explosion iterations - does the explosion not terminate for method " + method + "?";
-                    if (FailedLoopExplosionIsFatal.getValue()) {
-                        throw new RuntimeException(message);
-                    } else {
-                        throw bailout(message);
-                    }
+                    throw tooManyLoopExplosionIterations();
                 }
 
                 // Operate on the target dimension.
@@ -2103,6 +2098,15 @@
         return 0;
     }
 
+    private RuntimeException tooManyLoopExplosionIterations() {
+        String message = "too many loop explosion iterations - does the explosion not terminate for method " + method + "?";
+        if (FailedLoopExplosionIsFatal.getValue()) {
+            throw new RuntimeException(message);
+        } else {
+            throw bailout(message);
+        }
+    }
+
     /**
      * Returns a block begin node with the specified state. If the specified probability is 0, the
      * block deoptimizes immediately.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphDecoder.java	Tue Sep 15 17:05:35 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphDecoder.java	Tue Sep 15 21:10:57 2015 +0200
@@ -524,6 +524,7 @@
             int nextIterationNumber = loopScope.nextIterations.isEmpty() ? loopScope.loopIteration + 1 : loopScope.nextIterations.getLast().loopIteration + 1;
             LoopScope nextIterationScope = new LoopScope(loopScope.outer, loopScope.loopDepth, nextIterationNumber, loopScope.loopBeginOrderId, loopScope.initialCreatedNodes,
                             loopScope.nextIterations, loopScope.iterationStates);
+            checkLoopExplosionIteration(methodScope, nextIterationScope);
             loopScope.nextIterations.addLast(nextIterationScope);
             registerNode(nextIterationScope, loopScope.loopBeginOrderId, null, true, true);
             makeStubNode(methodScope, nextIterationScope, loopScope.loopBeginOrderId);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Tue Sep 15 17:05:35 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Tue Sep 15 21:10:57 2015 +0200
@@ -329,6 +329,22 @@
     }
 
     /**
+     * Gets approximate stack trace elements for a bytecode position.
+     */
+    public static StackTraceElement[] approxSourceStackTraceElement(BytecodePosition bytecodePosition) {
+        ArrayList<StackTraceElement> elements = new ArrayList<>();
+        BytecodePosition position = bytecodePosition;
+        while (position != null) {
+            ResolvedJavaMethod method = position.getMethod();
+            if (method != null) {
+                elements.add(method.asStackTraceElement(position.getBCI()));
+            }
+            position = position.getCaller();
+        }
+        return elements.toArray(new StackTraceElement[0]);
+    }
+
+    /**
      * Gets an approximate source code location for a node, encoded as an exception, if possible.
      *
      * @return the exception with the location
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java	Tue Sep 15 17:05:35 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java	Tue Sep 15 21:10:57 2015 +0200
@@ -47,6 +47,7 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.util.GraphUtil;
 import com.oracle.graal.phases.common.inlining.*;
 
 /**
@@ -129,7 +130,8 @@
 
         @Override
         public BailoutException bailout(String string) {
-            throw new BailoutException(string);
+            BailoutException bailout = new BailoutException(string);
+            throw GraphUtil.createBailoutException(string, bailout, GraphUtil.approxSourceStackTraceElement(methodScope.getBytecodePosition()));
         }
 
         @Override
@@ -321,15 +323,16 @@
         PEMethodScope methodScope = (PEMethodScope) s;
 
         if (loopScope.loopIteration > MaximumLoopExplosionCount.getValue()) {
-            String message = "too many loop explosion iterations - does the explosion not terminate for method " + methodScope.method + "?";
-            if (FailedLoopExplosionIsFatal.getValue()) {
-                throw new RuntimeException(message);
-            } else {
-                throw new BailoutException(message);
-            }
+            throw tooManyLoopExplosionIterations(methodScope);
         }
     }
 
+    private static RuntimeException tooManyLoopExplosionIterations(PEMethodScope methodScope) {
+        String message = "too many loop explosion iterations - does the explosion not terminate for method " + methodScope.method + "?";
+        RuntimeException bailout = FailedLoopExplosionIsFatal.getValue() ? new RuntimeException(message) : new BailoutException(message);
+        throw GraphUtil.createBailoutException(message, bailout, GraphUtil.approxSourceStackTraceElement(methodScope.getBytecodePosition()));
+    }
+
     @Override
     protected void handleInvoke(MethodScope s, LoopScope loopScope, InvokeData invokeData) {
         PEMethodScope methodScope = (PEMethodScope) s;