changeset 22244:92e1be818769

Truffle: add PE regression tests to prevent deoptimization on ControlFlowException
author Andreas Woess <andreas.woess@oracle.com>
date Mon, 20 Jul 2015 03:12:06 +0200
parents 6670754e4bf3
children bdfbff780167
files graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ControlFlowExceptionPartialEvaluationTest.java
diffstat 1 files changed, 55 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ControlFlowExceptionPartialEvaluationTest.java	Mon Jul 20 02:48:57 2015 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ControlFlowExceptionPartialEvaluationTest.java	Mon Jul 20 03:12:06 2015 +0200
@@ -24,7 +24,9 @@
 
 import org.junit.*;
 
+import com.oracle.graal.truffle.*;
 import com.oracle.graal.truffle.test.nodes.*;
+import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.nodes.*;
 
@@ -47,6 +49,21 @@
         assertPartialEvalEquals("constant42", new RootTestNode(fd, "catchSlowPathAndControlFlowException", result));
     }
 
+    @Test
+    public void catchControlFlowExceptionWithLoopExplosion() {
+        FrameDescriptor fd = new FrameDescriptor();
+        AbstractTestNode result = new CatchControlFlowExceptionTestNode(new BlockTestNode(new ThrowControlFlowExceptionTestNode()));
+        assertPartialEvalEquals("constant42", new RootTestNode(fd, "catchControlFlowExceptionWithLoopExplosion", result));
+    }
+
+    @Test
+    public void catchControlFlowExceptionFromCall() {
+        Assume.assumeTrue(TruffleCompilerOptions.TruffleFunctionInlining.getValue());
+        CallTarget callTarget = Truffle.getRuntime().createCallTarget(new RootTestNode(new FrameDescriptor(), "throwControlFlowException", new ThrowControlFlowExceptionTestNode()));
+        AbstractTestNode result = new CatchControlFlowExceptionTestNode(new CallTestNode(callTarget));
+        assertPartialEvalEquals("constant42", new RootTestNode(new FrameDescriptor(), "catchControlFlowExceptionFromCall", result));
+    }
+
     public static class ThrowControlFlowExceptionTestNode extends AbstractTestNode {
         @Override
         public int execute(VirtualFrame frame) {
@@ -94,4 +111,42 @@
             return child.execute(frame);
         }
     }
+
+    public static class BlockTestNode extends AbstractTestNode {
+        @Children private final AbstractTestNode[] statements;
+
+        public BlockTestNode(AbstractTestNode... statements) {
+            this.statements = statements;
+        }
+
+        @Override
+        public int execute(VirtualFrame frame) {
+            return executeSpecial(frame);
+        }
+
+        /*
+         * A statically resolvable method, so that ExplodeLoop annotation is visible during parsing.
+         */
+        @ExplodeLoop
+        private int executeSpecial(VirtualFrame frame) {
+            int result = 0;
+            for (AbstractTestNode statement : statements) {
+                result = statement.execute(frame);
+            }
+            return result;
+        }
+    }
+
+    public static class CallTestNode extends AbstractTestNode {
+        @Child private DirectCallNode callNode;
+
+        public CallTestNode(CallTarget callTarget) {
+            this.callNode = Truffle.getRuntime().createDirectCallNode(callTarget);
+        }
+
+        @Override
+        public int execute(VirtualFrame frame) {
+            return (int) callNode.call(frame, new Object[0]);
+        }
+    }
 }