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

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

Issue 2254493002: [interpreter] Use VisitForTest for loop conditions (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: typo Created 4 years, 4 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/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/compiler.h" 9 #include "src/compiler.h"
10 #include "src/interpreter/bytecode-flags.h" 10 #include "src/interpreter/bytecode-flags.h"
(...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 SwitchBuilder switch_builder(builder(), clauses->length()); 1111 SwitchBuilder switch_builder(builder(), clauses->length());
1112 ControlScopeForBreakable scope(this, stmt, &switch_builder); 1112 ControlScopeForBreakable scope(this, stmt, &switch_builder);
1113 int default_index = -1; 1113 int default_index = -1;
1114 1114
1115 builder()->SetStatementPosition(stmt); 1115 builder()->SetStatementPosition(stmt);
1116 1116
1117 // Keep the switch value in a register until a case matches. 1117 // Keep the switch value in a register until a case matches.
1118 Register tag = VisitForRegisterValue(stmt->tag()); 1118 Register tag = VisitForRegisterValue(stmt->tag());
1119 1119
1120 // Iterate over all cases and create nodes for label comparison. 1120 // Iterate over all cases and create nodes for label comparison.
1121 BytecodeLabel done_label;
1122 for (int i = 0; i < clauses->length(); i++) { 1121 for (int i = 0; i < clauses->length(); i++) {
1123 CaseClause* clause = clauses->at(i); 1122 CaseClause* clause = clauses->at(i);
1124 1123
1125 // The default is not a test, remember index. 1124 // The default is not a test, remember index.
1126 if (clause->is_default()) { 1125 if (clause->is_default()) {
1127 default_index = i; 1126 default_index = i;
1128 continue; 1127 continue;
1129 } 1128 }
1130 1129
1131 // Perform label comparison as if via '===' with tag. 1130 // Perform label comparison as if via '===' with tag.
1132 VisitForAccumulatorValue(clause->label()); 1131 VisitForAccumulatorValue(clause->label());
1133 builder()->CompareOperation(Token::Value::EQ_STRICT, tag); 1132 builder()->CompareOperation(Token::Value::EQ_STRICT, tag);
1134 switch_builder.Case(i); 1133 switch_builder.Case(i);
1135 } 1134 }
1136 1135
1137 if (default_index >= 0) { 1136 if (default_index >= 0) {
1138 // Emit default jump if there is a default case. 1137 // Emit default jump if there is a default case.
1139 switch_builder.DefaultAt(default_index); 1138 switch_builder.DefaultAt(default_index);
1140 } else { 1139 } else {
1141 // Otherwise if we have reached here none of the cases matched, so jump to 1140 // Otherwise if we have reached here none of the cases matched, so jump to
1142 // done. 1141 // the end.
1143 builder()->Jump(&done_label); 1142 switch_builder.Break();
1144 } 1143 }
1145 1144
1146 // Iterate over all cases and create the case bodies. 1145 // Iterate over all cases and create the case bodies.
1147 for (int i = 0; i < clauses->length(); i++) { 1146 for (int i = 0; i < clauses->length(); i++) {
1148 CaseClause* clause = clauses->at(i); 1147 CaseClause* clause = clauses->at(i);
1149 switch_builder.SetCaseTarget(i); 1148 switch_builder.SetCaseTarget(i);
1150 VisitStatements(clause->statements()); 1149 VisitStatements(clause->statements());
1151 } 1150 }
1152 builder()->Bind(&done_label); 1151 switch_builder.BindBreakTarget();
1153
1154 switch_builder.SetBreakTarget(done_label);
1155 } 1152 }
1156 1153
1157 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { 1154 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) {
1158 // Handled entirely in VisitSwitchStatement. 1155 // Handled entirely in VisitSwitchStatement.
1159 UNREACHABLE(); 1156 UNREACHABLE();
1160 } 1157 }
1161 1158
1162 void BytecodeGenerator::VisitIterationBody(IterationStatement* stmt, 1159 void BytecodeGenerator::VisitIterationBody(IterationStatement* stmt,
1163 LoopBuilder* loop_builder) { 1160 LoopBuilder* loop_builder) {
1164 ControlScopeForIteration execution_control(this, stmt, loop_builder); 1161 ControlScopeForIteration execution_control(this, stmt, loop_builder);
1165 builder()->StackCheck(stmt->position()); 1162 builder()->StackCheck(stmt->position());
1166 Visit(stmt->body()); 1163 Visit(stmt->body());
1167 loop_builder->SetContinueTarget(); 1164 loop_builder->BindContinueTarget();
1168 } 1165 }
1169 1166
1170 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 1167 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
1171 LoopBuilder loop_builder(builder()); 1168 LoopBuilder loop_builder(builder());
1172 if (stmt->cond()->ToBooleanIsFalse()) { 1169 if (stmt->cond()->ToBooleanIsFalse()) {
1173 VisitIterationBody(stmt, &loop_builder); 1170 VisitIterationBody(stmt, &loop_builder);
1174 } else if (stmt->cond()->ToBooleanIsTrue()) { 1171 } else if (stmt->cond()->ToBooleanIsTrue()) {
1175 VisitIterationHeader(stmt, &loop_builder); 1172 VisitIterationHeader(stmt, &loop_builder);
1176 VisitIterationBody(stmt, &loop_builder); 1173 VisitIterationBody(stmt, &loop_builder);
1177 loop_builder.JumpToHeader(); 1174 loop_builder.JumpToHeader();
1178 } else { 1175 } else {
1179 VisitIterationHeader(stmt, &loop_builder); 1176 VisitIterationHeader(stmt, &loop_builder);
1180 VisitIterationBody(stmt, &loop_builder); 1177 VisitIterationBody(stmt, &loop_builder);
1181 builder()->SetExpressionAsStatementPosition(stmt->cond()); 1178 builder()->SetExpressionAsStatementPosition(stmt->cond());
1182 // TODO(klaasb) VisitForTest for loop conditions 1179 VisitForTest(stmt->cond(), loop_builder.header_labels(),
Michael Starzinger 2016/08/18 13:24:28 Just for posterity: I am fine with this. But this
klaasb 2016/08/18 13:50:11 True. However, when/if that's needed we could just
1183 VisitForAccumulatorValue(stmt->cond()); 1180 loop_builder.break_labels(), TestFallthrough::kElse);
1184 loop_builder.JumpToHeaderIfTrue();
1185 } 1181 }
1186 loop_builder.EndLoop(); 1182 loop_builder.EndLoop();
1187 } 1183 }
1188 1184
1189 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 1185 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
1190 if (stmt->cond()->ToBooleanIsFalse()) { 1186 if (stmt->cond()->ToBooleanIsFalse()) {
1191 // If the condition is false there is no need to generate the loop. 1187 // If the condition is false there is no need to generate the loop.
1192 return; 1188 return;
1193 } 1189 }
1194 1190
1195 LoopBuilder loop_builder(builder()); 1191 LoopBuilder loop_builder(builder());
1196 VisitIterationHeader(stmt, &loop_builder); 1192 VisitIterationHeader(stmt, &loop_builder);
1197 if (!stmt->cond()->ToBooleanIsTrue()) { 1193 if (!stmt->cond()->ToBooleanIsTrue()) {
1198 builder()->SetExpressionAsStatementPosition(stmt->cond()); 1194 builder()->SetExpressionAsStatementPosition(stmt->cond());
1199 // TODO(klaasb) VisitForTest for loop conditions 1195 BytecodeLabels loop_body(zone());
1200 VisitForAccumulatorValue(stmt->cond()); 1196 VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(),
1201 loop_builder.BreakIfFalse(); 1197 TestFallthrough::kThen);
1198 loop_body.Bind(builder());
1202 } 1199 }
1203 VisitIterationBody(stmt, &loop_builder); 1200 VisitIterationBody(stmt, &loop_builder);
1204 loop_builder.JumpToHeader(); 1201 loop_builder.JumpToHeader();
1205 loop_builder.EndLoop(); 1202 loop_builder.EndLoop();
1206 } 1203 }
1207 1204
1208 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { 1205 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
1209 if (stmt->init() != nullptr) { 1206 if (stmt->init() != nullptr) {
1210 Visit(stmt->init()); 1207 Visit(stmt->init());
1211 } 1208 }
1212 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) { 1209 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
1213 // If the condition is known to be false there is no need to generate 1210 // If the condition is known to be false there is no need to generate
1214 // body, next or condition blocks. Init block should be generated. 1211 // body, next or condition blocks. Init block should be generated.
1215 return; 1212 return;
1216 } 1213 }
1217 1214
1218 LoopBuilder loop_builder(builder()); 1215 LoopBuilder loop_builder(builder());
1219 VisitIterationHeader(stmt, &loop_builder); 1216 VisitIterationHeader(stmt, &loop_builder);
1220 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) { 1217 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
1221 builder()->SetExpressionAsStatementPosition(stmt->cond()); 1218 builder()->SetExpressionAsStatementPosition(stmt->cond());
1222 // TODO(klaasb) VisitForTest for loop conditions 1219 BytecodeLabels loop_body(zone());
1223 VisitForAccumulatorValue(stmt->cond()); 1220 VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(),
1224 loop_builder.BreakIfFalse(); 1221 TestFallthrough::kThen);
1222 loop_body.Bind(builder());
1225 } 1223 }
1226 VisitIterationBody(stmt, &loop_builder); 1224 VisitIterationBody(stmt, &loop_builder);
1227 if (stmt->next() != nullptr) { 1225 if (stmt->next() != nullptr) {
1228 builder()->SetStatementPosition(stmt->next()); 1226 builder()->SetStatementPosition(stmt->next());
1229 Visit(stmt->next()); 1227 Visit(stmt->next());
1230 } 1228 }
1231 loop_builder.JumpToHeader(); 1229 loop_builder.JumpToHeader();
1232 loop_builder.EndLoop(); 1230 loop_builder.EndLoop();
1233 } 1231 }
1234 1232
(...skipping 2187 matching lines...) Expand 10 before | Expand all | Expand 10 after
3422 return execution_context()->scope()->language_mode(); 3420 return execution_context()->scope()->language_mode();
3423 } 3421 }
3424 3422
3425 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 3423 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
3426 return TypeFeedbackVector::GetIndex(slot); 3424 return TypeFeedbackVector::GetIndex(slot);
3427 } 3425 }
3428 3426
3429 } // namespace interpreter 3427 } // namespace interpreter
3430 } // namespace internal 3428 } // namespace internal
3431 } // namespace v8 3429 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698