Index: src/interpreter/bytecode-generator.h |
diff --git a/src/interpreter/bytecode-generator.h b/src/interpreter/bytecode-generator.h |
index 7284cfe9e18a41ae7454af1333872dcc7f59a922..be1bfe2760ad627b1989b50b825a1e4521645e59 100644 |
--- a/src/interpreter/bytecode-generator.h |
+++ b/src/interpreter/bytecode-generator.h |
@@ -13,10 +13,9 @@ namespace v8 { |
namespace internal { |
namespace interpreter { |
-class BytecodeGenerator : public AstVisitor { |
+class BytecodeGenerator final : public AstVisitor { |
public: |
BytecodeGenerator(Isolate* isolate, Zone* zone); |
- virtual ~BytecodeGenerator(); |
Handle<BytecodeArray> MakeBytecode(CompilationInfo* info); |
@@ -36,6 +35,37 @@ class BytecodeGenerator : public AstVisitor { |
class EffectResultScope; |
class AccumulatorResultScope; |
class RegisterResultScope; |
+ class AssignmentHazardScope; |
+ |
+ // Helper class that aliases locals and parameters when assignment |
+ // hazards occur in binary expressions. For y = x + (x = 1) has an |
+ // assignment hazard because the lhs evaluates to the register |
+ // holding x and the rhs (x = 1) potentially updates x. When this |
+ // hazard is detected, the rhs uses a temporary to hold the newer |
+ // value of x while preserving the lhs for the binary expresion |
+ // evaluation. The newer value is spilled to x at the end of the |
+ // binary expression evaluation. |
+ class AssignmentHazardHelper final { |
+ public: |
+ explicit AssignmentHazardHelper(BytecodeGenerator* generator); |
+ MUST_USE_RESULT Register GetRegisterForLoad(Register reg); |
+ MUST_USE_RESULT Register GetRegisterForStore(Register reg); |
+ |
+ private: |
+ friend class AssignmentHazardScope; |
+ |
+ void EnterScope(); |
+ void LeaveScope(); |
+ void RestoreAliasedLocalsAndParameters(); |
+ |
+ BytecodeGenerator* generator_; |
+ ZoneMap<int, int> alias_mappings_; |
+ ZoneSet<int> aliased_locals_and_parameters_; |
+ ExpressionResultScope* execution_result_; |
+ int scope_depth_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AssignmentHazardHelper); |
+ }; |
void MakeBytecodeBody(); |
Register NextContextRegister() const; |
@@ -54,6 +84,9 @@ class BytecodeGenerator : public AstVisitor { |
void VisitNot(UnaryOperation* expr); |
void VisitDelete(UnaryOperation* expr); |
+ // Used by flow control routines to evaluate loop condition. |
+ void VisitCondition(Expression* expr); |
+ |
// Helper visitors which perform common operations. |
Register VisitArguments(ZoneList<Expression*>* arguments); |
@@ -84,17 +117,12 @@ class BytecodeGenerator : public AstVisitor { |
Register value_out); |
void VisitForInAssignment(Expression* expr, FeedbackVectorSlot slot); |
- |
// Visitors for obtaining expression result in the accumulator, in a |
// register, or just getting the effect. |
void VisitForAccumulatorValue(Expression* expression); |
MUST_USE_RESULT Register VisitForRegisterValue(Expression* expression); |
void VisitForEffect(Expression* node); |
- // Methods marking the start and end of binary expressions. |
- void PrepareForBinaryExpression(); |
- void CompleteBinaryExpression(); |
- |
// Methods for tracking and remapping register. |
void RecordStoreToRegister(Register reg); |
Register LoadFromAliasedRegister(Register reg); |
@@ -121,6 +149,9 @@ class BytecodeGenerator : public AstVisitor { |
execution_result_ = execution_result; |
} |
ExpressionResultScope* execution_result() const { return execution_result_; } |
+ inline AssignmentHazardHelper* assignment_hazard_helper() { |
+ return &assignment_hazard_helper_; |
+ } |
ZoneVector<Handle<Object>>* globals() { return &globals_; } |
inline LanguageMode language_mode() const; |
@@ -136,9 +167,7 @@ class BytecodeGenerator : public AstVisitor { |
ControlScope* execution_control_; |
ContextScope* execution_context_; |
ExpressionResultScope* execution_result_; |
- |
- int binary_expression_depth_; |
- ZoneSet<int> binary_expression_hazard_set_; |
+ AssignmentHazardHelper assignment_hazard_helper_; |
}; |
} // namespace interpreter |