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

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

Issue 2331033002: [interpreter] Merge {OsrPoll} with {Jump} bytecode. (Closed)
Patch Set: Fix for wide jumps. 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
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 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 loop_builder->BindContinueTarget(); 1154 loop_builder->BindContinueTarget();
1163 } 1155 }
1164 1156
1165 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 1157 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
1166 LoopBuilder loop_builder(builder()); 1158 LoopBuilder loop_builder(builder());
1167 if (stmt->cond()->ToBooleanIsFalse()) { 1159 if (stmt->cond()->ToBooleanIsFalse()) {
1168 VisitIterationBody(stmt, &loop_builder); 1160 VisitIterationBody(stmt, &loop_builder);
1169 } else if (stmt->cond()->ToBooleanIsTrue()) { 1161 } else if (stmt->cond()->ToBooleanIsTrue()) {
1170 VisitIterationHeader(stmt, &loop_builder); 1162 VisitIterationHeader(stmt, &loop_builder);
1171 VisitIterationBody(stmt, &loop_builder); 1163 VisitIterationBody(stmt, &loop_builder);
1172 loop_builder.JumpToHeader(); 1164 loop_builder.JumpToHeader(loop_depth_);
1173 } else { 1165 } else {
1174 VisitIterationHeader(stmt, &loop_builder); 1166 VisitIterationHeader(stmt, &loop_builder);
1175 VisitIterationBody(stmt, &loop_builder); 1167 VisitIterationBody(stmt, &loop_builder);
1176 builder()->SetExpressionAsStatementPosition(stmt->cond()); 1168 builder()->SetExpressionAsStatementPosition(stmt->cond());
1177 VisitForTest(stmt->cond(), loop_builder.header_labels(), 1169 BytecodeLabels loop_backbranch(zone());
1178 loop_builder.break_labels(), TestFallthrough::kElse); 1170 VisitForTest(stmt->cond(), &loop_backbranch, loop_builder.break_labels(),
1171 TestFallthrough::kThen);
1172 loop_backbranch.Bind(builder());
1173 loop_builder.JumpToHeader(loop_depth_);
1179 } 1174 }
1180 loop_builder.EndLoop(); 1175 loop_builder.EndLoop();
1181 } 1176 }
1182 1177
1183 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 1178 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
1184 if (stmt->cond()->ToBooleanIsFalse()) { 1179 if (stmt->cond()->ToBooleanIsFalse()) {
1185 // If the condition is false there is no need to generate the loop. 1180 // If the condition is false there is no need to generate the loop.
1186 return; 1181 return;
1187 } 1182 }
1188 1183
1189 LoopBuilder loop_builder(builder()); 1184 LoopBuilder loop_builder(builder());
1190 VisitIterationHeader(stmt, &loop_builder); 1185 VisitIterationHeader(stmt, &loop_builder);
1191 if (!stmt->cond()->ToBooleanIsTrue()) { 1186 if (!stmt->cond()->ToBooleanIsTrue()) {
1192 builder()->SetExpressionAsStatementPosition(stmt->cond()); 1187 builder()->SetExpressionAsStatementPosition(stmt->cond());
1193 BytecodeLabels loop_body(zone()); 1188 BytecodeLabels loop_body(zone());
1194 VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(), 1189 VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(),
1195 TestFallthrough::kThen); 1190 TestFallthrough::kThen);
1196 loop_body.Bind(builder()); 1191 loop_body.Bind(builder());
1197 } 1192 }
1198 VisitIterationBody(stmt, &loop_builder); 1193 VisitIterationBody(stmt, &loop_builder);
1199 loop_builder.JumpToHeader(); 1194 loop_builder.JumpToHeader(loop_depth_);
1200 loop_builder.EndLoop(); 1195 loop_builder.EndLoop();
1201 } 1196 }
1202 1197
1203 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { 1198 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
1204 if (stmt->init() != nullptr) { 1199 if (stmt->init() != nullptr) {
1205 Visit(stmt->init()); 1200 Visit(stmt->init());
1206 } 1201 }
1207 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) { 1202 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
1208 // If the condition is known to be false there is no need to generate 1203 // If the condition is known to be false there is no need to generate
1209 // body, next or condition blocks. Init block should be generated. 1204 // body, next or condition blocks. Init block should be generated.
1210 return; 1205 return;
1211 } 1206 }
1212 1207
1213 LoopBuilder loop_builder(builder()); 1208 LoopBuilder loop_builder(builder());
1214 VisitIterationHeader(stmt, &loop_builder); 1209 VisitIterationHeader(stmt, &loop_builder);
1215 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) { 1210 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
1216 builder()->SetExpressionAsStatementPosition(stmt->cond()); 1211 builder()->SetExpressionAsStatementPosition(stmt->cond());
1217 BytecodeLabels loop_body(zone()); 1212 BytecodeLabels loop_body(zone());
1218 VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(), 1213 VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(),
1219 TestFallthrough::kThen); 1214 TestFallthrough::kThen);
1220 loop_body.Bind(builder()); 1215 loop_body.Bind(builder());
1221 } 1216 }
1222 VisitIterationBody(stmt, &loop_builder); 1217 VisitIterationBody(stmt, &loop_builder);
1223 if (stmt->next() != nullptr) { 1218 if (stmt->next() != nullptr) {
1224 builder()->SetStatementPosition(stmt->next()); 1219 builder()->SetStatementPosition(stmt->next());
1225 Visit(stmt->next()); 1220 Visit(stmt->next());
1226 } 1221 }
1227 loop_builder.JumpToHeader(); 1222 loop_builder.JumpToHeader(loop_depth_);
1228 loop_builder.EndLoop(); 1223 loop_builder.EndLoop();
1229 } 1224 }
1230 1225
1231 void BytecodeGenerator::VisitForInAssignment(Expression* expr, 1226 void BytecodeGenerator::VisitForInAssignment(Expression* expr,
1232 FeedbackVectorSlot slot) { 1227 FeedbackVectorSlot slot) {
1233 DCHECK(expr->IsValidReferenceExpression()); 1228 DCHECK(expr->IsValidReferenceExpression());
1234 1229
1235 // Evaluate assignment starting with the value to be stored in the 1230 // Evaluate assignment starting with the value to be stored in the
1236 // accumulator. 1231 // accumulator.
1237 Property* property = expr->AsProperty(); 1232 Property* property = expr->AsProperty();
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1338 builder()->ForInContinue(index, cache_length); 1333 builder()->ForInContinue(index, cache_length);
1339 loop_builder.BreakIfFalse(); 1334 loop_builder.BreakIfFalse();
1340 DCHECK(Register::AreContiguous(cache_type, cache_array)); 1335 DCHECK(Register::AreContiguous(cache_type, cache_array));
1341 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 1336 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
1342 builder()->ForInNext(receiver, index, cache_type, feedback_index(slot)); 1337 builder()->ForInNext(receiver, index, cache_type, feedback_index(slot));
1343 loop_builder.ContinueIfUndefined(); 1338 loop_builder.ContinueIfUndefined();
1344 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); 1339 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
1345 VisitIterationBody(stmt, &loop_builder); 1340 VisitIterationBody(stmt, &loop_builder);
1346 builder()->ForInStep(index); 1341 builder()->ForInStep(index);
1347 builder()->StoreAccumulatorInRegister(index); 1342 builder()->StoreAccumulatorInRegister(index);
1348 loop_builder.JumpToHeader(); 1343 loop_builder.JumpToHeader(loop_depth_);
1349 loop_builder.EndLoop(); 1344 loop_builder.EndLoop();
1350 builder()->Bind(&subject_null_label); 1345 builder()->Bind(&subject_null_label);
1351 builder()->Bind(&subject_undefined_label); 1346 builder()->Bind(&subject_undefined_label);
1352 } 1347 }
1353 1348
1354 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { 1349 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
1355 LoopBuilder loop_builder(builder()); 1350 LoopBuilder loop_builder(builder());
1356 1351
1357 builder()->SetExpressionAsStatementPosition(stmt->assign_iterator()); 1352 builder()->SetExpressionAsStatementPosition(stmt->assign_iterator());
1358 VisitForEffect(stmt->assign_iterator()); 1353 VisitForEffect(stmt->assign_iterator());
1359 1354
1360 VisitIterationHeader(stmt, &loop_builder); 1355 VisitIterationHeader(stmt, &loop_builder);
1361 builder()->SetExpressionAsStatementPosition(stmt->next_result()); 1356 builder()->SetExpressionAsStatementPosition(stmt->next_result());
1362 VisitForEffect(stmt->next_result()); 1357 VisitForEffect(stmt->next_result());
1363 VisitForAccumulatorValue(stmt->result_done()); 1358 VisitForAccumulatorValue(stmt->result_done());
1364 loop_builder.BreakIfTrue(); 1359 loop_builder.BreakIfTrue();
1365 1360
1366 VisitForEffect(stmt->assign_each()); 1361 VisitForEffect(stmt->assign_each());
1367 VisitIterationBody(stmt, &loop_builder); 1362 VisitIterationBody(stmt, &loop_builder);
1368 loop_builder.JumpToHeader(); 1363 loop_builder.JumpToHeader(loop_depth_);
1369 loop_builder.EndLoop(); 1364 loop_builder.EndLoop();
1370 } 1365 }
1371 1366
1372 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1367 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1373 TryCatchBuilder try_control_builder(builder(), stmt->catch_prediction()); 1368 TryCatchBuilder try_control_builder(builder(), stmt->catch_prediction());
1374 Register no_reg; 1369 Register no_reg;
1375 1370
1376 // Preserve the context in a dedicated register, so that it can be restored 1371 // Preserve the context in a dedicated register, so that it can be restored
1377 // when the handler is entered by the stack-unwinding machinery. 1372 // when the handler is entered by the stack-unwinding machinery.
1378 // TODO(mstarzinger): Be smarter about register allocation. 1373 // TODO(mstarzinger): Be smarter about register allocation.
(...skipping 2074 matching lines...) Expand 10 before | Expand all | Expand 10 after
3453 return execution_context()->scope()->language_mode(); 3448 return execution_context()->scope()->language_mode();
3454 } 3449 }
3455 3450
3456 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 3451 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
3457 return TypeFeedbackVector::GetIndex(slot); 3452 return TypeFeedbackVector::GetIndex(slot);
3458 } 3453 }
3459 3454
3460 } // namespace interpreter 3455 } // namespace interpreter
3461 } // namespace internal 3456 } // namespace internal
3462 } // namespace v8 3457 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698