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

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

Powered by Google App Engine
This is Rietveld 408576698