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

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

Issue 2331033002: [interpreter] Merge {OsrPoll} with {Jump} bytecode. (Closed)
Patch Set: One more test. Created 4 years, 3 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-array-writer.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/compile-time-value.h" 7 #include "src/ast/compile-time-value.h"
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/compilation-info.h" 10 #include "src/compilation-info.h"
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 size_t first_yield = stmt->first_yield_id(); 819 size_t first_yield = stmt->first_yield_id();
820 DCHECK_LE(first_yield + stmt->yield_count(), generator_resume_points_.size()); 820 DCHECK_LE(first_yield + stmt->yield_count(), generator_resume_points_.size());
821 for (size_t id = first_yield; id < first_yield + stmt->yield_count(); id++) { 821 for (size_t id = first_yield; id < first_yield + stmt->yield_count(); id++) {
822 auto& label = generator_resume_points_[id]; 822 auto& label = generator_resume_points_[id];
823 resume_points_in_loop.push_back(label); 823 resume_points_in_loop.push_back(label);
824 generator_resume_points_[id] = BytecodeLabel(); 824 generator_resume_points_[id] = BytecodeLabel();
825 } 825 }
826 826
827 loop_builder->LoopHeader(&resume_points_in_loop); 827 loop_builder->LoopHeader(&resume_points_in_loop);
828 828
829 // Insert an explicit {OsrPoll} right after the loop header, to trigger
830 // on-stack replacement when armed for the given loop nesting depth.
831 if (FLAG_ignition_osr) {
832 // TODO(4764): Merge this with another bytecode (e.g. {Jump} back edge).
833 int level = Min(loop_depth_, AbstractCode::kMaxLoopNestingMarker - 1);
834 builder()->OsrPoll(level);
835 }
836
837 if (stmt->yield_count() > 0) { 829 if (stmt->yield_count() > 0) {
838 // If we are not resuming, fall through to loop body. 830 // If we are not resuming, fall through to loop body.
839 // If we are resuming, perform state dispatch. 831 // If we are resuming, perform state dispatch.
840 BytecodeLabel not_resuming; 832 BytecodeLabel not_resuming;
841 builder() 833 builder()
842 ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)) 834 ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
843 .CompareOperation(Token::Value::EQ, generator_state_) 835 .CompareOperation(Token::Value::EQ, generator_state_)
844 .JumpIfTrue(&not_resuming); 836 .JumpIfTrue(&not_resuming);
845 BuildIndexedJump(generator_state_, first_yield, 837 BuildIndexedJump(generator_state_, first_yield,
846 stmt->yield_count(), generator_resume_points_); 838 stmt->yield_count(), generator_resume_points_);
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 loop_builder->BindContinueTarget(); 1155 loop_builder->BindContinueTarget();
1164 } 1156 }
1165 1157
1166 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 1158 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
1167 LoopBuilder loop_builder(builder()); 1159 LoopBuilder loop_builder(builder());
1168 if (stmt->cond()->ToBooleanIsFalse()) { 1160 if (stmt->cond()->ToBooleanIsFalse()) {
1169 VisitIterationBody(stmt, &loop_builder); 1161 VisitIterationBody(stmt, &loop_builder);
1170 } else if (stmt->cond()->ToBooleanIsTrue()) { 1162 } else if (stmt->cond()->ToBooleanIsTrue()) {
1171 VisitIterationHeader(stmt, &loop_builder); 1163 VisitIterationHeader(stmt, &loop_builder);
1172 VisitIterationBody(stmt, &loop_builder); 1164 VisitIterationBody(stmt, &loop_builder);
1173 loop_builder.JumpToHeader(); 1165 loop_builder.JumpToHeader(loop_depth_);
1174 } else { 1166 } else {
1175 VisitIterationHeader(stmt, &loop_builder); 1167 VisitIterationHeader(stmt, &loop_builder);
1176 VisitIterationBody(stmt, &loop_builder); 1168 VisitIterationBody(stmt, &loop_builder);
1177 builder()->SetExpressionAsStatementPosition(stmt->cond()); 1169 builder()->SetExpressionAsStatementPosition(stmt->cond());
1178 VisitForTest(stmt->cond(), loop_builder.header_labels(), 1170 BytecodeLabels loop_backbranch(zone());
1179 loop_builder.break_labels(), TestFallthrough::kElse); 1171 VisitForTest(stmt->cond(), &loop_backbranch, loop_builder.break_labels(),
1172 TestFallthrough::kThen);
1173 loop_backbranch.Bind(builder());
1174 loop_builder.JumpToHeader(loop_depth_);
1180 } 1175 }
1181 loop_builder.EndLoop(); 1176 loop_builder.EndLoop();
1182 } 1177 }
1183 1178
1184 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 1179 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
1185 if (stmt->cond()->ToBooleanIsFalse()) { 1180 if (stmt->cond()->ToBooleanIsFalse()) {
1186 // If the condition is false there is no need to generate the loop. 1181 // If the condition is false there is no need to generate the loop.
1187 return; 1182 return;
1188 } 1183 }
1189 1184
1190 LoopBuilder loop_builder(builder()); 1185 LoopBuilder loop_builder(builder());
1191 VisitIterationHeader(stmt, &loop_builder); 1186 VisitIterationHeader(stmt, &loop_builder);
1192 if (!stmt->cond()->ToBooleanIsTrue()) { 1187 if (!stmt->cond()->ToBooleanIsTrue()) {
1193 builder()->SetExpressionAsStatementPosition(stmt->cond()); 1188 builder()->SetExpressionAsStatementPosition(stmt->cond());
1194 BytecodeLabels loop_body(zone()); 1189 BytecodeLabels loop_body(zone());
1195 VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(), 1190 VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(),
1196 TestFallthrough::kThen); 1191 TestFallthrough::kThen);
1197 loop_body.Bind(builder()); 1192 loop_body.Bind(builder());
1198 } 1193 }
1199 VisitIterationBody(stmt, &loop_builder); 1194 VisitIterationBody(stmt, &loop_builder);
1200 loop_builder.JumpToHeader(); 1195 loop_builder.JumpToHeader(loop_depth_);
1201 loop_builder.EndLoop(); 1196 loop_builder.EndLoop();
1202 } 1197 }
1203 1198
1204 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { 1199 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
1205 if (stmt->init() != nullptr) { 1200 if (stmt->init() != nullptr) {
1206 Visit(stmt->init()); 1201 Visit(stmt->init());
1207 } 1202 }
1208 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) { 1203 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
1209 // If the condition is known to be false there is no need to generate 1204 // If the condition is known to be false there is no need to generate
1210 // body, next or condition blocks. Init block should be generated. 1205 // body, next or condition blocks. Init block should be generated.
1211 return; 1206 return;
1212 } 1207 }
1213 1208
1214 LoopBuilder loop_builder(builder()); 1209 LoopBuilder loop_builder(builder());
1215 VisitIterationHeader(stmt, &loop_builder); 1210 VisitIterationHeader(stmt, &loop_builder);
1216 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) { 1211 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
1217 builder()->SetExpressionAsStatementPosition(stmt->cond()); 1212 builder()->SetExpressionAsStatementPosition(stmt->cond());
1218 BytecodeLabels loop_body(zone()); 1213 BytecodeLabels loop_body(zone());
1219 VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(), 1214 VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(),
1220 TestFallthrough::kThen); 1215 TestFallthrough::kThen);
1221 loop_body.Bind(builder()); 1216 loop_body.Bind(builder());
1222 } 1217 }
1223 VisitIterationBody(stmt, &loop_builder); 1218 VisitIterationBody(stmt, &loop_builder);
1224 if (stmt->next() != nullptr) { 1219 if (stmt->next() != nullptr) {
1225 builder()->SetStatementPosition(stmt->next()); 1220 builder()->SetStatementPosition(stmt->next());
1226 Visit(stmt->next()); 1221 Visit(stmt->next());
1227 } 1222 }
1228 loop_builder.JumpToHeader(); 1223 loop_builder.JumpToHeader(loop_depth_);
1229 loop_builder.EndLoop(); 1224 loop_builder.EndLoop();
1230 } 1225 }
1231 1226
1232 void BytecodeGenerator::VisitForInAssignment(Expression* expr, 1227 void BytecodeGenerator::VisitForInAssignment(Expression* expr,
1233 FeedbackVectorSlot slot) { 1228 FeedbackVectorSlot slot) {
1234 DCHECK(expr->IsValidReferenceExpression()); 1229 DCHECK(expr->IsValidReferenceExpression());
1235 1230
1236 // Evaluate assignment starting with the value to be stored in the 1231 // Evaluate assignment starting with the value to be stored in the
1237 // accumulator. 1232 // accumulator.
1238 Property* property = expr->AsProperty(); 1233 Property* property = expr->AsProperty();
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1339 builder()->ForInContinue(index, cache_length); 1334 builder()->ForInContinue(index, cache_length);
1340 loop_builder.BreakIfFalse(); 1335 loop_builder.BreakIfFalse();
1341 DCHECK(Register::AreContiguous(cache_type, cache_array)); 1336 DCHECK(Register::AreContiguous(cache_type, cache_array));
1342 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 1337 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
1343 builder()->ForInNext(receiver, index, cache_type, feedback_index(slot)); 1338 builder()->ForInNext(receiver, index, cache_type, feedback_index(slot));
1344 loop_builder.ContinueIfUndefined(); 1339 loop_builder.ContinueIfUndefined();
1345 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); 1340 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
1346 VisitIterationBody(stmt, &loop_builder); 1341 VisitIterationBody(stmt, &loop_builder);
1347 builder()->ForInStep(index); 1342 builder()->ForInStep(index);
1348 builder()->StoreAccumulatorInRegister(index); 1343 builder()->StoreAccumulatorInRegister(index);
1349 loop_builder.JumpToHeader(); 1344 loop_builder.JumpToHeader(loop_depth_);
1350 loop_builder.EndLoop(); 1345 loop_builder.EndLoop();
1351 builder()->Bind(&subject_null_label); 1346 builder()->Bind(&subject_null_label);
1352 builder()->Bind(&subject_undefined_label); 1347 builder()->Bind(&subject_undefined_label);
1353 } 1348 }
1354 1349
1355 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { 1350 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
1356 LoopBuilder loop_builder(builder()); 1351 LoopBuilder loop_builder(builder());
1357 1352
1358 builder()->SetExpressionAsStatementPosition(stmt->assign_iterator()); 1353 builder()->SetExpressionAsStatementPosition(stmt->assign_iterator());
1359 VisitForEffect(stmt->assign_iterator()); 1354 VisitForEffect(stmt->assign_iterator());
1360 1355
1361 VisitIterationHeader(stmt, &loop_builder); 1356 VisitIterationHeader(stmt, &loop_builder);
1362 builder()->SetExpressionAsStatementPosition(stmt->next_result()); 1357 builder()->SetExpressionAsStatementPosition(stmt->next_result());
1363 VisitForEffect(stmt->next_result()); 1358 VisitForEffect(stmt->next_result());
1364 VisitForAccumulatorValue(stmt->result_done()); 1359 VisitForAccumulatorValue(stmt->result_done());
1365 loop_builder.BreakIfTrue(); 1360 loop_builder.BreakIfTrue();
1366 1361
1367 VisitForEffect(stmt->assign_each()); 1362 VisitForEffect(stmt->assign_each());
1368 VisitIterationBody(stmt, &loop_builder); 1363 VisitIterationBody(stmt, &loop_builder);
1369 loop_builder.JumpToHeader(); 1364 loop_builder.JumpToHeader(loop_depth_);
1370 loop_builder.EndLoop(); 1365 loop_builder.EndLoop();
1371 } 1366 }
1372 1367
1373 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1368 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1374 TryCatchBuilder try_control_builder(builder(), stmt->catch_prediction()); 1369 TryCatchBuilder try_control_builder(builder(), stmt->catch_prediction());
1375 Register no_reg; 1370 Register no_reg;
1376 1371
1377 // Preserve the context in a dedicated register, so that it can be restored 1372 // Preserve the context in a dedicated register, so that it can be restored
1378 // when the handler is entered by the stack-unwinding machinery. 1373 // when the handler is entered by the stack-unwinding machinery.
1379 // TODO(mstarzinger): Be smarter about register allocation. 1374 // TODO(mstarzinger): Be smarter about register allocation.
(...skipping 2047 matching lines...) Expand 10 before | Expand all | Expand 10 after
3427 return execution_context()->scope()->language_mode(); 3422 return execution_context()->scope()->language_mode();
3428 } 3423 }
3429 3424
3430 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 3425 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
3431 return TypeFeedbackVector::GetIndex(slot); 3426 return TypeFeedbackVector::GetIndex(slot);
3432 } 3427 }
3433 3428
3434 } // namespace interpreter 3429 } // namespace interpreter
3435 } // namespace internal 3430 } // namespace internal
3436 } // namespace v8 3431 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-array-writer.cc ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698