Index: src/codegen-ia32.cc |
=================================================================== |
--- src/codegen-ia32.cc (revision 1501) |
+++ src/codegen-ia32.cc (working copy) |
@@ -2228,18 +2228,24 @@ |
} |
case LoopStatement::WHILE_LOOP: { |
- // TODO(260): This flag controls whether to duplicate the test |
- // at the bottom of the loop. Replace it with a better |
- // indication of when it is safe to do so. |
- static const bool test_at_bottom = false; |
+ // Do not duplicate conditions with function literal |
+ // subexpressions. This can cause us to compile the function |
+ // literal twice. |
+ bool test_at_bottom = !node->has_function_literal(); |
- JumpTarget body(this); // Initialized as forward-only. |
IncrementLoopNesting(); |
// If the condition is always false and has no side effects, we |
// do not need to compile anything. |
if (info == ALWAYS_FALSE) break; |
+ JumpTarget body; |
+ if (test_at_bottom) { |
+ body.Initialize(this, JumpTarget::BIDIRECTIONAL); |
+ } else { |
+ body.Initialize(this); |
+ } |
+ |
// Based on the condition analysis, compile the test as necessary. |
if (info == ALWAYS_TRUE) { |
// We will not compile the test expression. Label the top of |
@@ -2252,7 +2258,6 @@ |
// Continue is the test at the bottom, no need to label the |
// test at the top. The body is a backward target. |
node->continue_target()->Initialize(this); |
- body.make_bidirectional(); |
} else { |
// Label the test at the top as the continue target. The |
// body is a forward-only target. |
@@ -2321,14 +2326,11 @@ |
} |
case LoopStatement::FOR_LOOP: { |
- // TODO(260): This flag controls whether to duplicate the test |
- // at the bottom of the loop. Replace it with a better |
- // indication of when it is safe to do so. |
- static const bool test_at_bottom = false; |
+ // Do not duplicate conditions with function literal |
+ // subexpressions. This can cause us to compile the function |
+ // literal twice. |
+ bool test_at_bottom = !node->has_function_literal(); |
- JumpTarget loop(this, JumpTarget::BIDIRECTIONAL); |
- JumpTarget body(this); |
- |
// Compile the init expression if present. |
if (node->init() != NULL) { |
Visit(node->init()); |
@@ -2340,6 +2342,19 @@ |
// do not need to compile anything else. |
if (info == ALWAYS_FALSE) break; |
+ // Target for backward edge if no test at the bottom, otherwise |
+ // unused. |
+ JumpTarget loop(this, JumpTarget::BIDIRECTIONAL); |
+ |
+ // Target for backward edge if there is a test at the bottom, |
+ // otherwise used as target for test at the top. |
+ JumpTarget body; |
+ if (test_at_bottom) { |
+ body.Initialize(this, JumpTarget::BIDIRECTIONAL); |
+ } else { |
+ body.Initialize(this); |
+ } |
+ |
// Based on the condition analysis, compile the test as necessary. |
if (info == ALWAYS_TRUE) { |
// We will not compile the test expression. Label the top of |