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

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: Fix unittests. 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
« no previous file with comments | « src/interpreter/bytecode-generator.h ('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/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 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 602
603 // Visit illegal re-declaration and bail out if it exists. 603 // Visit illegal re-declaration and bail out if it exists.
604 if (scope()->HasIllegalRedeclaration()) { 604 if (scope()->HasIllegalRedeclaration()) {
605 VisitForEffect(scope()->GetIllegalRedeclaration()); 605 VisitForEffect(scope()->GetIllegalRedeclaration());
606 return; 606 return;
607 } 607 }
608 608
609 // Visit declarations within the function scope. 609 // Visit declarations within the function scope.
610 VisitDeclarations(scope()->declarations()); 610 VisitDeclarations(scope()->declarations());
611 611
612 // Perform a stack-check before the body.
613 builder()->StackCheck();
614
612 // Visit statements in the function body. 615 // Visit statements in the function body.
613 VisitStatements(info()->literal()->body()); 616 VisitStatements(info()->literal()->body());
614 } 617 }
615 618
616 619
617 void BytecodeGenerator::VisitBlock(Block* stmt) { 620 void BytecodeGenerator::VisitBlock(Block* stmt) {
618 // Visit declarations and statements. 621 // Visit declarations and statements.
619 if (stmt->scope() != nullptr && stmt->scope()->NeedsContext()) { 622 if (stmt->scope() != nullptr && stmt->scope()->NeedsContext()) {
620 VisitNewLocalBlockContext(stmt->scope()); 623 VisitNewLocalBlockContext(stmt->scope());
621 ContextScope scope(this, stmt->scope()); 624 ContextScope scope(this, stmt->scope());
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 917
915 switch_builder.SetBreakTarget(done_label); 918 switch_builder.SetBreakTarget(done_label);
916 } 919 }
917 920
918 921
919 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { 922 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) {
920 // Handled entirely in VisitSwitchStatement. 923 // Handled entirely in VisitSwitchStatement.
921 UNREACHABLE(); 924 UNREACHABLE();
922 } 925 }
923 926
927 void BytecodeGenerator::VisitIterationBody(IterationStatement* stmt,
928 LoopBuilder* loop_builder) {
929 ControlScopeForIteration execution_control(this, stmt, loop_builder);
930 builder()->StackCheck();
931 Visit(stmt->body());
932 }
924 933
925 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 934 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
926 LoopBuilder loop_builder(builder()); 935 LoopBuilder loop_builder(builder());
927 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
928 loop_builder.LoopHeader(); 936 loop_builder.LoopHeader();
929 if (stmt->cond()->ToBooleanIsFalse()) { 937 if (stmt->cond()->ToBooleanIsFalse()) {
930 Visit(stmt->body()); 938 VisitIterationBody(stmt, &loop_builder);
931 loop_builder.Condition(); 939 loop_builder.Condition();
932 } else if (stmt->cond()->ToBooleanIsTrue()) { 940 } else if (stmt->cond()->ToBooleanIsTrue()) {
933 loop_builder.Condition(); 941 loop_builder.Condition();
934 Visit(stmt->body()); 942 VisitIterationBody(stmt, &loop_builder);
935 loop_builder.JumpToHeader(); 943 loop_builder.JumpToHeader();
936 } else { 944 } else {
937 Visit(stmt->body()); 945 VisitIterationBody(stmt, &loop_builder);
938 loop_builder.Condition(); 946 loop_builder.Condition();
939 VisitForAccumulatorValue(stmt->cond()); 947 VisitForAccumulatorValue(stmt->cond());
940 loop_builder.JumpToHeaderIfTrue(); 948 loop_builder.JumpToHeaderIfTrue();
941 } 949 }
942 loop_builder.EndLoop(); 950 loop_builder.EndLoop();
943 } 951 }
944 952
945
946 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 953 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
947 if (stmt->cond()->ToBooleanIsFalse()) { 954 if (stmt->cond()->ToBooleanIsFalse()) {
948 // If the condition is false there is no need to generate the loop. 955 // If the condition is false there is no need to generate the loop.
949 return; 956 return;
950 } 957 }
951 958
952 LoopBuilder loop_builder(builder()); 959 LoopBuilder loop_builder(builder());
953 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
954 loop_builder.LoopHeader(); 960 loop_builder.LoopHeader();
955 loop_builder.Condition(); 961 loop_builder.Condition();
956 if (!stmt->cond()->ToBooleanIsTrue()) { 962 if (!stmt->cond()->ToBooleanIsTrue()) {
957 VisitForAccumulatorValue(stmt->cond()); 963 VisitForAccumulatorValue(stmt->cond());
958 loop_builder.BreakIfFalse(); 964 loop_builder.BreakIfFalse();
959 } 965 }
960 Visit(stmt->body()); 966 VisitIterationBody(stmt, &loop_builder);
961 loop_builder.JumpToHeader(); 967 loop_builder.JumpToHeader();
962 loop_builder.EndLoop(); 968 loop_builder.EndLoop();
963 } 969 }
964 970
965 971
966 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { 972 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
967 if (stmt->init() != nullptr) { 973 if (stmt->init() != nullptr) {
968 Visit(stmt->init()); 974 Visit(stmt->init());
969 } 975 }
970 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) { 976 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
971 // If the condition is known to be false there is no need to generate 977 // If the condition is known to be false there is no need to generate
972 // body, next or condition blocks. Init block should be generated. 978 // body, next or condition blocks. Init block should be generated.
973 return; 979 return;
974 } 980 }
975 981
976 LoopBuilder loop_builder(builder()); 982 LoopBuilder loop_builder(builder());
977 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
978
979 loop_builder.LoopHeader(); 983 loop_builder.LoopHeader();
980 loop_builder.Condition(); 984 loop_builder.Condition();
981 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) { 985 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
982 VisitForAccumulatorValue(stmt->cond()); 986 VisitForAccumulatorValue(stmt->cond());
983 loop_builder.BreakIfFalse(); 987 loop_builder.BreakIfFalse();
984 } 988 }
985 Visit(stmt->body()); 989 VisitIterationBody(stmt, &loop_builder);
986 if (stmt->next() != nullptr) { 990 if (stmt->next() != nullptr) {
987 loop_builder.Next(); 991 loop_builder.Next();
988 Visit(stmt->next()); 992 Visit(stmt->next());
989 } 993 }
990 loop_builder.JumpToHeader(); 994 loop_builder.JumpToHeader();
991 loop_builder.EndLoop(); 995 loop_builder.EndLoop();
992 } 996 }
993 997
994 998
995 void BytecodeGenerator::VisitForInAssignment(Expression* expr, 999 void BytecodeGenerator::VisitForInAssignment(Expression* expr,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 1040
1037 1041
1038 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { 1042 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
1039 if (stmt->subject()->IsNullLiteral() || 1043 if (stmt->subject()->IsNullLiteral() ||
1040 stmt->subject()->IsUndefinedLiteral(isolate())) { 1044 stmt->subject()->IsUndefinedLiteral(isolate())) {
1041 // ForIn generates lots of code, skip if it wouldn't produce any effects. 1045 // ForIn generates lots of code, skip if it wouldn't produce any effects.
1042 return; 1046 return;
1043 } 1047 }
1044 1048
1045 LoopBuilder loop_builder(builder()); 1049 LoopBuilder loop_builder(builder());
1046 ControlScopeForIteration control_scope(this, stmt, &loop_builder);
1047 BytecodeLabel subject_null_label, subject_undefined_label, not_object_label; 1050 BytecodeLabel subject_null_label, subject_undefined_label, not_object_label;
1048 1051
1049 // Prepare the state for executing ForIn. 1052 // Prepare the state for executing ForIn.
1050 VisitForAccumulatorValue(stmt->subject()); 1053 VisitForAccumulatorValue(stmt->subject());
1051 builder()->JumpIfUndefined(&subject_undefined_label); 1054 builder()->JumpIfUndefined(&subject_undefined_label);
1052 builder()->JumpIfNull(&subject_null_label); 1055 builder()->JumpIfNull(&subject_null_label);
1053 Register receiver = register_allocator()->NewRegister(); 1056 Register receiver = register_allocator()->NewRegister();
1054 builder()->CastAccumulatorToJSObject(); 1057 builder()->CastAccumulatorToJSObject();
1055 builder()->JumpIfNull(&not_object_label); 1058 builder()->JumpIfNull(&not_object_label);
1056 builder()->StoreAccumulatorInRegister(receiver); 1059 builder()->StoreAccumulatorInRegister(receiver);
(...skipping 13 matching lines...) Expand all
1070 1073
1071 // The loop 1074 // The loop
1072 loop_builder.LoopHeader(); 1075 loop_builder.LoopHeader();
1073 loop_builder.Condition(); 1076 loop_builder.Condition();
1074 builder()->ForInDone(index, cache_length); 1077 builder()->ForInDone(index, cache_length);
1075 loop_builder.BreakIfTrue(); 1078 loop_builder.BreakIfTrue();
1076 DCHECK(Register::AreContiguous(cache_type, cache_array)); 1079 DCHECK(Register::AreContiguous(cache_type, cache_array));
1077 builder()->ForInNext(receiver, index, cache_type); 1080 builder()->ForInNext(receiver, index, cache_type);
1078 loop_builder.ContinueIfUndefined(); 1081 loop_builder.ContinueIfUndefined();
1079 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); 1082 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
1080 Visit(stmt->body()); 1083 VisitIterationBody(stmt, &loop_builder);
1081 loop_builder.Next(); 1084 loop_builder.Next();
1082 builder()->ForInStep(index); 1085 builder()->ForInStep(index);
1083 builder()->StoreAccumulatorInRegister(index); 1086 builder()->StoreAccumulatorInRegister(index);
1084 loop_builder.JumpToHeader(); 1087 loop_builder.JumpToHeader();
1085 loop_builder.EndLoop(); 1088 loop_builder.EndLoop();
1086 builder()->Bind(&not_object_label); 1089 builder()->Bind(&not_object_label);
1087 builder()->Bind(&subject_null_label); 1090 builder()->Bind(&subject_null_label);
1088 builder()->Bind(&subject_undefined_label); 1091 builder()->Bind(&subject_undefined_label);
1089 } 1092 }
1090 1093
1091 1094
1092 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { 1095 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
1093 LoopBuilder loop_builder(builder()); 1096 LoopBuilder loop_builder(builder());
1094 ControlScopeForIteration control_scope(this, stmt, &loop_builder); 1097 ControlScopeForIteration control_scope(this, stmt, &loop_builder);
1095 1098
1096 VisitForEffect(stmt->assign_iterator()); 1099 VisitForEffect(stmt->assign_iterator());
1097 1100
1098 loop_builder.LoopHeader(); 1101 loop_builder.LoopHeader();
1099 loop_builder.Next(); 1102 loop_builder.Next();
1100 VisitForEffect(stmt->next_result()); 1103 VisitForEffect(stmt->next_result());
1101 VisitForAccumulatorValue(stmt->result_done()); 1104 VisitForAccumulatorValue(stmt->result_done());
1102 loop_builder.BreakIfTrue(); 1105 loop_builder.BreakIfTrue();
1103 1106
1104 VisitForEffect(stmt->assign_each()); 1107 VisitForEffect(stmt->assign_each());
1105 Visit(stmt->body()); 1108 VisitIterationBody(stmt, &loop_builder);
1106 loop_builder.JumpToHeader(); 1109 loop_builder.JumpToHeader();
1107 loop_builder.EndLoop(); 1110 loop_builder.EndLoop();
1108 } 1111 }
1109 1112
1110 1113
1111 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1114 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1112 TryCatchBuilder try_control_builder(builder()); 1115 TryCatchBuilder try_control_builder(builder());
1113 Register no_reg; 1116 Register no_reg;
1114 1117
1115 // Preserve the context in a dedicated register, so that it can be restored 1118 // Preserve the context in a dedicated register, so that it can be restored
(...skipping 1433 matching lines...) Expand 10 before | Expand all | Expand 10 after
2549 } 2552 }
2550 2553
2551 2554
2552 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 2555 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
2553 return info()->feedback_vector()->GetIndex(slot); 2556 return info()->feedback_vector()->GetIndex(slot);
2554 } 2557 }
2555 2558
2556 } // namespace interpreter 2559 } // namespace interpreter
2557 } // namespace internal 2560 } // namespace internal
2558 } // namespace v8 2561 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698