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

Unified Diff: src/full-codegen.cc

Issue 6976028: Reduced the code ping-pong between the full code generator and contexts a bit. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 7 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
Index: src/full-codegen.cc
===================================================================
--- src/full-codegen.cc (revision 8079)
+++ src/full-codegen.cc (working copy)
@@ -702,143 +702,110 @@
void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
Comment cmnt(masm_, "[ BinaryOperation");
Kevin Millikin (Chromium) 2011/05/31 11:46:28 By moving this comment into VisitComma, VisitLogic
Sven Panne 2011/05/31 14:30:33 Done.
+ switch (expr->op()) {
+ case Token::COMMA: return VisitComma(expr);
+ case Token::OR: return VisitAndOr(expr, false);
Kevin Millikin (Chromium) 2011/05/31 11:46:28 Let's not pass the flag here, since we can just us
Sven Panne 2011/05/31 14:30:33 Done, same for HGraphBuilder.
+ case Token::AND: return VisitAndOr(expr, true);
+ default: return VisitCommon(expr);
+ }
+}
+
+
+void FullCodeGenerator::VisitCommon(BinaryOperation* expr) {
Token::Value op = expr->op();
Expression* left = expr->left();
Expression* right = expr->right();
+ OverwriteMode mode =
+ left->ResultOverwriteAllowed()
+ ? OVERWRITE_LEFT
+ : (right->ResultOverwriteAllowed() ? OVERWRITE_RIGHT : NO_OVERWRITE);
- OverwriteMode mode = NO_OVERWRITE;
- if (left->ResultOverwriteAllowed()) {
- mode = OVERWRITE_LEFT;
- } else if (right->ResultOverwriteAllowed()) {
- mode = OVERWRITE_RIGHT;
- }
+ VisitForStackValue(left);
+ VisitForAccumulatorValue(right);
- switch (op) {
- case Token::COMMA:
- VisitForEffect(left);
- if (context()->IsTest()) ForwardBailoutToChild(expr);
- context()->HandleExpression(right);
- break;
-
- case Token::OR:
- case Token::AND:
- EmitLogicalOperation(expr);
- break;
-
- case Token::ADD:
- case Token::SUB:
- case Token::DIV:
- case Token::MOD:
- case Token::MUL:
- case Token::BIT_OR:
- case Token::BIT_AND:
- case Token::BIT_XOR:
- case Token::SHL:
- case Token::SHR:
- case Token::SAR: {
- // Load both operands.
- VisitForStackValue(left);
- VisitForAccumulatorValue(right);
-
- SetSourcePosition(expr->position());
- if (ShouldInlineSmiCase(op)) {
- EmitInlineSmiBinaryOp(expr, op, mode, left, right);
- } else {
- EmitBinaryOp(expr, op, mode);
- }
- break;
- }
-
- default:
- UNREACHABLE();
+ SetSourcePosition(expr->position());
+ if (ShouldInlineSmiCase(op)) {
+ EmitInlineSmiBinaryOp(expr, op, mode, left, right);
+ } else {
+ EmitBinaryOp(expr, op, mode);
}
}
-void FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
- Label eval_right, done;
-
- context()->EmitLogicalLeft(expr, &eval_right, &done);
-
- PrepareForBailoutForId(expr->RightId(), NO_REGISTERS);
- __ bind(&eval_right);
+void FullCodeGenerator::VisitComma(BinaryOperation* expr) {
+ VisitForEffect(expr->left());
if (context()->IsTest()) ForwardBailoutToChild(expr);
- context()->HandleExpression(expr->right());
-
- __ bind(&done);
+ VisitInSameContext(expr->right());
}
-void FullCodeGenerator::EffectContext::EmitLogicalLeft(BinaryOperation* expr,
- Label* eval_right,
- Label* done) const {
- if (expr->op() == Token::OR) {
- codegen()->VisitForControl(expr->left(), done, eval_right, eval_right);
- } else {
- ASSERT(expr->op() == Token::AND);
- codegen()->VisitForControl(expr->left(), eval_right, done, eval_right);
- }
-}
+void FullCodeGenerator::VisitAndOr(BinaryOperation* expr, bool is_logical_and) {
+ Expression* left = expr->left();
+ Expression* right = expr->right();
+ int rightId = expr->RightId();
Kevin Millikin (Chromium) 2011/05/31 11:46:28 right_id
Sven Panne 2011/05/31 14:30:33 Done.
+ Label done;
+ if (context()->IsTest()) {
Kevin Millikin (Chromium) 2011/05/31 11:46:28 I did like having this code as virtual functions o
Sven Panne 2011/05/31 14:30:33 In principle I agree that the explicit IfFooContex
+ Label eval_right;
+ const TestContext* test = TestContext::cast(context());
+ if (is_logical_and) {
+ VisitForControl(left, &eval_right, test->false_label(), &eval_right);
+ } else {
+ VisitForControl(left, test->true_label(), &eval_right, &eval_right);
+ }
+ PrepareForBailoutForId(rightId, NO_REGISTERS);
+ __ bind(&eval_right);
+ ForwardBailoutToChild(expr);
-void FullCodeGenerator::AccumulatorValueContext::EmitLogicalLeft(
- BinaryOperation* expr,
- Label* eval_right,
- Label* done) const {
- HandleExpression(expr->left());
- // We want the value in the accumulator for the test, and on the stack in case
- // we need it.
- __ push(result_register());
- Label discard, restore;
- if (expr->op() == Token::OR) {
- codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
- codegen()->DoTest(&restore, &discard, &restore);
- } else {
- ASSERT(expr->op() == Token::AND);
- codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
- codegen()->DoTest(&discard, &restore, &restore);
- }
- __ bind(&restore);
- __ pop(result_register());
- __ jmp(done);
- __ bind(&discard);
- __ Drop(1);
-}
+ } else if (context()->IsAccumulatorValue()) {
+ VisitForAccumulatorValue(left);
+ // We want the value in the accumulator for the test, and on the stack in
+ // case we need it.
+ __ push(result_register());
+ Label discard, restore;
+ PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
+ if (is_logical_and) {
+ DoTest(&discard, &restore, &restore);
+ } else {
+ DoTest(&restore, &discard, &restore);
+ }
+ __ bind(&restore);
+ __ pop(result_register());
+ __ jmp(&done);
+ __ bind(&discard);
+ __ Drop(1);
+ PrepareForBailoutForId(rightId, NO_REGISTERS);
+ } else if (context()->IsStackValue()) {
+ VisitForAccumulatorValue(left);
+ // We want the value in the accumulator for the test, and on the stack in
+ // case we need it.
+ __ push(result_register());
+ Label discard;
+ PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
+ if (is_logical_and) {
+ DoTest(&discard, &done, &discard);
+ } else {
+ DoTest(&done, &discard, &discard);
+ }
+ __ bind(&discard);
+ __ Drop(1);
+ PrepareForBailoutForId(rightId, NO_REGISTERS);
-void FullCodeGenerator::StackValueContext::EmitLogicalLeft(
- BinaryOperation* expr,
- Label* eval_right,
- Label* done) const {
- codegen()->VisitForAccumulatorValue(expr->left());
- // We want the value in the accumulator for the test, and on the stack in case
- // we need it.
- __ push(result_register());
- Label discard;
- if (expr->op() == Token::OR) {
- codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
- codegen()->DoTest(done, &discard, &discard);
} else {
- ASSERT(expr->op() == Token::AND);
- codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
- codegen()->DoTest(&discard, done, &discard);
+ ASSERT(context()->IsEffect());
+ Label eval_right;
+ if (is_logical_and) {
+ VisitForControl(left, &eval_right, &done, &eval_right);
+ } else {
+ VisitForControl(left, &done, &eval_right, &eval_right);
+ }
+ PrepareForBailoutForId(rightId, NO_REGISTERS);
+ __ bind(&eval_right);
}
- __ bind(&discard);
- __ Drop(1);
-}
-
-void FullCodeGenerator::TestContext::EmitLogicalLeft(BinaryOperation* expr,
- Label* eval_right,
- Label* done) const {
- if (expr->op() == Token::OR) {
- codegen()->VisitForControl(expr->left(),
- true_label_, eval_right, eval_right);
- } else {
- ASSERT(expr->op() == Token::AND);
- codegen()->VisitForControl(expr->left(),
- eval_right, false_label_, eval_right);
- }
+ VisitInSameContext(right);
+ __ bind(&done);
}
@@ -850,49 +817,26 @@
}
-void FullCodeGenerator::EffectContext::HandleExpression(
- Expression* expr) const {
- codegen()->HandleInNonTestContext(expr, NO_REGISTERS);
+void FullCodeGenerator::VisitInSameContext(Expression* expr) {
+ if (context()->IsTest()) {
+ ForwardBailoutStack stack(expr, forward_bailout_pending_);
+ ForwardBailoutStack* saved = forward_bailout_stack_;
+ forward_bailout_pending_ = NULL;
+ forward_bailout_stack_ = &stack;
+ AstVisitor::Visit(expr);
Kevin Millikin (Chromium) 2011/05/31 11:46:28 This can just be Visit(expr), can't it?
Sven Panne 2011/05/31 14:30:33 Done.
+ forward_bailout_stack_ = saved;
+ } else {
+ ASSERT(forward_bailout_pending_ == NULL);
+ Visit(expr);
+ State state = context()->IsAccumulatorValue() ? TOS_REG : NO_REGISTERS;
+ PrepareForBailout(expr, state);
+ // Forwarding bailouts to children is a one shot operation. It should have
+ // been processed at this point.
+ ASSERT(forward_bailout_pending_ == NULL);
+ }
}
-void FullCodeGenerator::AccumulatorValueContext::HandleExpression(
- Expression* expr) const {
- codegen()->HandleInNonTestContext(expr, TOS_REG);
-}
-
-
-void FullCodeGenerator::StackValueContext::HandleExpression(
- Expression* expr) const {
- codegen()->HandleInNonTestContext(expr, NO_REGISTERS);
-}
-
-
-void FullCodeGenerator::TestContext::HandleExpression(Expression* expr) const {
- codegen()->VisitInTestContext(expr);
-}
-
-
-void FullCodeGenerator::HandleInNonTestContext(Expression* expr, State state) {
- ASSERT(forward_bailout_pending_ == NULL);
- AstVisitor::Visit(expr);
- PrepareForBailout(expr, state);
- // Forwarding bailouts to children is a one shot operation. It
- // should have been processed at this point.
- ASSERT(forward_bailout_pending_ == NULL);
-}
-
-
-void FullCodeGenerator::VisitInTestContext(Expression* expr) {
- ForwardBailoutStack stack(expr, forward_bailout_pending_);
- ForwardBailoutStack* saved = forward_bailout_stack_;
- forward_bailout_pending_ = NULL;
- forward_bailout_stack_ = &stack;
- AstVisitor::Visit(expr);
- forward_bailout_stack_ = saved;
-}
-
-
void FullCodeGenerator::VisitBlock(Block* stmt) {
Comment cmnt(masm_, "[ Block");
Breakable nested_statement(this, stmt);
@@ -1287,7 +1231,7 @@
for_test->false_label(),
NULL);
} else {
- context()->HandleExpression(expr->then_expression());
+ VisitInSameContext(expr->then_expression());
__ jmp(&done);
}
@@ -1296,7 +1240,7 @@
if (context()->IsTest()) ForwardBailoutToChild(expr);
SetExpressionPosition(expr->else_expression(),
expr->else_expression_position());
- context()->HandleExpression(expr->else_expression());
+ VisitInSameContext(expr->else_expression());
// If control flow falls through Visit, merge it with true case here.
if (!context()->IsTest()) {
__ bind(&done);
« src/full-codegen.h ('K') | « src/full-codegen.h ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698