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

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 1502243002: [Interpreter] Local flow control in the bytecode graph builder. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Incorporate comments by mstarzinger on patchet 10. Created 5 years 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
« no previous file with comments | « src/interpreter/bytecode-array-iterator.cc ('k') | src/interpreter/bytecodes.h » ('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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/interpreter/bytecode-generator.h" 5 #include "src/interpreter/bytecode-generator.h"
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/compiler.h" 8 #include "src/compiler.h"
9 #include "src/interpreter/control-flow-builders.h" 9 #include "src/interpreter/control-flow-builders.h"
10 #include "src/objects.h" 10 #include "src/objects.h"
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 } 621 }
622 622
623 623
624 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 624 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
625 } 625 }
626 626
627 627
628 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) { 628 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
629 BytecodeLabel else_label, end_label; 629 BytecodeLabel else_label, end_label;
630 if (stmt->condition()->ToBooleanIsTrue()) { 630 if (stmt->condition()->ToBooleanIsTrue()) {
631 // Generate only then block. 631 // Generate then block unconditionally as always true.
632 Visit(stmt->then_statement()); 632 Visit(stmt->then_statement());
633 } else if (stmt->condition()->ToBooleanIsFalse()) { 633 } else if (stmt->condition()->ToBooleanIsFalse()) {
634 // Generate only else block if it exists. 634 // Generate else block unconditionally if it exists.
635 if (stmt->HasElseStatement()) { 635 if (stmt->HasElseStatement()) {
636 Visit(stmt->else_statement()); 636 Visit(stmt->else_statement());
637 } 637 }
638 } else { 638 } else {
639 // TODO(oth): If then statement is BreakStatement or
640 // ContinueStatement we can reduce number of generated
641 // jump/jump_ifs here. See BasicLoops test.
639 VisitForAccumulatorValue(stmt->condition()); 642 VisitForAccumulatorValue(stmt->condition());
640 builder()->JumpIfFalse(&else_label); 643 builder()->JumpIfFalse(&else_label);
641 Visit(stmt->then_statement()); 644 Visit(stmt->then_statement());
642 if (stmt->HasElseStatement()) { 645 if (stmt->HasElseStatement()) {
643 builder()->Jump(&end_label); 646 builder()->Jump(&end_label);
644 builder()->Bind(&else_label); 647 builder()->Bind(&else_label);
645 Visit(stmt->else_statement()); 648 Visit(stmt->else_statement());
646 } else { 649 } else {
647 builder()->Bind(&else_label); 650 builder()->Bind(&else_label);
648 } 651 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 732
730 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { 733 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) {
731 // Handled entirely in VisitSwitchStatement. 734 // Handled entirely in VisitSwitchStatement.
732 UNREACHABLE(); 735 UNREACHABLE();
733 } 736 }
734 737
735 738
736 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 739 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
737 LoopBuilder loop_builder(builder()); 740 LoopBuilder loop_builder(builder());
738 ControlScopeForIteration execution_control(this, stmt, &loop_builder); 741 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
739 BytecodeLabel body_label, condition_label, done_label; 742 loop_builder.LoopHeader();
740 if (stmt->cond()->ToBooleanIsFalse()) { 743 if (stmt->cond()->ToBooleanIsFalse()) {
741 Visit(stmt->body()); 744 Visit(stmt->body());
742 // Bind condition_label and done_label for processing continue and break. 745 loop_builder.Condition();
743 builder()->Bind(&condition_label); 746 } else if (stmt->cond()->ToBooleanIsTrue()) {
744 builder()->Bind(&done_label); 747 loop_builder.Condition();
748 Visit(stmt->body());
749 loop_builder.JumpToHeader();
745 } else { 750 } else {
746 builder()->Bind(&body_label);
747 Visit(stmt->body()); 751 Visit(stmt->body());
748 752 loop_builder.Condition();
749 builder()->Bind(&condition_label); 753 VisitForAccumulatorValue(stmt->cond());
750 if (stmt->cond()->ToBooleanIsTrue()) { 754 loop_builder.JumpToHeaderIfTrue();
751 builder()->Jump(&body_label);
752 } else {
753 VisitForAccumulatorValue(stmt->cond());
754 builder()->JumpIfTrue(&body_label);
755 }
756 builder()->Bind(&done_label);
757 } 755 }
758 loop_builder.SetBreakTarget(done_label); 756 loop_builder.LoopEnd();
759 loop_builder.SetContinueTarget(condition_label);
760 } 757 }
761 758
762 759
763 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 760 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
764 LoopBuilder loop_builder(builder());
765 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
766
767 BytecodeLabel body_label, condition_label, done_label;
768 if (stmt->cond()->ToBooleanIsFalse()) { 761 if (stmt->cond()->ToBooleanIsFalse()) {
769 // If the condition is false there is no need to generate the loop. 762 // If the condition is false there is no need to generate the loop.
770 return; 763 return;
771 } 764 }
772 765
766 LoopBuilder loop_builder(builder());
767 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
768 loop_builder.LoopHeader();
769 loop_builder.Condition();
773 if (!stmt->cond()->ToBooleanIsTrue()) { 770 if (!stmt->cond()->ToBooleanIsTrue()) {
774 builder()->Jump(&condition_label); 771 VisitForAccumulatorValue(stmt->cond());
772 loop_builder.BreakIfFalse();
775 } 773 }
776 builder()->Bind(&body_label);
777 Visit(stmt->body()); 774 Visit(stmt->body());
778 775 loop_builder.JumpToHeader();
779 builder()->Bind(&condition_label); 776 loop_builder.LoopEnd();
780 if (stmt->cond()->ToBooleanIsTrue()) {
781 builder()->Jump(&body_label);
782 } else {
783 VisitForAccumulatorValue(stmt->cond());
784 builder()->JumpIfTrue(&body_label);
785 }
786 builder()->Bind(&done_label);
787
788 loop_builder.SetBreakTarget(done_label);
789 loop_builder.SetContinueTarget(condition_label);
790 } 777 }
791 778
792 779
793 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { 780 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
794 LoopBuilder loop_builder(builder());
795 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
796
797 if (stmt->init() != nullptr) { 781 if (stmt->init() != nullptr) {
798 Visit(stmt->init()); 782 Visit(stmt->init());
799 } 783 }
800
801 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) { 784 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
802 // If the condition is known to be false there is no need to generate 785 // If the condition is known to be false there is no need to generate
803 // body, next or condition blocks. Init block should be generated. 786 // body, next or condition blocks. Init block should be generated.
804 return; 787 return;
805 } 788 }
806 789
807 BytecodeLabel body_label, condition_label, next_label, done_label; 790 LoopBuilder loop_builder(builder());
791 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
792
793 loop_builder.LoopHeader();
794 loop_builder.Condition();
808 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) { 795 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
809 builder()->Jump(&condition_label); 796 VisitForAccumulatorValue(stmt->cond());
797 loop_builder.BreakIfFalse();
810 } 798 }
811 builder()->Bind(&body_label);
812 Visit(stmt->body()); 799 Visit(stmt->body());
813 builder()->Bind(&next_label);
814 if (stmt->next() != nullptr) { 800 if (stmt->next() != nullptr) {
801 loop_builder.Next();
815 Visit(stmt->next()); 802 Visit(stmt->next());
816 } 803 }
817 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) { 804 loop_builder.JumpToHeader();
818 builder()->Bind(&condition_label); 805 loop_builder.LoopEnd();
819 VisitForAccumulatorValue(stmt->cond());
820 builder()->JumpIfTrue(&body_label);
821 } else {
822 builder()->Jump(&body_label);
823 }
824 builder()->Bind(&done_label);
825
826 loop_builder.SetBreakTarget(done_label);
827 loop_builder.SetContinueTarget(next_label);
828 } 806 }
829 807
830 808
831 void BytecodeGenerator::VisitForInAssignment(Expression* expr, 809 void BytecodeGenerator::VisitForInAssignment(Expression* expr,
832 FeedbackVectorSlot slot) { 810 FeedbackVectorSlot slot) {
833 DCHECK(expr->IsValidReferenceExpression()); 811 DCHECK(expr->IsValidReferenceExpression());
834 812
835 // Evaluate assignment starting with the value to be stored in the 813 // Evaluate assignment starting with the value to be stored in the
836 // accumulator. 814 // accumulator.
837 Property* property = expr->AsProperty(); 815 Property* property = expr->AsProperty();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 Register receiver = execution_result()->NewRegister(); 869 Register receiver = execution_result()->NewRegister();
892 builder()->CastAccumulatorToJSObject(); 870 builder()->CastAccumulatorToJSObject();
893 builder()->StoreAccumulatorInRegister(receiver); 871 builder()->StoreAccumulatorInRegister(receiver);
894 builder()->CallRuntime(Runtime::kGetPropertyNamesFast, receiver, 1); 872 builder()->CallRuntime(Runtime::kGetPropertyNamesFast, receiver, 1);
895 builder()->ForInPrepare(receiver); 873 builder()->ForInPrepare(receiver);
896 loop_builder.BreakIfUndefined(); 874 loop_builder.BreakIfUndefined();
897 875
898 Register for_in_state = execution_result()->NewRegister(); 876 Register for_in_state = execution_result()->NewRegister();
899 builder()->StoreAccumulatorInRegister(for_in_state); 877 builder()->StoreAccumulatorInRegister(for_in_state);
900 878
901 // The loop. 879 // Check loop termination (accumulator holds index).
902 BytecodeLabel condition_label, break_label, continue_label;
903 Register index = receiver; // Re-using register as receiver no longer used. 880 Register index = receiver; // Re-using register as receiver no longer used.
904 builder()->LoadLiteral(Smi::FromInt(0)); 881 builder()->LoadLiteral(Smi::FromInt(0));
905 882 loop_builder.LoopHeader();
906 // Check loop termination (accumulator holds index). 883 loop_builder.Condition();
907 builder() 884 builder()->StoreAccumulatorInRegister(index).ForInDone(for_in_state);
908 ->Bind(&condition_label)
909 .StoreAccumulatorInRegister(index)
910 .ForInDone(for_in_state);
911 loop_builder.BreakIfTrue(); 885 loop_builder.BreakIfTrue();
912
913 // Get the next item.
914 builder()->ForInNext(for_in_state, index); 886 builder()->ForInNext(for_in_state, index);
915
916 // Start again if the item, currently in the accumulator, is undefined.
917 loop_builder.ContinueIfUndefined(); 887 loop_builder.ContinueIfUndefined();
918 888
919 // Store the value in the each variable.
920 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); 889 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
921 // NB the user's loop variable will be assigned the value of each so
922 // even an empty body will have this assignment.
923 Visit(stmt->body()); 890 Visit(stmt->body());
924 891
925 // Increment the index and start loop again. 892 // TODO(oth): replace CountOperation here with ForInStep.
926 builder() 893 loop_builder.Next();
927 ->Bind(&continue_label) 894 builder()->LoadAccumulatorWithRegister(index).CountOperation(
928 .LoadAccumulatorWithRegister(index) 895 Token::Value::ADD, language_mode_strength());
929 .CountOperation(Token::Value::ADD, language_mode_strength()) 896 loop_builder.JumpToHeader();
930 .Jump(&condition_label); 897 loop_builder.LoopEnd();
931
932 // End of the loop.
933 builder()->Bind(&break_label);
934
935 loop_builder.SetBreakTarget(break_label);
936 loop_builder.SetContinueTarget(continue_label);
937 } 898 }
938 899
939 900
940 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { 901 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
941 UNIMPLEMENTED(); 902 UNIMPLEMENTED();
942 } 903 }
943 904
944 905
945 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 906 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
946 if (FLAG_ignition_fake_try_catch) { 907 if (FLAG_ignition_fake_try_catch) {
(...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after
2237 } 2198 }
2238 2199
2239 2200
2240 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 2201 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
2241 return info()->feedback_vector()->GetIndex(slot); 2202 return info()->feedback_vector()->GetIndex(slot);
2242 } 2203 }
2243 2204
2244 } // namespace interpreter 2205 } // namespace interpreter
2245 } // namespace internal 2206 } // namespace internal
2246 } // namespace v8 2207 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-array-iterator.cc ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698