Index: src/interpreter/bytecode-generator.cc |
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc |
index 73eee32fcb5aa7b66458639ab91fc363721c0b29..268b9fd79a1282e64e661dfc28222b309fcc646d 100644 |
--- a/src/interpreter/bytecode-generator.cc |
+++ b/src/interpreter/bytecode-generator.cc |
@@ -214,11 +214,12 @@ class BytecodeGenerator::ExpressionResultScope { |
// VisitForRegisterValue allocates register in outer context. |
return allocator_.NewRegister(); |
} else { |
- // We need this when allocating registers due to an Assignment hazard. |
- // 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. |
- return allocator_.AllocateNewRegister(); |
+ // If it is required to allocate a register other than current or outer |
+ // scopes, allocate a new temporary register. It might be expensive to |
+ // walk the full context chain and compute the list of consecutive |
+ // reservations in the innerscopes. |
+ UNIMPLEMENTED(); |
+ return Register(-1); |
} |
} |
@@ -312,120 +313,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 +322,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 +594,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 effect_results_scope(this); |
ZoneList<CaseClause*>* clauses = stmt->cases(); |
SwitchBuilder switch_builder(builder(), clauses->length()); |
ControlScopeForBreakable scope(this, stmt, &switch_builder); |
@@ -1281,16 +1170,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 +1247,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 +1254,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 +1854,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 +1862,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()); |