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

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

Issue 1665853002: [Interpreter] Add explicit StackCheck bytecodes on function entry and back branches. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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 unified diff | Download patch
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/bytecode-register-allocator.h" 9 #include "src/interpreter/bytecode-register-allocator.h"
10 #include "src/interpreter/control-flow-builders.h" 10 #include "src/interpreter/control-flow-builders.h"
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 603
604 // Visit illegal re-declaration and bail out if it exists. 604 // Visit illegal re-declaration and bail out if it exists.
605 if (scope()->HasIllegalRedeclaration()) { 605 if (scope()->HasIllegalRedeclaration()) {
606 VisitForEffect(scope()->GetIllegalRedeclaration()); 606 VisitForEffect(scope()->GetIllegalRedeclaration());
607 return; 607 return;
608 } 608 }
609 609
610 // Visit declarations within the function scope. 610 // Visit declarations within the function scope.
611 VisitDeclarations(scope()->declarations()); 611 VisitDeclarations(scope()->declarations());
612 612
613 // Perform a stack-check before the body.
614 builder()->StackCheck();
615
613 // Visit statements in the function body. 616 // Visit statements in the function body.
614 VisitStatements(info()->literal()->body()); 617 VisitStatements(info()->literal()->body());
615 } 618 }
616 619
617 620
618 void BytecodeGenerator::VisitBlock(Block* stmt) { 621 void BytecodeGenerator::VisitBlock(Block* stmt) {
619 // Visit declarations and statements. 622 // Visit declarations and statements.
620 if (stmt->scope() != nullptr && stmt->scope()->NeedsContext()) { 623 if (stmt->scope() != nullptr && stmt->scope()->NeedsContext()) {
621 VisitNewLocalBlockContext(stmt->scope()); 624 VisitNewLocalBlockContext(stmt->scope());
622 ContextScope scope(this, stmt->scope()); 625 ContextScope scope(this, stmt->scope());
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 915
913 switch_builder.SetBreakTarget(done_label); 916 switch_builder.SetBreakTarget(done_label);
914 } 917 }
915 918
916 919
917 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { 920 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) {
918 // Handled entirely in VisitSwitchStatement. 921 // Handled entirely in VisitSwitchStatement.
919 UNREACHABLE(); 922 UNREACHABLE();
920 } 923 }
921 924
925 void BytecodeGenerator::VisitIterationBody(IterationStatement* stmt,
926 LoopBuilder* loop_builder) {
927 ControlScopeForIteration execution_control(this, stmt, loop_builder);
928 builder()->StackCheck();
929 Visit(stmt->body());
930 }
922 931
923 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 932 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
924 LoopBuilder loop_builder(builder()); 933 LoopBuilder loop_builder(builder());
925 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
926 loop_builder.LoopHeader(); 934 loop_builder.LoopHeader();
927 if (stmt->cond()->ToBooleanIsFalse()) { 935 if (stmt->cond()->ToBooleanIsFalse()) {
928 Visit(stmt->body()); 936 VisitIterationBody(stmt, &loop_builder);
929 loop_builder.Condition(); 937 loop_builder.Condition();
930 } else if (stmt->cond()->ToBooleanIsTrue()) { 938 } else if (stmt->cond()->ToBooleanIsTrue()) {
931 loop_builder.Condition(); 939 loop_builder.Condition();
932 Visit(stmt->body()); 940 VisitIterationBody(stmt, &loop_builder);
933 loop_builder.JumpToHeader(); 941 loop_builder.JumpToHeader();
934 } else { 942 } else {
935 Visit(stmt->body()); 943 VisitIterationBody(stmt, &loop_builder);
936 loop_builder.Condition(); 944 loop_builder.Condition();
937 VisitForAccumulatorValue(stmt->cond()); 945 VisitForAccumulatorValue(stmt->cond());
938 loop_builder.JumpToHeaderIfTrue(); 946 loop_builder.JumpToHeaderIfTrue();
939 } 947 }
940 loop_builder.EndLoop(); 948 loop_builder.EndLoop();
941 } 949 }
942 950
943
944 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 951 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
945 if (stmt->cond()->ToBooleanIsFalse()) { 952 if (stmt->cond()->ToBooleanIsFalse()) {
946 // If the condition is false there is no need to generate the loop. 953 // If the condition is false there is no need to generate the loop.
947 return; 954 return;
948 } 955 }
949 956
950 LoopBuilder loop_builder(builder()); 957 LoopBuilder loop_builder(builder());
951 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
952 loop_builder.LoopHeader(); 958 loop_builder.LoopHeader();
953 loop_builder.Condition(); 959 loop_builder.Condition();
954 if (!stmt->cond()->ToBooleanIsTrue()) { 960 if (!stmt->cond()->ToBooleanIsTrue()) {
955 VisitForAccumulatorValue(stmt->cond()); 961 VisitForAccumulatorValue(stmt->cond());
956 loop_builder.BreakIfFalse(); 962 loop_builder.BreakIfFalse();
957 } 963 }
958 Visit(stmt->body()); 964 VisitIterationBody(stmt, &loop_builder);
959 loop_builder.JumpToHeader(); 965 loop_builder.JumpToHeader();
960 loop_builder.EndLoop(); 966 loop_builder.EndLoop();
961 } 967 }
962 968
963 969
964 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { 970 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
965 if (stmt->init() != nullptr) { 971 if (stmt->init() != nullptr) {
966 Visit(stmt->init()); 972 Visit(stmt->init());
967 } 973 }
968 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) { 974 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
969 // If the condition is known to be false there is no need to generate 975 // If the condition is known to be false there is no need to generate
970 // body, next or condition blocks. Init block should be generated. 976 // body, next or condition blocks. Init block should be generated.
971 return; 977 return;
972 } 978 }
973 979
974 LoopBuilder loop_builder(builder()); 980 LoopBuilder loop_builder(builder());
975 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
976
977 loop_builder.LoopHeader(); 981 loop_builder.LoopHeader();
978 loop_builder.Condition(); 982 loop_builder.Condition();
979 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) { 983 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
980 VisitForAccumulatorValue(stmt->cond()); 984 VisitForAccumulatorValue(stmt->cond());
981 loop_builder.BreakIfFalse(); 985 loop_builder.BreakIfFalse();
982 } 986 }
983 Visit(stmt->body()); 987 VisitIterationBody(stmt, &loop_builder);
984 if (stmt->next() != nullptr) { 988 if (stmt->next() != nullptr) {
985 loop_builder.Next(); 989 loop_builder.Next();
986 Visit(stmt->next()); 990 Visit(stmt->next());
987 } 991 }
988 loop_builder.JumpToHeader(); 992 loop_builder.JumpToHeader();
989 loop_builder.EndLoop(); 993 loop_builder.EndLoop();
990 } 994 }
991 995
992 996
993 void BytecodeGenerator::VisitForInAssignment(Expression* expr, 997 void BytecodeGenerator::VisitForInAssignment(Expression* expr,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 1038
1035 1039
1036 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { 1040 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
1037 if (stmt->subject()->IsNullLiteral() || 1041 if (stmt->subject()->IsNullLiteral() ||
1038 stmt->subject()->IsUndefinedLiteral(isolate())) { 1042 stmt->subject()->IsUndefinedLiteral(isolate())) {
1039 // ForIn generates lots of code, skip if it wouldn't produce any effects. 1043 // ForIn generates lots of code, skip if it wouldn't produce any effects.
1040 return; 1044 return;
1041 } 1045 }
1042 1046
1043 LoopBuilder loop_builder(builder()); 1047 LoopBuilder loop_builder(builder());
1044 ControlScopeForIteration control_scope(this, stmt, &loop_builder);
1045 BytecodeLabel subject_null_label, subject_undefined_label, not_object_label; 1048 BytecodeLabel subject_null_label, subject_undefined_label, not_object_label;
1046 1049
1047 // Prepare the state for executing ForIn. 1050 // Prepare the state for executing ForIn.
1048 VisitForAccumulatorValue(stmt->subject()); 1051 VisitForAccumulatorValue(stmt->subject());
1049 builder()->JumpIfUndefined(&subject_undefined_label); 1052 builder()->JumpIfUndefined(&subject_undefined_label);
1050 builder()->JumpIfNull(&subject_null_label); 1053 builder()->JumpIfNull(&subject_null_label);
1051 Register receiver = register_allocator()->NewRegister(); 1054 Register receiver = register_allocator()->NewRegister();
1052 builder()->CastAccumulatorToJSObject(); 1055 builder()->CastAccumulatorToJSObject();
1053 builder()->JumpIfNull(&not_object_label); 1056 builder()->JumpIfNull(&not_object_label);
1054 builder()->StoreAccumulatorInRegister(receiver); 1057 builder()->StoreAccumulatorInRegister(receiver);
(...skipping 13 matching lines...) Expand all
1068 1071
1069 // The loop 1072 // The loop
1070 loop_builder.LoopHeader(); 1073 loop_builder.LoopHeader();
1071 loop_builder.Condition(); 1074 loop_builder.Condition();
1072 builder()->ForInDone(index, cache_length); 1075 builder()->ForInDone(index, cache_length);
1073 loop_builder.BreakIfTrue(); 1076 loop_builder.BreakIfTrue();
1074 DCHECK(Register::AreContiguous(cache_type, cache_array)); 1077 DCHECK(Register::AreContiguous(cache_type, cache_array));
1075 builder()->ForInNext(receiver, index, cache_type); 1078 builder()->ForInNext(receiver, index, cache_type);
1076 loop_builder.ContinueIfUndefined(); 1079 loop_builder.ContinueIfUndefined();
1077 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); 1080 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
1078 Visit(stmt->body()); 1081 VisitIterationBody(stmt, &loop_builder);
1079 loop_builder.Next(); 1082 loop_builder.Next();
1080 builder()->ForInStep(index); 1083 builder()->ForInStep(index);
1081 builder()->StoreAccumulatorInRegister(index); 1084 builder()->StoreAccumulatorInRegister(index);
1082 loop_builder.JumpToHeader(); 1085 loop_builder.JumpToHeader();
1083 loop_builder.EndLoop(); 1086 loop_builder.EndLoop();
1084 builder()->Bind(&not_object_label); 1087 builder()->Bind(&not_object_label);
1085 builder()->Bind(&subject_null_label); 1088 builder()->Bind(&subject_null_label);
1086 builder()->Bind(&subject_undefined_label); 1089 builder()->Bind(&subject_undefined_label);
1087 } 1090 }
1088 1091
1089 1092
1090 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { 1093 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
1091 LoopBuilder loop_builder(builder()); 1094 LoopBuilder loop_builder(builder());
1092 ControlScopeForIteration control_scope(this, stmt, &loop_builder); 1095 ControlScopeForIteration control_scope(this, stmt, &loop_builder);
1093 1096
1094 VisitForEffect(stmt->assign_iterator()); 1097 VisitForEffect(stmt->assign_iterator());
1095 1098
1096 loop_builder.LoopHeader(); 1099 loop_builder.LoopHeader();
1097 loop_builder.Next(); 1100 loop_builder.Next();
1098 VisitForEffect(stmt->next_result()); 1101 VisitForEffect(stmt->next_result());
1099 VisitForAccumulatorValue(stmt->result_done()); 1102 VisitForAccumulatorValue(stmt->result_done());
1100 loop_builder.BreakIfTrue(); 1103 loop_builder.BreakIfTrue();
1101 1104
1102 VisitForEffect(stmt->assign_each()); 1105 VisitForEffect(stmt->assign_each());
1103 Visit(stmt->body()); 1106 VisitIterationBody(stmt, &loop_builder);
1104 loop_builder.JumpToHeader(); 1107 loop_builder.JumpToHeader();
1105 loop_builder.EndLoop(); 1108 loop_builder.EndLoop();
1106 } 1109 }
1107 1110
1108 1111
1109 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1112 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1110 TryCatchBuilder try_control_builder(builder()); 1113 TryCatchBuilder try_control_builder(builder());
1111 1114
1112 // Preserve the context in a dedicated register, so that it can be restored 1115 // Preserve the context in a dedicated register, so that it can be restored
1113 // when the handler is entered by the stack-unwinding machinery. 1116 // when the handler is entered by the stack-unwinding machinery.
(...skipping 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after
2507 } 2510 }
2508 2511
2509 2512
2510 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 2513 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
2511 return info()->feedback_vector()->GetIndex(slot); 2514 return info()->feedback_vector()->GetIndex(slot);
2512 } 2515 }
2513 2516
2514 } // namespace interpreter 2517 } // namespace interpreter
2515 } // namespace internal 2518 } // namespace internal
2516 } // namespace v8 2519 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698