Mercurial > hg > graal-compiler
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 |