Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Unified Diff: src/codegen-ia32.cc

Issue 40294: Work around issue 260 for now by disabling duplication of the loop... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-260.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/codegen-ia32.cc
===================================================================
--- src/codegen-ia32.cc (revision 1450)
+++ src/codegen-ia32.cc (working copy)
@@ -2174,15 +2174,16 @@
JumpTarget body(this, JumpTarget::BIDIRECTIONAL);
IncrementLoopNesting();
- // Label the top of the loop for the backward CFG edge. If the test
- // is always true we can use the continue target, and if the test is
- // always false there is no need.
+ // Label the top of the loop for the backward jump if necessary.
if (info == ALWAYS_TRUE) {
+ // Use the continue target.
node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL);
node->continue_target()->Bind();
} else if (info == ALWAYS_FALSE) {
+ // No need to label it.
node->continue_target()->Initialize(this);
} else {
+ // Continue is the test, so use the backward body target.
ASSERT(info == DONT_KNOW);
node->continue_target()->Initialize(this);
body.Bind();
@@ -2193,8 +2194,8 @@
// Compile the test.
if (info == ALWAYS_TRUE) {
- // If control flow can fall off the end of the body, jump back to
- // the top and bind the break target as the exit.
+ // If control flow can fall off the end of the body, jump back
+ // to the top and bind the break target at the exit.
if (has_valid_frame()) {
node->continue_target()->Jump();
}
@@ -2230,15 +2231,19 @@
}
case LoopStatement::WHILE_LOOP: {
- JumpTarget body(this, JumpTarget::BIDIRECTIONAL);
+ // 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;
+
+ JumpTarget body; // Uninitialized.
IncrementLoopNesting();
// If the condition is always false and has no side effects, we
// do not need to compile anything.
if (info == ALWAYS_FALSE) break;
- // Based on the condition analysis, compile the test if
- // necessary and label the body if necessary.
+ // 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
// the loop with the continue target.
@@ -2246,7 +2251,18 @@
node->continue_target()->Bind();
} else {
ASSERT(info == DONT_KNOW); // ALWAYS_FALSE cannot reach here.
- node->continue_target()->Initialize(this);
+ if (test_at_bottom) {
+ // 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.Initialize(this, JumpTarget::BIDIRECTIONAL);
+ } else {
+ // Label the test at the top as the continue target. The
+ // body is a forward-only target.
+ node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL);
+ node->continue_target()->Bind();
+ body.Initialize(this);
+ }
// Compile the test with the body as the true target and
// preferred fall-through and with the break target as the
// false target.
@@ -2254,9 +2270,9 @@
LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
if (dest.false_was_fall_through()) {
- // If we don't have dangling jumps to the body, the test is
- // unconditionally false and we do not need to compile the
- // body.
+ // If we got the break target as fall-through, the test may
+ // have been unconditionally false (if there are no jumps to
+ // the body).
if (!body.is_linked()) break;
// Otherwise, jump around the body on the fall through and
@@ -2267,31 +2283,37 @@
}
}
- // The (stack check at the start of the) body was labeled.
- // Compile it.
CheckStack(); // TODO(1222600): ignore if body contains calls.
Visit(node->body());
- // Compile the test if necessary and jump back.
+ // Based on the condition analysis, compile the backward jump as
+ // necessary.
if (info == ALWAYS_TRUE) {
- // The body has been labeled with the continue target.
+ // The loop body has been labeled with the continue target.
if (has_valid_frame()) {
node->continue_target()->Jump();
}
} else {
ASSERT(info == DONT_KNOW); // ALWAYS_FALSE cannot reach here.
- if (node->continue_target()->is_linked()) {
- node->continue_target()->Bind();
+ if (test_at_bottom) {
+ // If we have chosen to recompile the test at the bottom,
+ // then it is the continue target.
+ if (node->continue_target()->is_linked()) {
+ node->continue_target()->Bind();
+ }
+ if (has_valid_frame()) {
+ // The break target is the fall-through (body is a backward
+ // jump from here and thus an invalid fall-through).
+ ControlDestination dest(&body, node->break_target(), false);
+ LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
+ }
+ } else {
+ // If we have chosen not to recompile the test at the
+ // bottom, jump back to the one at the top.
+ if (has_valid_frame()) {
+ node->continue_target()->Jump();
+ }
}
-
- // If control can reach the bottom by falling off the body or
- // a continue in the body, (re)compile the test at the bottom.
- if (has_valid_frame()) {
- // The break target is the fall-through (body is a backward
- // jump from here).
- ControlDestination dest(&body, node->break_target(), false);
- LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
- }
}
// The break target may be already bound (by the condition), or
@@ -2303,8 +2325,14 @@
}
case LoopStatement::FOR_LOOP: {
- JumpTarget body(this, JumpTarget::BIDIRECTIONAL);
+ // 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;
+ JumpTarget loop(this, JumpTarget::BIDIRECTIONAL);
+ JumpTarget body(this);
+
// Compile the init expression if present.
if (node->init() != NULL) {
Visit(node->init());
@@ -2316,22 +2344,37 @@
// do not need to compile anything else.
if (info == ALWAYS_FALSE) break;
- // Based on the condition analysis, compile the test if
- // necessary and label the body if necessary.
+ // 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
- // the loop with the continue target if there is no update
- // expression, otherwise with the body target.
+ // the loop.
if (node->next() == NULL) {
+ // Use the continue target if there is no update expression.
node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL);
node->continue_target()->Bind();
} else {
+ // Otherwise use the backward loop target.
node->continue_target()->Initialize(this);
- body.Bind();
+ loop.Bind();
}
} else {
ASSERT(info == DONT_KNOW);
- node->continue_target()->Initialize(this);
+ if (test_at_bottom) {
+ // Continue is either the update expression or the test at
+ // the bottom, no need to label the test at the top.
+ node->continue_target()->Initialize(this);
+ } else if (node->next() == NULL) {
+ // We are not recompiling the test at the bottom and there
+ // is no update expression.
+ node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL);
+ node->continue_target()->Bind();
+ } else {
+ // We are not recompiling the test at the bottom and there
+ // is an update expression.
+ node->continue_target()->Initialize(this);
+ loop.Bind();
+ }
+
// Compile the test with the body as the true target and
// preferred fall-through and with the break target as the
// false target.
@@ -2339,9 +2382,9 @@
LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
if (dest.false_was_fall_through()) {
- // If we don't have dangling jumps to the body, the test is
- // unconditionally false and we do not need to compile the
- // body.
+ // If we got the break target as fall-through, the test may
+ // have been unconditionally false (if there are no jumps to
+ // the body).
if (!body.is_linked()) break;
// Otherwise, jump around the body on the fall through and
@@ -2352,20 +2395,17 @@
}
}
- // The (stack check at the start of the) body was labeled.
- // Compile it.
CheckStack(); // TODO(1222600): ignore if body contains calls.
Visit(node->body());
// If there is an update expression, compile it if necessary.
if (node->next() != NULL) {
- // We did not use the continue target for the body.
if (node->continue_target()->is_linked()) {
node->continue_target()->Bind();
}
// Control can reach the update by falling out of the body or
- // by a continue in the body.
+ // by a continue.
if (has_valid_frame()) {
// Record the source position of the statement as this code
// which is after the code for the body actually belongs to
@@ -2375,32 +2415,43 @@
}
}
- // Compile the test if necessary and jump back.
+ // Based on the condition analysis, compile the backward jump as
+ // necessary.
if (info == ALWAYS_TRUE) {
if (has_valid_frame()) {
if (node->next() == NULL) {
node->continue_target()->Jump();
} else {
- body.Jump();
+ loop.Jump();
}
}
} else {
ASSERT(info == DONT_KNOW); // ALWAYS_FALSE cannot reach here.
- if (node->continue_target()->is_linked()) {
- // We can have dangling jumps to the continue target if
- // there was no update expression.
- node->continue_target()->Bind();
+ if (test_at_bottom) {
+ if (node->continue_target()->is_linked()) {
+ // We can have dangling jumps to the continue target if
+ // there was no update expression.
+ node->continue_target()->Bind();
+ }
+ // Control can reach the test at the bottom by falling out
+ // of the body, by a continue in the body, or from the
+ // update expression.
+ if (has_valid_frame()) {
+ // The break target is the fall-through (body is a
+ // backward jump from here).
+ ControlDestination dest(&body, node->break_target(), false);
+ LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
+ }
+ } else {
+ // Otherwise, jump back to the test at the top.
+ if (has_valid_frame()) {
+ if (node->next() == NULL) {
+ node->continue_target()->Jump();
+ } else {
+ loop.Jump();
+ }
+ }
}
-
- // Control can reach the test at the bottom by falling out of
- // the body, by a continue in the body, or from the update
- // expression.
- if (has_valid_frame()) {
- // The break target is the fall-through (body is a backward
- // jump from here).
- ControlDestination dest(&body, node->break_target(), false);
- LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
- }
}
// The break target may be already bound (by the condition), or
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-260.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698