comparison graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java @ 13836:64c77f0577bb

More documentation and improvements of Simple Language
author Christian Wimmer <christian.wimmer@oracle.com>
date Thu, 30 Jan 2014 17:53:27 -0800
parents b16ec83edc73
children f9b934e1e172
comparison
equal deleted inserted replaced
13835:67e4e7f56911 13836:64c77f0577bb
30 import com.oracle.truffle.sl.nodes.*; 30 import com.oracle.truffle.sl.nodes.*;
31 31
32 @NodeInfo(shortName = "while") 32 @NodeInfo(shortName = "while")
33 public class SLWhileNode extends SLStatementNode { 33 public class SLWhileNode extends SLStatementNode {
34 34
35 /**
36 * The condition of the loop. This in a {@link SLExpressionNode} because we require a result
37 * value. We do not have a node type that can only return a {@code boolean} value, so
38 * {@link #evaluateCondition executing the condition} can lead to a type error.
39 */
35 @Child private SLExpressionNode conditionNode; 40 @Child private SLExpressionNode conditionNode;
41
42 /** Statement (or {@SLBlockNode block}) executed as long as the condition is true. */
36 @Child private SLStatementNode bodyNode; 43 @Child private SLStatementNode bodyNode;
37 44
45 /**
46 * Profiling information, collected by the interpreter, capturing whether a {@code continue}
47 * statement was used in this loop. This allows the compiler to generate better code for loops
48 * without a {@code continue}.
49 */
38 private final BranchProfile continueTaken = new BranchProfile(); 50 private final BranchProfile continueTaken = new BranchProfile();
39 private final BranchProfile breakTaken = new BranchProfile(); 51 private final BranchProfile breakTaken = new BranchProfile();
40 52
41 public SLWhileNode(SLExpressionNode conditionNode, SLStatementNode bodyNode) { 53 public SLWhileNode(SLExpressionNode conditionNode, SLStatementNode bodyNode) {
54 /*
55 * It is a Truffle requirement to call adoptChild(), which performs all the necessary steps
56 * to add the new child to the node tree.
57 */
42 this.conditionNode = adoptChild(conditionNode); 58 this.conditionNode = adoptChild(conditionNode);
43 this.bodyNode = adoptChild(bodyNode); 59 this.bodyNode = adoptChild(bodyNode);
44 } 60 }
45 61
46 @Override 62 @Override
47 public void executeVoid(VirtualFrame frame) { 63 public void executeVoid(VirtualFrame frame) {
48 int count = 0; 64 int count = 0;
49 try { 65 try {
50 while (evaluateCondition(frame)) { 66 while (evaluateCondition(frame)) {
51 try { 67 try {
68 /* Execute the loop body. */
52 bodyNode.executeVoid(frame); 69 bodyNode.executeVoid(frame);
70
53 if (CompilerDirectives.inInterpreter()) { 71 if (CompilerDirectives.inInterpreter()) {
72 /* In the interpreter, profile the the number of loop iteration. */
54 count++; 73 count++;
55 } 74 }
56 } catch (SLContinueException ex) { 75 } catch (SLContinueException ex) {
76 /* In the interpreter, record profiling information that the loop uses continue. */
57 continueTaken.enter(); 77 continueTaken.enter();
58 /* Fall through to next loop iteration. */ 78 /* Fall through to next loop iteration. */
59 } 79 }
60 } 80 }
61 } catch (SLBreakException ex) { 81 } catch (SLBreakException ex) {
82 /* In the interpreter, record profiling information that the loop uses break. */
62 breakTaken.enter(); 83 breakTaken.enter();
63 /* Done executing this loop, exit method to execute statement following the loop. */ 84 /* Done executing this loop, exit method to execute statement following the loop. */
85
64 } finally { 86 } finally {
65 if (CompilerDirectives.inInterpreter()) { 87 if (CompilerDirectives.inInterpreter()) {
66 /* 88 /*
67 * Report the loop count to the Truffle system. It is used for compilation and 89 * In the interpreter, report the loop count to the Truffle system. It is used for
68 * inlining decisions. 90 * compilation and inlining decisions.
69 */ 91 */
70 RootNode root = getRootNode(); 92 getRootNode().reportLoopCount(count);
71 if (root.getCallTarget() instanceof LoopCountReceiver) {
72 ((LoopCountReceiver) root.getCallTarget()).reportLoopCount(count);
73 }
74 } 93 }
75 } 94 }
76 } 95 }
77 96
78 private boolean evaluateCondition(VirtualFrame frame) { 97 private boolean evaluateCondition(VirtualFrame frame) {
79 try { 98 try {
80 /* 99 /*
81 * The condition must evaluate to a boolean value, so we call boolean-specialized 100 * The condition must evaluate to a boolean value, so we call the boolean-specialized
82 * method. 101 * execute method.
83 */ 102 */
84 return conditionNode.executeBoolean(frame); 103 return conditionNode.executeBoolean(frame);
85 } catch (UnexpectedResultException ex) { 104 } catch (UnexpectedResultException ex) {
86 /* 105 /*
87 * The condition evaluated to a non-boolean result. This is a type error in the SL 106 * The condition evaluated to a non-boolean result. This is a type error in the SL