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

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

Issue 1412683011: [Interpreter] Enable assignments in expressions. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Sync test bytecode sequences to avoid unnecessary Ldar/Star instructions. Created 5 years, 1 month 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/compiler.h" 7 #include "src/compiler.h"
8 #include "src/interpreter/control-flow-builders.h" 8 #include "src/interpreter/control-flow-builders.h"
9 #include "src/objects.h" 9 #include "src/objects.h"
10 #include "src/parser.h" 10 #include "src/parser.h"
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 set_result_identified(); 290 set_result_identified();
291 } 291 }
292 292
293 Register ResultRegister() const { return result_register_; } 293 Register ResultRegister() const { return result_register_; }
294 294
295 private: 295 private:
296 Register result_register_; 296 Register result_register_;
297 }; 297 };
298 298
299 299
300 BytecodeGenerator::AssignmentHazardHelper::AssignmentHazardHelper(
301 BytecodeGenerator* generator)
302 : generator_(generator),
303 alias_mappings_(generator->zone()),
304 aliased_locals_and_parameters_(generator->zone()),
305 execution_result_(nullptr),
306 scope_depth_(0) {}
307
308
309 void BytecodeGenerator::AssignmentHazardHelper::EnterScope() {
310 DCHECK_GE(scope_depth_, 0);
311 if (scope_depth_++ == 0) {
312 execution_result_ = generator_->execution_result();
313 }
314 }
315
316
317 void BytecodeGenerator::AssignmentHazardHelper::LeaveScope() {
318 DCHECK_GT(scope_depth_, 0);
319 if (--scope_depth_ == 0) {
320 DCHECK_EQ(execution_result_, generator_->execution_result());
321 RestoreAliasedLocalsAndParameters();
322 }
323 }
324
325
326 // Returns a register that a load instruction should use when
327 // loading from |reg|. This allows an alias for a modified version
328 // of |reg| to be used within a hazard regions.
329 MUST_USE_RESULT Register
330 BytecodeGenerator::AssignmentHazardHelper::GetRegisterForLoad(Register reg) {
331 if (scope_depth_ == 0) {
332 return reg;
333 } else {
334 // A load from |reg| is to be issued. The register is placed in
335 // the mappings table initially mapping to itself. Future stores
336 // will update the mapping with temporaries thus preserving the
337 // original register's value.
338 //
339 // NB This insert only updates the table if no mapping exists
340 // already (std::map::insert semantics).
341 auto insert_result =
342 alias_mappings_.insert(std::make_pair(reg.index(), reg.index()));
343 auto mapping = insert_result.first;
344 // Return the current alias for reg.
345 return Register(mapping->second);
346 }
347 }
348
349
350 // Returns a register that a store instruction should use when
351 // loading from |reg|. This allows an alias for a modified version
352 // of |reg| to be used within hazard regions.
353 MUST_USE_RESULT Register
354 BytecodeGenerator::AssignmentHazardHelper::GetRegisterForStore(Register reg) {
355 if (scope_depth_ == 0 ||
356 alias_mappings_.find(reg.index()) == alias_mappings_.end()) {
357 // If not in a hazard region or a load for this register has not
358 // occurred no mapping is necessary.
359 return reg;
360 } else {
361 // Storing to a register with 1 or more loads issued. The
362 // register is mapped to a temporary alias so we don't overwrite
363 // the lhs value, e.g. y = x + (x = 1); has a register for x on
364 // the lhs and needs a new register x' for the upcoming store on
365 // the rhs as the original x is an input to the add operation.
366 Register alias = execution_result_->NewRegister();
367 alias_mappings_[reg.index()] = alias.index();
368 if (generator_->builder()->RegisterIsParameterOrLocal(reg)) {
369 // Keep track of registers that need to be restored on exit
370 // from the assignment hazard region.
371 aliased_locals_and_parameters_.insert(reg.index());
372 }
373 return alias;
374 }
375 }
376
377
378 void BytecodeGenerator::AssignmentHazardHelper::
379 RestoreAliasedLocalsAndParameters() {
380 DCHECK(scope_depth_ == 0);
381 // Move temporary registers holding values for locals and
382 // parameters back into their local and parameter registers.
383 for (auto reg = aliased_locals_and_parameters_.begin();
384 reg != aliased_locals_and_parameters_.end(); reg++) {
385 auto mapping = alias_mappings_.find(*reg);
386 if (mapping != alias_mappings_.end()) {
387 generator_->builder()->MoveRegister(Register(mapping->second),
388 Register(*reg));
389 }
390 }
391 alias_mappings_.clear();
392 aliased_locals_and_parameters_.clear();
393 }
394
395
396 class BytecodeGenerator::AssignmentHazardScope final {
397 public:
398 explicit AssignmentHazardScope(BytecodeGenerator* generator)
399 : generator_(generator) {
400 generator_->assignment_hazard_helper()->EnterScope();
401 }
402
403 ~AssignmentHazardScope() {
404 generator_->assignment_hazard_helper()->LeaveScope();
405 }
406
407 private:
408 BytecodeGenerator* generator_;
409
410 DISALLOW_COPY_AND_ASSIGN(AssignmentHazardScope);
411 };
412
413
300 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone) 414 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone)
301 : isolate_(isolate), 415 : isolate_(isolate),
302 zone_(zone), 416 zone_(zone),
303 builder_(isolate, zone), 417 builder_(isolate, zone),
304 info_(nullptr), 418 info_(nullptr),
305 scope_(nullptr), 419 scope_(nullptr),
306 globals_(0, zone), 420 globals_(0, zone),
307 execution_control_(nullptr), 421 execution_control_(nullptr),
308 execution_context_(nullptr), 422 execution_context_(nullptr),
309 execution_result_(nullptr), 423 execution_result_(nullptr),
310 binary_expression_depth_(0), 424 assignment_hazard_helper_(this) {
311 binary_expression_hazard_set_(zone) {
312 InitializeAstVisitor(isolate); 425 InitializeAstVisitor(isolate);
313 } 426 }
314 427
315 428
316 BytecodeGenerator::~BytecodeGenerator() {}
317
318
319 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) { 429 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) {
320 set_info(info); 430 set_info(info);
321 set_scope(info->scope()); 431 set_scope(info->scope());
322 432
323 // Initialize the incoming context. 433 // Initialize the incoming context.
324 ContextScope incoming_context(this, scope(), false); 434 ContextScope incoming_context(this, scope(), false);
325 435
326 builder()->set_parameter_count(info->num_parameters_including_this()); 436 builder()->set_parameter_count(info->num_parameters_including_this());
327 builder()->set_locals_count(scope()->num_stack_slots()); 437 builder()->set_locals_count(scope()->num_stack_slots());
328 builder()->set_context_count(scope()->MaxNestedContextChainLength()); 438 builder()->set_context_count(scope()->MaxNestedContextChainLength());
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 builder()->LoadLiteral(Smi::FromInt(encoded_flags)); 609 builder()->LoadLiteral(Smi::FromInt(encoded_flags));
500 builder()->StoreAccumulatorInRegister(flags); 610 builder()->StoreAccumulatorInRegister(flags);
501 DCHECK(flags.index() == pairs.index() + 1); 611 DCHECK(flags.index() == pairs.index() + 1);
502 612
503 builder()->CallRuntime(Runtime::kDeclareGlobals, pairs, 2); 613 builder()->CallRuntime(Runtime::kDeclareGlobals, pairs, 2);
504 globals()->clear(); 614 globals()->clear();
505 } 615 }
506 616
507 617
508 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 618 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
509 // TODO(rmcilroy): Replace this with a StatementResultScope when it exists. 619 EffectResultScope statement_result_scope(this);
510 EffectResultScope effect_scope(this);
511 VisitForEffect(stmt->expression()); 620 VisitForEffect(stmt->expression());
512 } 621 }
513 622
514 623
515 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 624 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
516 } 625 }
517 626
518 627
519 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) { 628 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
520 BytecodeLabel else_label, end_label; 629 BytecodeLabel else_label, end_label;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 execution_control()->Continue(stmt->target()); 661 execution_control()->Continue(stmt->target());
553 } 662 }
554 663
555 664
556 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 665 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
557 execution_control()->Break(stmt->target()); 666 execution_control()->Break(stmt->target());
558 } 667 }
559 668
560 669
561 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 670 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
562 EffectResultScope effect_scope(this); 671 EffectResultScope statement_result_scope(this);
563 VisitForAccumulatorValue(stmt->expression()); 672 VisitForAccumulatorValue(stmt->expression());
564 builder()->Return(); 673 builder()->Return();
565 } 674 }
566 675
567 676
568 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) { 677 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) {
569 UNIMPLEMENTED(); 678 UNIMPLEMENTED();
570 } 679 }
571 680
572 681
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { 730 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) {
622 // Handled entirely in VisitSwitchStatement. 731 // Handled entirely in VisitSwitchStatement.
623 UNREACHABLE(); 732 UNREACHABLE();
624 } 733 }
625 734
626 735
627 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 736 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
628 LoopBuilder loop_builder(builder()); 737 LoopBuilder loop_builder(builder());
629 ControlScopeForIteration execution_control(this, stmt, &loop_builder); 738 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
630 BytecodeLabel body_label, condition_label, done_label; 739 BytecodeLabel body_label, condition_label, done_label;
631
632 if (stmt->cond()->ToBooleanIsFalse()) { 740 if (stmt->cond()->ToBooleanIsFalse()) {
633 Visit(stmt->body()); 741 Visit(stmt->body());
634 // Bind condition_label and done_label for processing continue and break. 742 // Bind condition_label and done_label for processing continue and break.
635 builder()->Bind(&condition_label); 743 builder()->Bind(&condition_label);
636 builder()->Bind(&done_label); 744 builder()->Bind(&done_label);
637 } else { 745 } else {
638 builder()->Bind(&body_label); 746 builder()->Bind(&body_label);
639 Visit(stmt->body()); 747 Visit(stmt->body());
640 748
641 builder()->Bind(&condition_label); 749 builder()->Bind(&condition_label);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 break; 865 break;
758 } 866 }
759 case NAMED_SUPER_PROPERTY: 867 case NAMED_SUPER_PROPERTY:
760 case KEYED_SUPER_PROPERTY: 868 case KEYED_SUPER_PROPERTY:
761 UNIMPLEMENTED(); 869 UNIMPLEMENTED();
762 } 870 }
763 } 871 }
764 872
765 873
766 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { 874 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
767 // TODO(oth): For now we need a parent scope for paths that end up 875 EffectResultScope statement_result_scope(this);
768 // in VisitLiteral which can allocate in the parent scope. A future
769 // CL in preparation will add a StatementResultScope that will
770 // remove the need for this EffectResultScope.
771 EffectResultScope result_scope(this);
772 876
773 if (stmt->subject()->IsNullLiteral() || 877 if (stmt->subject()->IsNullLiteral() ||
774 stmt->subject()->IsUndefinedLiteral(isolate())) { 878 stmt->subject()->IsUndefinedLiteral(isolate())) {
775 // ForIn generates lots of code, skip if it wouldn't produce any effects. 879 // ForIn generates lots of code, skip if it wouldn't produce any effects.
776 return; 880 return;
777 } 881 }
778 882
779 LoopBuilder loop_builder(builder()); 883 LoopBuilder loop_builder(builder());
780 ControlScopeForIteration control_scope(this, stmt, &loop_builder); 884 ControlScopeForIteration control_scope(this, stmt, &loop_builder);
781 885
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot()); 1295 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot());
1192 } 1296 }
1193 1297
1194 1298
1195 void BytecodeGenerator::VisitVariableLoad(Variable* variable, 1299 void BytecodeGenerator::VisitVariableLoad(Variable* variable,
1196 FeedbackVectorSlot slot, 1300 FeedbackVectorSlot slot,
1197 TypeofMode typeof_mode) { 1301 TypeofMode typeof_mode) {
1198 switch (variable->location()) { 1302 switch (variable->location()) {
1199 case VariableLocation::LOCAL: { 1303 case VariableLocation::LOCAL: {
1200 Register source(Register(variable->index())); 1304 Register source(Register(variable->index()));
1305 source = assignment_hazard_helper()->GetRegisterForLoad(source);
1201 execution_result()->SetResultInRegister(source); 1306 execution_result()->SetResultInRegister(source);
1202 break; 1307 break;
1203 } 1308 }
1204 case VariableLocation::PARAMETER: { 1309 case VariableLocation::PARAMETER: {
1205 // The parameter indices are shifted by 1 (receiver is variable 1310 // The parameter indices are shifted by 1 (receiver is variable
1206 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 1311 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
1207 Register source = builder()->Parameter(variable->index() + 1); 1312 Register source = builder()->Parameter(variable->index() + 1);
1313 source = assignment_hazard_helper()->GetRegisterForLoad(source);
1208 execution_result()->SetResultInRegister(source); 1314 execution_result()->SetResultInRegister(source);
1209 break; 1315 break;
1210 } 1316 }
1211 case VariableLocation::GLOBAL: 1317 case VariableLocation::GLOBAL:
1212 case VariableLocation::UNALLOCATED: { 1318 case VariableLocation::UNALLOCATED: {
1213 size_t name_index = builder()->GetConstantPoolEntry(variable->name()); 1319 size_t name_index = builder()->GetConstantPoolEntry(variable->name());
1214 builder()->LoadGlobal(name_index, feedback_index(slot), language_mode(), 1320 builder()->LoadGlobal(name_index, feedback_index(slot), language_mode(),
1215 typeof_mode); 1321 typeof_mode);
1216 execution_result()->SetResultInAccumulator(); 1322 execution_result()->SetResultInAccumulator();
1217 break; 1323 break;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1262 return register_scope.ResultRegister(); 1368 return register_scope.ResultRegister();
1263 } 1369 }
1264 1370
1265 1371
1266 void BytecodeGenerator::VisitVariableAssignment(Variable* variable, 1372 void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
1267 FeedbackVectorSlot slot) { 1373 FeedbackVectorSlot slot) {
1268 switch (variable->location()) { 1374 switch (variable->location()) {
1269 case VariableLocation::LOCAL: { 1375 case VariableLocation::LOCAL: {
1270 // TODO(rmcilroy): support const mode initialization. 1376 // TODO(rmcilroy): support const mode initialization.
1271 Register destination(variable->index()); 1377 Register destination(variable->index());
1378 destination =
1379 assignment_hazard_helper()->GetRegisterForStore(destination);
1272 builder()->StoreAccumulatorInRegister(destination); 1380 builder()->StoreAccumulatorInRegister(destination);
1273 RecordStoreToRegister(destination);
1274 break; 1381 break;
1275 } 1382 }
1276 case VariableLocation::PARAMETER: { 1383 case VariableLocation::PARAMETER: {
1277 // The parameter indices are shifted by 1 (receiver is variable 1384 // The parameter indices are shifted by 1 (receiver is variable
1278 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 1385 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
1279 Register destination(builder()->Parameter(variable->index() + 1)); 1386 Register destination(builder()->Parameter(variable->index() + 1));
1387 destination =
1388 assignment_hazard_helper()->GetRegisterForStore(destination);
1389
1280 builder()->StoreAccumulatorInRegister(destination); 1390 builder()->StoreAccumulatorInRegister(destination);
1281 RecordStoreToRegister(destination);
1282 break; 1391 break;
1283 } 1392 }
1284 case VariableLocation::GLOBAL: 1393 case VariableLocation::GLOBAL:
1285 case VariableLocation::UNALLOCATED: { 1394 case VariableLocation::UNALLOCATED: {
1286 size_t name_index = builder()->GetConstantPoolEntry(variable->name()); 1395 size_t name_index = builder()->GetConstantPoolEntry(variable->name());
1287 builder()->StoreGlobal(name_index, feedback_index(slot), language_mode()); 1396 builder()->StoreGlobal(name_index, feedback_index(slot), language_mode());
1288 break; 1397 break;
1289 } 1398 }
1290 case VariableLocation::CONTEXT: { 1399 case VariableLocation::CONTEXT: {
1291 // TODO(rmcilroy): support const mode initialization. 1400 // TODO(rmcilroy): support const mode initialization.
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after
1819 VisitLogicalAndExpression(binop); 1928 VisitLogicalAndExpression(binop);
1820 break; 1929 break;
1821 default: 1930 default:
1822 VisitArithmeticExpression(binop); 1931 VisitArithmeticExpression(binop);
1823 break; 1932 break;
1824 } 1933 }
1825 } 1934 }
1826 1935
1827 1936
1828 void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) { 1937 void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) {
1829 // TODO(oth): Remove PrepareForBinaryExpression/CompleteBinaryExpression 1938 // The evaluation of binary comparison expressions has an assignment
1830 // once we have StatementScope that tracks hazardous loads/stores. 1939 // hazard because the lhs may be a variable that evaluates to a
1831 PrepareForBinaryExpression(); 1940 // local or parameter and the rhs may modify that, e.g. y = x + (x = 1)
1941 // To get a correct result the generator treats the inner assigment
1942 // as being made to a temporary x' that is spilled on exit of the
1943 // assignment hazard.
1944 AssignmentHazardScope assignment_hazard_scope(this);
1945
1832 Register lhs = VisitForRegisterValue(expr->left()); 1946 Register lhs = VisitForRegisterValue(expr->left());
1833 if (builder()->RegisterIsParameterOrLocal(lhs)) {
1834 // Result was returned in an existing local or parameter. See if
1835 // it needs to be moved to a temporary.
1836 // TODO(oth) LoadFromAliasedRegister call into VisitVariableLoad().
1837 lhs = LoadFromAliasedRegister(lhs);
1838 }
1839 VisitForAccumulatorValue(expr->right()); 1947 VisitForAccumulatorValue(expr->right());
1840 builder()->CompareOperation(expr->op(), lhs, language_mode_strength()); 1948 builder()->CompareOperation(expr->op(), lhs, language_mode_strength());
1841 CompleteBinaryExpression();
1842 execution_result()->SetResultInAccumulator(); 1949 execution_result()->SetResultInAccumulator();
1843 } 1950 }
1844 1951
1845 1952
1846 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { 1953 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
1847 // TODO(oth): Remove PrepareForBinaryExpression/CompleteBinaryExpression 1954 // The evaluation of binary arithmetic expressions has an assignment
1848 // once we have StatementScope that tracks hazardous loads/stores. 1955 // hazard because the lhs may be a variable that evaluates to a
1849 PrepareForBinaryExpression(); 1956 // local or parameter and the rhs may modify that, e.g. y = x + (x = 1)
1957 // To get a correct result the generator treats the inner assigment
1958 // as being made to a temporary x' that is spilled on exit of the
1959 // assignment hazard.
1960 AssignmentHazardScope assignment_hazard_scope(this);
1961
1850 Register lhs = VisitForRegisterValue(expr->left()); 1962 Register lhs = VisitForRegisterValue(expr->left());
1851 if (builder()->RegisterIsParameterOrLocal(lhs)) {
1852 // Result was returned in an existing local or parameter. See if
1853 // it needs to be moved to a temporary.
1854 // TODO(oth) LoadFromAliasedRegister call into VisitVariableLoad().
1855 lhs = LoadFromAliasedRegister(lhs);
1856 }
1857 VisitForAccumulatorValue(expr->right()); 1963 VisitForAccumulatorValue(expr->right());
1858 builder()->BinaryOperation(expr->op(), lhs, language_mode_strength()); 1964 builder()->BinaryOperation(expr->op(), lhs, language_mode_strength());
1859 CompleteBinaryExpression();
1860 execution_result()->SetResultInAccumulator(); 1965 execution_result()->SetResultInAccumulator();
1861 } 1966 }
1862 1967
1863 1968
1864 void BytecodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); } 1969 void BytecodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); }
1865 1970
1866 1971
1867 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) { 1972 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) {
1868 UNREACHABLE(); 1973 UNREACHABLE();
1869 } 1974 }
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
2067 // Pass a SMI sentinel and let the runtime look up the empty function. 2172 // Pass a SMI sentinel and let the runtime look up the empty function.
2068 builder()->LoadLiteral(Smi::FromInt(0)); 2173 builder()->LoadLiteral(Smi::FromInt(0));
2069 } else { 2174 } else {
2070 DCHECK(closure_scope->is_function_scope()); 2175 DCHECK(closure_scope->is_function_scope());
2071 builder()->LoadAccumulatorWithRegister(Register::function_closure()); 2176 builder()->LoadAccumulatorWithRegister(Register::function_closure());
2072 } 2177 }
2073 execution_result()->SetResultInAccumulator(); 2178 execution_result()->SetResultInAccumulator();
2074 } 2179 }
2075 2180
2076 2181
2077 void BytecodeGenerator::PrepareForBinaryExpression() {
2078 if (binary_expression_depth_++ == 0) {
2079 binary_expression_hazard_set_.clear();
2080 }
2081 }
2082
2083
2084 // Visits the expression |expr| and places the result in the accumulator. 2182 // Visits the expression |expr| and places the result in the accumulator.
2085 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) { 2183 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) {
2086 AccumulatorResultScope accumulator_scope(this); 2184 AccumulatorResultScope accumulator_scope(this);
2087 Visit(expr); 2185 Visit(expr);
2088 } 2186 }
2089 2187
2090 2188
2091 // Visits the expression |expr| and discards the result. 2189 // Visits the expression |expr| and discards the result.
2092 void BytecodeGenerator::VisitForEffect(Expression* expr) { 2190 void BytecodeGenerator::VisitForEffect(Expression* expr) {
2093 EffectResultScope effect_scope(this); 2191 EffectResultScope effect_scope(this);
2094 Visit(expr); 2192 Visit(expr);
2095 } 2193 }
2096 2194
2097 2195
2098 // Visits the expression |expr| and returns the register containing 2196 // Visits the expression |expr| and returns the register containing
2099 // the expression result. 2197 // the expression result.
2100 Register BytecodeGenerator::VisitForRegisterValue(Expression* expr) { 2198 Register BytecodeGenerator::VisitForRegisterValue(Expression* expr) {
2101 RegisterResultScope register_scope(this); 2199 RegisterResultScope register_scope(this);
2102 Visit(expr); 2200 Visit(expr);
2103 return register_scope.ResultRegister(); 2201 return register_scope.ResultRegister();
2104 } 2202 }
2105 2203
2106 2204
2107 Register BytecodeGenerator::LoadFromAliasedRegister(Register reg) {
2108 // TODO(oth): Follow on CL to load from re-map here.
2109 DCHECK(builder()->RegisterIsParameterOrLocal(reg));
2110 if (binary_expression_depth_ > 0) {
2111 binary_expression_hazard_set_.insert(reg.index());
2112 }
2113 return reg;
2114 }
2115
2116
2117 void BytecodeGenerator::RecordStoreToRegister(Register reg) {
2118 DCHECK(builder()->RegisterIsParameterOrLocal(reg));
2119 if (binary_expression_depth_ > 0) {
2120 // TODO(oth): a store to a register that's be loaded needs to be
2121 // remapped.
2122 DCHECK(binary_expression_hazard_set_.find(reg.index()) ==
2123 binary_expression_hazard_set_.end());
2124 }
2125 }
2126
2127
2128 void BytecodeGenerator::CompleteBinaryExpression() {
2129 DCHECK(binary_expression_depth_ > 0);
2130 binary_expression_depth_ -= 1;
2131 // TODO(oth): spill remapped registers into origins.
2132 // TODO(oth): make statement/top-level.
2133 }
2134
2135
2136 Register BytecodeGenerator::NextContextRegister() const { 2205 Register BytecodeGenerator::NextContextRegister() const {
2137 if (execution_context() == nullptr) { 2206 if (execution_context() == nullptr) {
2138 // Return the incoming function context for the outermost execution context. 2207 // Return the incoming function context for the outermost execution context.
2139 return Register::function_context(); 2208 return Register::function_context();
2140 } 2209 }
2141 Register previous = execution_context()->reg(); 2210 Register previous = execution_context()->reg();
2142 if (previous == Register::function_context()) { 2211 if (previous == Register::function_context()) {
2143 // If the previous context was the incoming function context, then the next 2212 // If the previous context was the incoming function context, then the next
2144 // context register is the first local context register. 2213 // context register is the first local context register.
2145 return builder_.first_context_register(); 2214 return builder_.first_context_register();
(...skipping 15 matching lines...) Expand all
2161 } 2230 }
2162 2231
2163 2232
2164 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 2233 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
2165 return info()->feedback_vector()->GetIndex(slot); 2234 return info()->feedback_vector()->GetIndex(slot);
2166 } 2235 }
2167 2236
2168 } // namespace interpreter 2237 } // namespace interpreter
2169 } // namespace internal 2238 } // namespace internal
2170 } // namespace v8 2239 } // 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