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

Side by Side Diff: src/full-codegen.cc

Issue 8386037: Remove the forward-bailout stack from the non-optimizing compiler. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/full-codegen.h ('k') | src/hydrogen.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 409
410 410
411 void FullCodeGenerator::StackValueContext::Plug(Register reg) const { 411 void FullCodeGenerator::StackValueContext::Plug(Register reg) const {
412 __ push(reg); 412 __ push(reg);
413 } 413 }
414 414
415 415
416 void FullCodeGenerator::TestContext::Plug(Register reg) const { 416 void FullCodeGenerator::TestContext::Plug(Register reg) const {
417 // For simplicity we always test the accumulator register. 417 // For simplicity we always test the accumulator register.
418 __ Move(result_register(), reg); 418 __ Move(result_register(), reg);
419 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 419 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
420 codegen()->DoTest(this); 420 codegen()->DoTest(this);
421 } 421 }
422 422
423 423
424 void FullCodeGenerator::EffectContext::PlugTOS() const { 424 void FullCodeGenerator::EffectContext::PlugTOS() const {
425 __ Drop(1); 425 __ Drop(1);
426 } 426 }
427 427
428 428
429 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const { 429 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const {
430 __ pop(result_register()); 430 __ pop(result_register());
431 } 431 }
432 432
433 433
434 void FullCodeGenerator::StackValueContext::PlugTOS() const { 434 void FullCodeGenerator::StackValueContext::PlugTOS() const {
435 } 435 }
436 436
437 437
438 void FullCodeGenerator::TestContext::PlugTOS() const { 438 void FullCodeGenerator::TestContext::PlugTOS() const {
439 // For simplicity we always test the accumulator register. 439 // For simplicity we always test the accumulator register.
440 __ pop(result_register()); 440 __ pop(result_register());
441 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 441 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
442 codegen()->DoTest(this); 442 codegen()->DoTest(this);
443 } 443 }
444 444
445 445
446 void FullCodeGenerator::EffectContext::PrepareTest( 446 void FullCodeGenerator::EffectContext::PrepareTest(
447 Label* materialize_true, 447 Label* materialize_true,
448 Label* materialize_false, 448 Label* materialize_false,
449 Label** if_true, 449 Label** if_true,
450 Label** if_false, 450 Label** if_false,
451 Label** fall_through) const { 451 Label** fall_through) const {
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 FullCodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) { 645 FullCodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) {
646 int lookup_index = 646 int lookup_index =
647 static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction); 647 static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction);
648 ASSERT(lookup_index >= 0); 648 ASSERT(lookup_index >= 0);
649 ASSERT(static_cast<size_t>(lookup_index) < 649 ASSERT(static_cast<size_t>(lookup_index) <
650 ARRAY_SIZE(kInlineFunctionGenerators)); 650 ARRAY_SIZE(kInlineFunctionGenerators));
651 return kInlineFunctionGenerators[lookup_index]; 651 return kInlineFunctionGenerators[lookup_index];
652 } 652 }
653 653
654 654
655 void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* node) { 655 void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) {
656 ZoneList<Expression*>* args = node->arguments(); 656 const Runtime::Function* function = expr->function();
657 const Runtime::Function* function = node->function();
658 ASSERT(function != NULL); 657 ASSERT(function != NULL);
659 ASSERT(function->intrinsic_type == Runtime::INLINE); 658 ASSERT(function->intrinsic_type == Runtime::INLINE);
660 InlineFunctionGenerator generator = 659 InlineFunctionGenerator generator =
661 FindInlineFunctionGenerator(function->function_id); 660 FindInlineFunctionGenerator(function->function_id);
662 ((*this).*(generator))(args); 661 ((*this).*(generator))(expr);
663 } 662 }
664 663
665 664
666 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 665 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
667 switch (expr->op()) { 666 switch (expr->op()) {
668 case Token::COMMA: 667 case Token::COMMA:
669 return VisitComma(expr); 668 return VisitComma(expr);
670 case Token::OR: 669 case Token::OR:
671 case Token::AND: 670 case Token::AND:
672 return VisitLogicalExpression(expr); 671 return VisitLogicalExpression(expr);
673 default: 672 default:
674 return VisitArithmeticExpression(expr); 673 return VisitArithmeticExpression(expr);
675 } 674 }
676 } 675 }
677 676
678 677
678 void FullCodeGenerator::VisitInDuplicateContext(Expression* expr) {
679 if (context()->IsEffect()) {
680 VisitForEffect(expr);
681 } else if (context()->IsAccumulatorValue()) {
682 VisitForAccumulatorValue(expr);
683 } else if (context()->IsStackValue()) {
684 VisitForStackValue(expr);
685 } else if (context()->IsTest()) {
686 const TestContext* test = TestContext::cast(context());
687 VisitForControl(expr, test->true_label(), test->false_label(),
688 test->fall_through());
689 }
690 }
691
692
679 void FullCodeGenerator::VisitComma(BinaryOperation* expr) { 693 void FullCodeGenerator::VisitComma(BinaryOperation* expr) {
680 Comment cmnt(masm_, "[ Comma"); 694 Comment cmnt(masm_, "[ Comma");
681 VisitForEffect(expr->left()); 695 VisitForEffect(expr->left());
682 if (context()->IsTest()) ForwardBailoutToChild(expr); 696 VisitInDuplicateContext(expr->right());
683 VisitInCurrentContext(expr->right());
684 } 697 }
685 698
686 699
687 void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) { 700 void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) {
688 bool is_logical_and = expr->op() == Token::AND; 701 bool is_logical_and = expr->op() == Token::AND;
689 Comment cmnt(masm_, is_logical_and ? "[ Logical AND" : "[ Logical OR"); 702 Comment cmnt(masm_, is_logical_and ? "[ Logical AND" : "[ Logical OR");
690 Expression* left = expr->left(); 703 Expression* left = expr->left();
691 Expression* right = expr->right(); 704 Expression* right = expr->right();
692 int right_id = expr->RightId(); 705 int right_id = expr->RightId();
693 Label done; 706 Label done;
694 707
695 if (context()->IsTest()) { 708 if (context()->IsTest()) {
696 Label eval_right; 709 Label eval_right;
697 const TestContext* test = TestContext::cast(context()); 710 const TestContext* test = TestContext::cast(context());
698 if (is_logical_and) { 711 if (is_logical_and) {
699 VisitForControl(left, &eval_right, test->false_label(), &eval_right); 712 VisitForControl(left, &eval_right, test->false_label(), &eval_right);
700 } else { 713 } else {
701 VisitForControl(left, test->true_label(), &eval_right, &eval_right); 714 VisitForControl(left, test->true_label(), &eval_right, &eval_right);
702 } 715 }
703 PrepareForBailoutForId(right_id, NO_REGISTERS); 716 PrepareForBailoutForId(right_id, NO_REGISTERS);
704 __ bind(&eval_right); 717 __ bind(&eval_right);
705 ForwardBailoutToChild(expr);
706 718
707 } else if (context()->IsAccumulatorValue()) { 719 } else if (context()->IsAccumulatorValue()) {
708 VisitForAccumulatorValue(left); 720 VisitForAccumulatorValue(left);
709 // We want the value in the accumulator for the test, and on the stack in 721 // We want the value in the accumulator for the test, and on the stack in
710 // case we need it. 722 // case we need it.
711 __ push(result_register()); 723 __ push(result_register());
712 Label discard, restore; 724 Label discard, restore;
713 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
714 if (is_logical_and) { 725 if (is_logical_and) {
715 DoTest(left, &discard, &restore, &restore); 726 DoTest(left, &discard, &restore, &restore);
716 } else { 727 } else {
717 DoTest(left, &restore, &discard, &restore); 728 DoTest(left, &restore, &discard, &restore);
718 } 729 }
719 __ bind(&restore); 730 __ bind(&restore);
720 __ pop(result_register()); 731 __ pop(result_register());
721 __ jmp(&done); 732 __ jmp(&done);
722 __ bind(&discard); 733 __ bind(&discard);
723 __ Drop(1); 734 __ Drop(1);
724 PrepareForBailoutForId(right_id, NO_REGISTERS); 735 PrepareForBailoutForId(right_id, NO_REGISTERS);
725 736
726 } else if (context()->IsStackValue()) { 737 } else if (context()->IsStackValue()) {
727 VisitForAccumulatorValue(left); 738 VisitForAccumulatorValue(left);
728 // We want the value in the accumulator for the test, and on the stack in 739 // We want the value in the accumulator for the test, and on the stack in
729 // case we need it. 740 // case we need it.
730 __ push(result_register()); 741 __ push(result_register());
731 Label discard; 742 Label discard;
732 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
733 if (is_logical_and) { 743 if (is_logical_and) {
734 DoTest(left, &discard, &done, &discard); 744 DoTest(left, &discard, &done, &discard);
735 } else { 745 } else {
736 DoTest(left, &done, &discard, &discard); 746 DoTest(left, &done, &discard, &discard);
737 } 747 }
738 __ bind(&discard); 748 __ bind(&discard);
739 __ Drop(1); 749 __ Drop(1);
740 PrepareForBailoutForId(right_id, NO_REGISTERS); 750 PrepareForBailoutForId(right_id, NO_REGISTERS);
741 751
742 } else { 752 } else {
743 ASSERT(context()->IsEffect()); 753 ASSERT(context()->IsEffect());
744 Label eval_right; 754 Label eval_right;
745 if (is_logical_and) { 755 if (is_logical_and) {
746 VisitForControl(left, &eval_right, &done, &eval_right); 756 VisitForControl(left, &eval_right, &done, &eval_right);
747 } else { 757 } else {
748 VisitForControl(left, &done, &eval_right, &eval_right); 758 VisitForControl(left, &done, &eval_right, &eval_right);
749 } 759 }
750 PrepareForBailoutForId(right_id, NO_REGISTERS); 760 PrepareForBailoutForId(right_id, NO_REGISTERS);
751 __ bind(&eval_right); 761 __ bind(&eval_right);
752 } 762 }
753 763
754 VisitInCurrentContext(right); 764 VisitInDuplicateContext(right);
755 __ bind(&done); 765 __ bind(&done);
756 } 766 }
757 767
758 768
759 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { 769 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
760 Token::Value op = expr->op(); 770 Token::Value op = expr->op();
761 Comment cmnt(masm_, "[ ArithmeticExpression"); 771 Comment cmnt(masm_, "[ ArithmeticExpression");
762 Expression* left = expr->left(); 772 Expression* left = expr->left();
763 Expression* right = expr->right(); 773 Expression* right = expr->right();
764 OverwriteMode mode = 774 OverwriteMode mode =
765 left->ResultOverwriteAllowed() 775 left->ResultOverwriteAllowed()
766 ? OVERWRITE_LEFT 776 ? OVERWRITE_LEFT
767 : (right->ResultOverwriteAllowed() ? OVERWRITE_RIGHT : NO_OVERWRITE); 777 : (right->ResultOverwriteAllowed() ? OVERWRITE_RIGHT : NO_OVERWRITE);
768 778
769 VisitForStackValue(left); 779 VisitForStackValue(left);
770 VisitForAccumulatorValue(right); 780 VisitForAccumulatorValue(right);
771 781
772 SetSourcePosition(expr->position()); 782 SetSourcePosition(expr->position());
773 if (ShouldInlineSmiCase(op)) { 783 if (ShouldInlineSmiCase(op)) {
774 EmitInlineSmiBinaryOp(expr, op, mode, left, right); 784 EmitInlineSmiBinaryOp(expr, op, mode, left, right);
775 } else { 785 } else {
776 EmitBinaryOp(expr, op, mode); 786 EmitBinaryOp(expr, op, mode);
777 } 787 }
778 } 788 }
779 789
780 790
781 void FullCodeGenerator::ForwardBailoutToChild(Expression* expr) {
782 if (!info_->HasDeoptimizationSupport()) return;
783 ASSERT(context()->IsTest());
784 ASSERT(expr == forward_bailout_stack_->expr());
785 forward_bailout_pending_ = forward_bailout_stack_;
786 }
787
788
789 void FullCodeGenerator::VisitInCurrentContext(Expression* expr) {
790 if (context()->IsTest()) {
791 ForwardBailoutStack stack(expr, forward_bailout_pending_);
792 ForwardBailoutStack* saved = forward_bailout_stack_;
793 forward_bailout_pending_ = NULL;
794 forward_bailout_stack_ = &stack;
795 Visit(expr);
796 forward_bailout_stack_ = saved;
797 } else {
798 ASSERT(forward_bailout_pending_ == NULL);
799 Visit(expr);
800 State state = context()->IsAccumulatorValue() ? TOS_REG : NO_REGISTERS;
801 PrepareForBailout(expr, state);
802 // Forwarding bailouts to children is a one shot operation. It should have
803 // been processed at this point.
804 ASSERT(forward_bailout_pending_ == NULL);
805 }
806 }
807
808
809 void FullCodeGenerator::VisitBlock(Block* stmt) { 791 void FullCodeGenerator::VisitBlock(Block* stmt) {
810 Comment cmnt(masm_, "[ Block"); 792 Comment cmnt(masm_, "[ Block");
811 NestedBlock nested_block(this, stmt); 793 NestedBlock nested_block(this, stmt);
812 SetStatementPosition(stmt); 794 SetStatementPosition(stmt);
813 795
814 Scope* saved_scope = scope(); 796 Scope* saved_scope = scope();
815 // Push a block context when entering a block with block scoped variables. 797 // Push a block context when entering a block with block scoped variables.
816 if (stmt->block_scope() != NULL) { 798 if (stmt->block_scope() != NULL) {
817 { Comment cmnt(masm_, "[ Extend block context"); 799 { Comment cmnt(masm_, "[ Extend block context");
818 scope_ = stmt->block_scope(); 800 scope_ = stmt->block_scope();
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
1240 __ bind(&true_case); 1222 __ bind(&true_case);
1241 SetExpressionPosition(expr->then_expression(), 1223 SetExpressionPosition(expr->then_expression(),
1242 expr->then_expression_position()); 1224 expr->then_expression_position());
1243 if (context()->IsTest()) { 1225 if (context()->IsTest()) {
1244 const TestContext* for_test = TestContext::cast(context()); 1226 const TestContext* for_test = TestContext::cast(context());
1245 VisitForControl(expr->then_expression(), 1227 VisitForControl(expr->then_expression(),
1246 for_test->true_label(), 1228 for_test->true_label(),
1247 for_test->false_label(), 1229 for_test->false_label(),
1248 NULL); 1230 NULL);
1249 } else { 1231 } else {
1250 VisitInCurrentContext(expr->then_expression()); 1232 VisitInDuplicateContext(expr->then_expression());
1251 __ jmp(&done); 1233 __ jmp(&done);
1252 } 1234 }
1253 1235
1254 PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS); 1236 PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS);
1255 __ bind(&false_case); 1237 __ bind(&false_case);
1256 if (context()->IsTest()) ForwardBailoutToChild(expr);
1257 SetExpressionPosition(expr->else_expression(), 1238 SetExpressionPosition(expr->else_expression(),
1258 expr->else_expression_position()); 1239 expr->else_expression_position());
1259 VisitInCurrentContext(expr->else_expression()); 1240 VisitInDuplicateContext(expr->else_expression());
1260 // If control flow falls through Visit, merge it with true case here. 1241 // If control flow falls through Visit, merge it with true case here.
1261 if (!context()->IsTest()) { 1242 if (!context()->IsTest()) {
1262 __ bind(&done); 1243 __ bind(&done);
1263 } 1244 }
1264 } 1245 }
1265 1246
1266 1247
1267 void FullCodeGenerator::VisitLiteral(Literal* expr) { 1248 void FullCodeGenerator::VisitLiteral(Literal* expr) {
1268 Comment cmnt(masm_, "[ Literal"); 1249 Comment cmnt(masm_, "[ Literal");
1269 context()->Plug(expr->handle()); 1250 context()->Plug(expr->handle());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 __ PopTryHandler(); 1288 __ PopTryHandler();
1308 *stack_depth = 0; 1289 *stack_depth = 0;
1309 return previous_; 1290 return previous_;
1310 } 1291 }
1311 1292
1312 1293
1313 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) { 1294 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) {
1314 Expression *sub_expr; 1295 Expression *sub_expr;
1315 Handle<String> check; 1296 Handle<String> check;
1316 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { 1297 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
1317 EmitLiteralCompareTypeof(sub_expr, check); 1298 EmitLiteralCompareTypeof(expr, sub_expr, check);
1318 return true; 1299 return true;
1319 } 1300 }
1320 1301
1321 if (expr->IsLiteralCompareUndefined(&sub_expr)) { 1302 if (expr->IsLiteralCompareUndefined(&sub_expr)) {
1322 EmitLiteralCompareNil(expr, sub_expr, kUndefinedValue); 1303 EmitLiteralCompareNil(expr, sub_expr, kUndefinedValue);
1323 return true; 1304 return true;
1324 } 1305 }
1325 1306
1326 if (expr->IsLiteralCompareNull(&sub_expr)) { 1307 if (expr->IsLiteralCompareNull(&sub_expr)) {
1327 EmitLiteralCompareNil(expr, sub_expr, kNullValue); 1308 EmitLiteralCompareNil(expr, sub_expr, kNullValue);
1328 return true; 1309 return true;
1329 } 1310 }
1330 1311
1331 return false; 1312 return false;
1332 } 1313 }
1333 1314
1334 1315
1335 #undef __ 1316 #undef __
1336 1317
1337 1318
1338 } } // namespace v8::internal 1319 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698