Chromium Code Reviews| Index: src/hydrogen-instructions.h | 
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h | 
| index c9a4bf062d3a7c3c6b4c79d36d4abe4959c6d8e2..213e0c69524476b9475994f549f18d94efc660af 100644 | 
| --- a/src/hydrogen-instructions.h | 
| +++ b/src/hydrogen-instructions.h | 
| @@ -3447,8 +3447,21 @@ class HStoreGlobalGeneric: public HTemplateInstruction<3> { | 
| class HLoadContextSlot: public HUnaryOperation { | 
| public: | 
| - HLoadContextSlot(HValue* context , int slot_index) | 
| - : HUnaryOperation(context), slot_index_(slot_index) { | 
| + enum Mode { | 
| + // Perform a normal load of the context slot without checking its value. | 
| + kLoad, | 
| + // Load and check the value of the context slot. Deoptimize if it's the | 
| + // hole value. This is used for checking for loading of uninitialized | 
| + // harmony bindings where we deoptimize into full-codegen generated code | 
| + // which will subsequently throw a reference error. | 
| + kLoadCheck | 
| + }; | 
| + | 
| + HLoadContextSlot(HValue* context, Variable* var) | 
| + : HUnaryOperation(context), slot_index_(var->index()) { | 
| + ASSERT(var->IsContextSlot()); | 
| + mode_ = (var->mode() == LET || var->mode() == CONST_HARMONY) | 
| + ? kLoadCheck : kLoad; | 
| set_representation(Representation::Tagged()); | 
| SetFlag(kUseGVN); | 
| SetFlag(kDependsOnContextSlots); | 
| @@ -3456,6 +3469,10 @@ class HLoadContextSlot: public HUnaryOperation { | 
| int slot_index() const { return slot_index_; } | 
| + bool RequiresHoleCheck() { | 
| + return mode_ == kLoadCheck; | 
| + } | 
| + | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| } | 
| @@ -3472,13 +3489,35 @@ class HLoadContextSlot: public HUnaryOperation { | 
| private: | 
| int slot_index_; | 
| + Mode mode_; | 
| }; | 
| class HStoreContextSlot: public HTemplateInstruction<2> { | 
| public: | 
| - HStoreContextSlot(HValue* context, int slot_index, HValue* value) | 
| - : slot_index_(slot_index) { | 
| + enum Mode { | 
| + // Perform a normal store to the context slot without checking its previous | 
| + // value. | 
| + kAssign, | 
| + // Check the previous value of the context slot and deoptimize if it's the | 
| + // hole value. This is used for checking for assignments to uninitialized | 
| + // harmony bindings where we deoptimize into full-codegen generated code | 
| + // which will subsequently throw a reference error. | 
| + kAssignCheck | 
| + }; | 
| + | 
| + HStoreContextSlot(HValue* context, Variable* var, HValue* value) | 
| + : slot_index_(var->index()) { | 
| 
 
fschneider
2011/12/09 08:37:40
I'm not convinced that two constructors are better
 
Steven
2011/12/09 09:44:56
Agreed.
 
 | 
| + ASSERT(var->IsContextSlot()); | 
| + mode_ = (var->mode() == LET || var->mode() == CONST_HARMONY) | 
| + ? kAssignCheck : kAssign; | 
| + SetOperandAt(0, context); | 
| + SetOperandAt(1, value); | 
| + SetFlag(kChangesContextSlots); | 
| + } | 
| + | 
| + HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value) | 
| + : slot_index_(slot_index), mode_(mode) { | 
| SetOperandAt(0, context); | 
| SetOperandAt(1, value); | 
| SetFlag(kChangesContextSlots); | 
| @@ -3487,11 +3526,16 @@ class HStoreContextSlot: public HTemplateInstruction<2> { | 
| HValue* context() { return OperandAt(0); } | 
| HValue* value() { return OperandAt(1); } | 
| int slot_index() const { return slot_index_; } | 
| + Mode mode() const { return mode_; } | 
| bool NeedsWriteBarrier() { | 
| return StoringValueNeedsWriteBarrier(value()); | 
| } | 
| + bool RequiresHoleCheck() { | 
| + return mode_ == kAssignCheck; | 
| + } | 
| + | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| } | 
| @@ -3502,6 +3546,7 @@ class HStoreContextSlot: public HTemplateInstruction<2> { | 
| private: | 
| int slot_index_; | 
| + Mode mode_; | 
| }; |