Chromium Code Reviews| Index: src/interpreter/bytecode-generator.cc |
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc |
| index 73eee32fcb5aa7b66458639ab91fc363721c0b29..e1a651ea544356a065feda48cab0433329cd6220 100644 |
| --- a/src/interpreter/bytecode-generator.cc |
| +++ b/src/interpreter/bytecode-generator.cc |
| @@ -214,10 +214,13 @@ class BytecodeGenerator::ExpressionResultScope { |
| // VisitForRegisterValue allocates register in outer context. |
| return allocator_.NewRegister(); |
| } else { |
| - // We need this when allocating registers due to an Assignment hazard. |
| + // Allocating a register other than the current or outer scope: |
| // It might be expensive to walk the full context chain and compute the |
| // list of consecutive reservations in the innerscopes. So allocates a |
| - // new unallocated temporary register. |
| + // new unallocated temporary register. We needed this in an implementation |
| + // of Assignment hazard. |
| + // TODO(mythria): Reevaluate this after we have the new assignment hazard |
| + // implementation. Remove this if not required. |
|
rmcilroy
2016/01/12 14:43:17
I'd rather just remove this now if it is no longer
mythria
2016/01/12 16:53:21
Done.
|
| return allocator_.AllocateNewRegister(); |
| } |
| } |
| @@ -312,120 +315,6 @@ class BytecodeGenerator::RegisterResultScope final |
| }; |
| -BytecodeGenerator::AssignmentHazardHelper::AssignmentHazardHelper( |
| - BytecodeGenerator* generator) |
| - : generator_(generator), |
| - alias_mappings_(generator->zone()), |
| - aliased_locals_and_parameters_(generator->zone()), |
| - execution_result_(nullptr), |
| - scope_depth_(0) {} |
| - |
| - |
| -void BytecodeGenerator::AssignmentHazardHelper::EnterScope() { |
| - DCHECK_GE(scope_depth_, 0); |
| - if (scope_depth_++ == 0) { |
| - execution_result_ = generator_->execution_result(); |
| - } |
| -} |
| - |
| - |
| -void BytecodeGenerator::AssignmentHazardHelper::LeaveScope() { |
| - DCHECK_GT(scope_depth_, 0); |
| - if (--scope_depth_ == 0) { |
| - DCHECK_EQ(execution_result_, generator_->execution_result()); |
| - RestoreAliasedLocalsAndParameters(); |
| - } |
| -} |
| - |
| - |
| -// Returns a register that a load instruction should use when |
| -// loading from |reg|. This allows an alias for a modified version |
| -// of |reg| to be used within a hazard regions. |
| -MUST_USE_RESULT Register |
| -BytecodeGenerator::AssignmentHazardHelper::GetRegisterForLoad(Register reg) { |
| - if (scope_depth_ == 0) { |
| - return reg; |
| - } else { |
| - // A load from |reg| is to be issued. The register is placed in |
| - // the mappings table initially mapping to itself. Future stores |
| - // will update the mapping with temporaries thus preserving the |
| - // original register's value. |
| - // |
| - // NB This insert only updates the table if no mapping exists |
| - // already (std::map::insert semantics). |
| - auto insert_result = |
| - alias_mappings_.insert(std::make_pair(reg.index(), reg.index())); |
| - auto mapping = insert_result.first; |
| - // Return the current alias for reg. |
| - return Register(mapping->second); |
| - } |
| -} |
| - |
| - |
| -// Returns a register that a store instruction should use when |
| -// loading from |reg|. This allows an alias for a modified version |
| -// of |reg| to be used within hazard regions. |
| -MUST_USE_RESULT Register |
| -BytecodeGenerator::AssignmentHazardHelper::GetRegisterForStore(Register reg) { |
| - if (scope_depth_ == 0 || |
| - alias_mappings_.find(reg.index()) == alias_mappings_.end()) { |
| - // If not in a hazard region or a load for this register has not |
| - // occurred no mapping is necessary. |
| - return reg; |
| - } else { |
| - // Storing to a register with 1 or more loads issued. The |
| - // register is mapped to a temporary alias so we don't overwrite |
| - // the lhs value, e.g. y = x + (x = 1); has a register for x on |
| - // the lhs and needs a new register x' for the upcoming store on |
| - // the rhs as the original x is an input to the add operation. |
| - Register alias = execution_result_->NewRegister(); |
| - alias_mappings_[reg.index()] = alias.index(); |
| - if (generator_->builder()->RegisterIsParameterOrLocal(reg)) { |
| - // Keep track of registers that need to be restored on exit |
| - // from the assignment hazard region. |
| - aliased_locals_and_parameters_.insert(reg.index()); |
| - } |
| - return alias; |
| - } |
| -} |
| - |
| - |
| -void BytecodeGenerator::AssignmentHazardHelper:: |
| - RestoreAliasedLocalsAndParameters() { |
| - DCHECK(scope_depth_ == 0); |
| - // Move temporary registers holding values for locals and |
| - // parameters back into their local and parameter registers. |
| - for (auto reg = aliased_locals_and_parameters_.begin(); |
| - reg != aliased_locals_and_parameters_.end(); reg++) { |
| - auto mapping = alias_mappings_.find(*reg); |
| - if (mapping != alias_mappings_.end()) { |
| - generator_->builder()->MoveRegister(Register(mapping->second), |
| - Register(*reg)); |
| - } |
| - } |
| - alias_mappings_.clear(); |
| - aliased_locals_and_parameters_.clear(); |
| -} |
| - |
| - |
| -class BytecodeGenerator::AssignmentHazardScope final { |
| - public: |
| - explicit AssignmentHazardScope(BytecodeGenerator* generator) |
| - : generator_(generator) { |
| - generator_->assignment_hazard_helper()->EnterScope(); |
| - } |
| - |
| - ~AssignmentHazardScope() { |
| - generator_->assignment_hazard_helper()->LeaveScope(); |
| - } |
| - |
| - private: |
| - BytecodeGenerator* generator_; |
| - |
| - DISALLOW_COPY_AND_ASSIGN(AssignmentHazardScope); |
| -}; |
| - |
| - |
| BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone) |
| : isolate_(isolate), |
| zone_(zone), |
| @@ -435,8 +324,7 @@ BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone) |
| globals_(0, zone), |
| execution_control_(nullptr), |
| execution_context_(nullptr), |
| - execution_result_(nullptr), |
| - assignment_hazard_helper_(this) { |
| + execution_result_(nullptr) { |
| InitializeAstVisitor(isolate); |
| } |
| @@ -708,6 +596,9 @@ void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) { |
| void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { |
| + // We need this scope because we visit for register values. We have to |
| + // maintain a execution result scope where registers can be allocated. |
| + EffectResultScope switch_result_scope(this); |
|
rmcilroy
2016/01/12 14:43:17
nit - effect_results_scope
mythria
2016/01/12 16:53:21
Done.
|
| ZoneList<CaseClause*>* clauses = stmt->cases(); |
| SwitchBuilder switch_builder(builder(), clauses->length()); |
| ControlScopeForBreakable scope(this, stmt, &switch_builder); |
| @@ -1281,16 +1172,16 @@ void BytecodeGenerator::VisitVariableLoad(Variable* variable, |
| switch (variable->location()) { |
| case VariableLocation::LOCAL: { |
| Register source(Register(variable->index())); |
| - source = assignment_hazard_helper()->GetRegisterForLoad(source); |
| - execution_result()->SetResultInRegister(source); |
| + builder()->LoadAccumulatorWithRegister(source); |
| + execution_result()->SetResultInAccumulator(); |
| break; |
| } |
| case VariableLocation::PARAMETER: { |
| // The parameter indices are shifted by 1 (receiver is variable |
| // index -1 but is parameter index 0 in BytecodeArrayBuilder). |
| Register source = builder()->Parameter(variable->index() + 1); |
| - source = assignment_hazard_helper()->GetRegisterForLoad(source); |
| - execution_result()->SetResultInRegister(source); |
| + builder()->LoadAccumulatorWithRegister(source); |
| + execution_result()->SetResultInAccumulator(); |
| break; |
| } |
| case VariableLocation::GLOBAL: |
| @@ -1358,8 +1249,6 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable, |
| case VariableLocation::LOCAL: { |
| // TODO(rmcilroy): support const mode initialization. |
| Register destination(variable->index()); |
| - destination = |
| - assignment_hazard_helper()->GetRegisterForStore(destination); |
| builder()->StoreAccumulatorInRegister(destination); |
| break; |
| } |
| @@ -1367,9 +1256,6 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable, |
| // The parameter indices are shifted by 1 (receiver is variable |
| // index -1 but is parameter index 0 in BytecodeArrayBuilder). |
| Register destination(builder()->Parameter(variable->index() + 1)); |
| - destination = |
| - assignment_hazard_helper()->GetRegisterForStore(destination); |
| - |
| builder()->StoreAccumulatorInRegister(destination); |
| break; |
| } |
| @@ -1970,14 +1856,6 @@ void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) { |
| void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
| - // The evaluation of binary comparison expressions has an assignment |
| - // hazard because the lhs may be a variable that evaluates to a |
| - // local or parameter and the rhs may modify that, e.g. y = x + (x = 1) |
| - // To get a correct result the generator treats the inner assigment |
| - // as being made to a temporary x' that is spilled on exit of the |
| - // assignment hazard. |
| - AssignmentHazardScope assignment_hazard_scope(this); |
| - |
| Register lhs = VisitForRegisterValue(expr->left()); |
| VisitForAccumulatorValue(expr->right()); |
| builder()->CompareOperation(expr->op(), lhs, language_mode_strength()); |
| @@ -1986,14 +1864,6 @@ void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
| void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { |
| - // The evaluation of binary arithmetic expressions has an assignment |
| - // hazard because the lhs may be a variable that evaluates to a |
| - // local or parameter and the rhs may modify that, e.g. y = x + (x = 1) |
| - // To get a correct result the generator treats the inner assigment |
| - // as being made to a temporary x' that is spilled on exit of the |
| - // assignment hazard. |
| - AssignmentHazardScope assignment_hazard_scope(this); |
| - |
| Register lhs = VisitForRegisterValue(expr->left()); |
| VisitForAccumulatorValue(expr->right()); |
| builder()->BinaryOperation(expr->op(), lhs, language_mode_strength()); |