| Index: src/hydrogen-instructions.h | 
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h | 
| index 1bd27cb68561205f3ea927756bc0695ec652439c..5831bbdc3e725fa26047b73ebdb79891a8d13f6e 100644 | 
| --- a/src/hydrogen-instructions.h | 
| +++ b/src/hydrogen-instructions.h | 
| @@ -1308,6 +1308,48 @@ class HValue: public ZoneObject { | 
| }; | 
|  | 
|  | 
| +#define DECLARE_INSTRUCTION_FACTORY_P0(I)                                      \ | 
| +  static I* New(Zone* zone, HValue* context) {                                 \ | 
| +    return new(zone) I();                                                      \ | 
| +} | 
| + | 
| +#define DECLARE_INSTRUCTION_FACTORY_P1(I, P1)                                  \ | 
| +  static I* New(Zone* zone, HValue* context, P1 p1) {                          \ | 
| +    return new(zone) I(p1);                                                    \ | 
| +  } | 
| + | 
| +#define DECLARE_INSTRUCTION_FACTORY_P2(I, P1, P2)                              \ | 
| +  static I* New(Zone* zone, HValue* context, P1 p1, P2 p2) {                   \ | 
| +    return new(zone) I(p1, p2);                                                \ | 
| +  } | 
| + | 
| +#define DECLARE_INSTRUCTION_FACTORY_P3(I, P1, P2, P3)                          \ | 
| +  static I* New(Zone* zone, HValue* context, P1 p1, P2 p2, P3 p3) {            \ | 
| +    return new(zone) I(p1, p2, p3);                                            \ | 
| +  } | 
| + | 
| +#define DECLARE_INSTRUCTION_FACTORY_P4(I, P1, P2, P3, P4)                      \ | 
| +  static I* New(Zone* zone,                                                    \ | 
| +                HValue* context,                                               \ | 
| +                P1 p1,                                                         \ | 
| +                P2 p2,                                                         \ | 
| +                P3 p3,                                                         \ | 
| +                P4 p4) {                                                       \ | 
| +    return new(zone) I(p1, p2, p3, p4);                                        \ | 
| +  } | 
| + | 
| +#define DECLARE_INSTRUCTION_FACTORY_P5(I, P1, P2, P3, P4, P5)                  \ | 
| +  static I* New(Zone* zone,                                                    \ | 
| +                HValue* context,                                               \ | 
| +                P1 p1,                                                         \ | 
| +                P2 p2,                                                         \ | 
| +                P3 p3,                                                         \ | 
| +                P4 p4,                                                         \ | 
| +                P5 p5) {                                                       \ | 
| +    return new(zone) I(p1, p2, p3, p4, p5);                                    \ | 
| +  } | 
| + | 
| + | 
| class HInstruction: public HValue { | 
| public: | 
| HInstruction* next() const { return next_; } | 
| @@ -1520,7 +1562,7 @@ class HNumericConstraint : public HTemplateInstruction<2> { | 
|  | 
| class HDeoptimize: public HTemplateInstruction<0> { | 
| public: | 
| -  explicit HDeoptimize(Deoptimizer::BailoutType type) : type_(type) {} | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HDeoptimize, Deoptimizer::BailoutType); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::None(); | 
| @@ -1531,6 +1573,8 @@ class HDeoptimize: public HTemplateInstruction<0> { | 
| DECLARE_CONCRETE_INSTRUCTION(Deoptimize) | 
|  | 
| private: | 
| +  explicit HDeoptimize(Deoptimizer::BailoutType type) : type_(type) {} | 
| + | 
| Deoptimizer::BailoutType type_; | 
| }; | 
|  | 
| @@ -1631,12 +1675,44 @@ class HCompareMap: public HUnaryControlInstruction { | 
| }; | 
|  | 
|  | 
| +class HContext: public HTemplateInstruction<0> { | 
| + public: | 
| +  static HContext* New(Zone* zone) { | 
| +    return new(zone) HContext(); | 
| +  } | 
| + | 
| +  virtual Representation RequiredInputRepresentation(int index) { | 
| +    return Representation::None(); | 
| +  } | 
| + | 
| +  DECLARE_CONCRETE_INSTRUCTION(Context) | 
| + | 
| + protected: | 
| +  virtual bool DataEquals(HValue* other) { return true; } | 
| + | 
| + private: | 
| +  HContext() { | 
| +    set_representation(Representation::Tagged()); | 
| +    SetFlag(kUseGVN); | 
| +  } | 
| + | 
| +  virtual bool IsDeletable() const { return true; } | 
| +}; | 
| + | 
| + | 
| class HReturn: public HTemplateControlInstruction<0, 3> { | 
| public: | 
| -  HReturn(HValue* value, HValue* context, HValue* parameter_count) { | 
| -    SetOperandAt(0, value); | 
| -    SetOperandAt(1, context); | 
| -    SetOperandAt(2, parameter_count); | 
| +  static HInstruction* New(Zone* zone, | 
| +                           HValue* context, | 
| +                           HValue* value, | 
| +                           HValue* parameter_count) { | 
| +    return new(zone) HReturn(value, context, parameter_count); | 
| +  } | 
| + | 
| +  static HInstruction* New(Zone* zone, | 
| +                           HValue* context, | 
| +                           HValue* value) { | 
| +    return new(zone) HReturn(value, context, 0); | 
| } | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| @@ -1650,6 +1726,13 @@ class HReturn: public HTemplateControlInstruction<0, 3> { | 
| HValue* parameter_count() { return OperandAt(2); } | 
|  | 
| DECLARE_CONCRETE_INSTRUCTION(Return) | 
| + | 
| + private: | 
| +  HReturn(HValue* value, HValue* context, HValue* parameter_count) { | 
| +    SetOperandAt(0, value); | 
| +    SetOperandAt(1, context); | 
| +    SetOperandAt(2, parameter_count); | 
| +  } | 
| }; | 
|  | 
|  | 
| @@ -1681,10 +1764,10 @@ class HUnaryOperation: public HTemplateInstruction<1> { | 
|  | 
| class HThrow: public HTemplateInstruction<2> { | 
| public: | 
| -  HThrow(HValue* context, HValue* value) { | 
| -    SetOperandAt(0, context); | 
| -    SetOperandAt(1, value); | 
| -    SetAllSideEffects(); | 
| +  static HThrow* New(Zone* zone, | 
| +                     HValue* context, | 
| +                     HValue* value) { | 
| +    return new(zone) HThrow(context, value); | 
| } | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| @@ -1695,27 +1778,34 @@ class HThrow: public HTemplateInstruction<2> { | 
| HValue* value() { return OperandAt(1); } | 
|  | 
| DECLARE_CONCRETE_INSTRUCTION(Throw) | 
| + | 
| + private: | 
| +  HThrow(HValue* context, HValue* value) { | 
| +    SetOperandAt(0, context); | 
| +    SetOperandAt(1, value); | 
| +    SetAllSideEffects(); | 
| +  } | 
| }; | 
|  | 
|  | 
| class HUseConst: public HUnaryOperation { | 
| public: | 
| -  explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { } | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HUseConst, HValue*); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::None(); | 
| } | 
|  | 
| DECLARE_CONCRETE_INSTRUCTION(UseConst) | 
| + | 
| + private: | 
| +    explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { } | 
| }; | 
|  | 
|  | 
| class HForceRepresentation: public HTemplateInstruction<1> { | 
| public: | 
| -  HForceRepresentation(HValue* value, Representation required_representation) { | 
| -    SetOperandAt(0, value); | 
| -    set_representation(required_representation); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P2(HForceRepresentation, HValue*, Representation); | 
|  | 
| HValue* value() { return OperandAt(0); } | 
|  | 
| @@ -1728,6 +1818,12 @@ class HForceRepresentation: public HTemplateInstruction<1> { | 
| virtual void PrintDataTo(StringStream* stream); | 
|  | 
| DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation) | 
| + | 
| + private: | 
| +  HForceRepresentation(HValue* value, Representation required_representation) { | 
| +    SetOperandAt(0, value); | 
| +    set_representation(required_representation); | 
| +  } | 
| }; | 
|  | 
|  | 
| @@ -1789,12 +1885,7 @@ class HChange: public HUnaryOperation { | 
|  | 
| class HClampToUint8: public HUnaryOperation { | 
| public: | 
| -  explicit HClampToUint8(HValue* value) | 
| -      : HUnaryOperation(value) { | 
| -    set_representation(Representation::Integer32()); | 
| -    SetFlag(kAllowUndefinedAsNaN); | 
| -    SetFlag(kUseGVN); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HClampToUint8, HValue*); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::None(); | 
| @@ -1806,6 +1897,13 @@ class HClampToUint8: public HUnaryOperation { | 
| virtual bool DataEquals(HValue* other) { return true; } | 
|  | 
| private: | 
| +  explicit HClampToUint8(HValue* value) | 
| +      : HUnaryOperation(value) { | 
| +    set_representation(Representation::Integer32()); | 
| +    SetFlag(kAllowUndefinedAsNaN); | 
| +    SetFlag(kUseGVN); | 
| +  } | 
| + | 
| virtual bool IsDeletable() const { return true; } | 
| }; | 
|  | 
| @@ -1962,10 +2060,7 @@ class HStackCheck: public HTemplateInstruction<1> { | 
| kBackwardsBranch | 
| }; | 
|  | 
| -  HStackCheck(HValue* context, Type type) : type_(type) { | 
| -    SetOperandAt(0, context); | 
| -    SetGVNFlag(kChangesNewSpacePromotion); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P2(HStackCheck, HValue*, Type); | 
|  | 
| HValue* context() { return OperandAt(0); } | 
|  | 
| @@ -1987,6 +2082,11 @@ class HStackCheck: public HTemplateInstruction<1> { | 
| DECLARE_CONCRETE_INSTRUCTION(StackCheck) | 
|  | 
| private: | 
| +  HStackCheck(HValue* context, Type type) : type_(type) { | 
| +    SetOperandAt(0, context); | 
| +    SetGVNFlag(kChangesNewSpacePromotion); | 
| +  } | 
| + | 
| Type type_; | 
| }; | 
|  | 
| @@ -2005,23 +2105,18 @@ class HArgumentsObject; | 
|  | 
| class HEnterInlined: public HTemplateInstruction<0> { | 
| public: | 
| -  HEnterInlined(Handle<JSFunction> closure, | 
| -                int arguments_count, | 
| -                FunctionLiteral* function, | 
| -                InliningKind inlining_kind, | 
| -                Variable* arguments_var, | 
| -                HArgumentsObject* arguments_object, | 
| -                bool undefined_receiver, | 
| -                Zone* zone) | 
| -      : closure_(closure), | 
| -        arguments_count_(arguments_count), | 
| -        arguments_pushed_(false), | 
| -        function_(function), | 
| -        inlining_kind_(inlining_kind), | 
| -        arguments_var_(arguments_var), | 
| -        arguments_object_(arguments_object), | 
| -        undefined_receiver_(undefined_receiver), | 
| -        return_targets_(2, zone) { | 
| +  static HEnterInlined* New(Zone* zone, | 
| +                            HValue* context, | 
| +                            Handle<JSFunction> closure, | 
| +                            int arguments_count, | 
| +                            FunctionLiteral* function, | 
| +                            InliningKind inlining_kind, | 
| +                            Variable* arguments_var, | 
| +                            HArgumentsObject* arguments_object, | 
| +                            bool undefined_receiver) { | 
| +    return new(zone) HEnterInlined(closure, arguments_count, function, | 
| +                                   inlining_kind, arguments_var, | 
| +                                   arguments_object, undefined_receiver, zone); | 
| } | 
|  | 
| void RegisterReturnTarget(HBasicBlock* return_target, Zone* zone); | 
| @@ -2047,6 +2142,25 @@ class HEnterInlined: public HTemplateInstruction<0> { | 
| DECLARE_CONCRETE_INSTRUCTION(EnterInlined) | 
|  | 
| private: | 
| +  HEnterInlined(Handle<JSFunction> closure, | 
| +                int arguments_count, | 
| +                FunctionLiteral* function, | 
| +                InliningKind inlining_kind, | 
| +                Variable* arguments_var, | 
| +                HArgumentsObject* arguments_object, | 
| +                bool undefined_receiver, | 
| +                Zone* zone) | 
| +      : closure_(closure), | 
| +        arguments_count_(arguments_count), | 
| +        arguments_pushed_(false), | 
| +        function_(function), | 
| +        inlining_kind_(inlining_kind), | 
| +        arguments_var_(arguments_var), | 
| +        arguments_object_(arguments_object), | 
| +        undefined_receiver_(undefined_receiver), | 
| +        return_targets_(2, zone) { | 
| +  } | 
| + | 
| Handle<JSFunction> closure_; | 
| int arguments_count_; | 
| bool arguments_pushed_; | 
| @@ -2073,9 +2187,7 @@ class HLeaveInlined: public HTemplateInstruction<0> { | 
|  | 
| class HPushArgument: public HUnaryOperation { | 
| public: | 
| -  explicit HPushArgument(HValue* value) : HUnaryOperation(value) { | 
| -    set_representation(Representation::Tagged()); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HPushArgument, HValue*); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| @@ -2084,6 +2196,11 @@ class HPushArgument: public HUnaryOperation { | 
| HValue* argument() { return OperandAt(0); } | 
|  | 
| DECLARE_CONCRETE_INSTRUCTION(PushArgument) | 
| + | 
| + private: | 
| +  explicit HPushArgument(HValue* value) : HUnaryOperation(value) { | 
| +    set_representation(Representation::Tagged()); | 
| +  } | 
| }; | 
|  | 
|  | 
| @@ -2108,44 +2225,25 @@ class HThisFunction: public HTemplateInstruction<0> { | 
| }; | 
|  | 
|  | 
| -class HContext: public HTemplateInstruction<0> { | 
| +class HOuterContext: public HUnaryOperation { | 
| public: | 
| -  HContext() { | 
| -    set_representation(Representation::Tagged()); | 
| -    SetFlag(kUseGVN); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HOuterContext, HValue*); | 
| + | 
| +  DECLARE_CONCRETE_INSTRUCTION(OuterContext); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| -    return Representation::None(); | 
| +    return Representation::Tagged(); | 
| } | 
|  | 
| -  DECLARE_CONCRETE_INSTRUCTION(Context) | 
| - | 
| protected: | 
| virtual bool DataEquals(HValue* other) { return true; } | 
|  | 
| private: | 
| -  virtual bool IsDeletable() const { return true; } | 
| -}; | 
| - | 
| - | 
| -class HOuterContext: public HUnaryOperation { | 
| - public: | 
| explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) { | 
| set_representation(Representation::Tagged()); | 
| SetFlag(kUseGVN); | 
| } | 
|  | 
| -  DECLARE_CONCRETE_INSTRUCTION(OuterContext); | 
| - | 
| -  virtual Representation RequiredInputRepresentation(int index) { | 
| -    return Representation::Tagged(); | 
| -  } | 
| - | 
| - protected: | 
| -  virtual bool DataEquals(HValue* other) { return true; } | 
| - | 
| - private: | 
| virtual bool IsDeletable() const { return true; } | 
| }; | 
|  | 
| @@ -2162,6 +2260,13 @@ class HDeclareGlobals: public HUnaryOperation { | 
| SetAllSideEffects(); | 
| } | 
|  | 
| +  static HDeclareGlobals* New(Zone* zone, | 
| +                              HValue* context, | 
| +                              Handle<FixedArray> pairs, | 
| +                              int flags) { | 
| +    return new(zone) HDeclareGlobals(context, pairs, flags); | 
| +  } | 
| + | 
| HValue* context() { return OperandAt(0); } | 
| Handle<FixedArray> pairs() const { return pairs_; } | 
| int flags() const { return flags_; } | 
| @@ -2171,6 +2276,7 @@ class HDeclareGlobals: public HUnaryOperation { | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| } | 
| + | 
| private: | 
| Handle<FixedArray> pairs_; | 
| int flags_; | 
| @@ -2184,6 +2290,10 @@ class HGlobalObject: public HUnaryOperation { | 
| SetFlag(kUseGVN); | 
| } | 
|  | 
| +  static HGlobalObject* New(Zone* zone, HValue* context) { | 
| +    return new(zone) HGlobalObject(context); | 
| +  } | 
| + | 
| DECLARE_CONCRETE_INSTRUCTION(GlobalObject) | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| @@ -2200,11 +2310,7 @@ class HGlobalObject: public HUnaryOperation { | 
|  | 
| class HGlobalReceiver: public HUnaryOperation { | 
| public: | 
| -  explicit HGlobalReceiver(HValue* global_object) | 
| -      : HUnaryOperation(global_object) { | 
| -    set_representation(Representation::Tagged()); | 
| -    SetFlag(kUseGVN); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HGlobalReceiver, HValue*); | 
|  | 
| DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver) | 
|  | 
| @@ -2216,6 +2322,12 @@ class HGlobalReceiver: public HUnaryOperation { | 
| virtual bool DataEquals(HValue* other) { return true; } | 
|  | 
| private: | 
| +  explicit HGlobalReceiver(HValue* global_object) | 
| +      : HUnaryOperation(global_object) { | 
| +    set_representation(Representation::Tagged()); | 
| +    SetFlag(kUseGVN); | 
| +  } | 
| + | 
| virtual bool IsDeletable() const { return true; } | 
| }; | 
|  | 
| @@ -2282,6 +2394,13 @@ class HInvokeFunction: public HBinaryCall { | 
| : HBinaryCall(context, function, argument_count) { | 
| } | 
|  | 
| +  static HInvokeFunction* New(Zone* zone, | 
| +                              HValue* context, | 
| +                              HValue* function, | 
| +                              int argument_count) { | 
| +    return new(zone) HInvokeFunction(context, function, argument_count); | 
| +  } | 
| + | 
| HInvokeFunction(HValue* context, | 
| HValue* function, | 
| Handle<JSFunction> known_function, | 
| @@ -2292,6 +2411,15 @@ class HInvokeFunction: public HBinaryCall { | 
| ? 0 : known_function->shared()->formal_parameter_count(); | 
| } | 
|  | 
| +  static HInvokeFunction* New(Zone* zone, | 
| +                              HValue* context, | 
| +                              HValue* function, | 
| +                              Handle<JSFunction> known_function, | 
| +                              int argument_count) { | 
| +    return new(zone) HInvokeFunction(context, function, | 
| +                                     known_function, argument_count); | 
| +  } | 
| + | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| } | 
| @@ -2383,6 +2511,13 @@ class HCallFunction: public HBinaryCall { | 
| : HBinaryCall(context, function, argument_count) { | 
| } | 
|  | 
| +  static HCallFunction* New(Zone* zone, | 
| +                            HValue* context, | 
| +                            HValue* function, | 
| +                            int argument_count) { | 
| +    return new(zone) HCallFunction(context, function, argument_count); | 
| +  } | 
| + | 
| HValue* context() { return first(); } | 
| HValue* function() { return second(); } | 
|  | 
| @@ -2400,6 +2535,13 @@ class HCallGlobal: public HUnaryCall { | 
| : HUnaryCall(context, argument_count), name_(name) { | 
| } | 
|  | 
| +  static HCallGlobal* New(Zone* zone, | 
| +                          HValue* context, | 
| +                          Handle<String> name, | 
| +                          int argument_count) { | 
| +    return new(zone) HCallGlobal(context, name, argument_count); | 
| +  } | 
| + | 
| virtual void PrintDataTo(StringStream* stream); | 
|  | 
| HValue* context() { return value(); } | 
| @@ -2483,12 +2625,12 @@ class HCallNewArray: public HCallNew { | 
|  | 
| class HCallRuntime: public HCall<1> { | 
| public: | 
| -  HCallRuntime(HValue* context, | 
| -               Handle<String> name, | 
| -               const Runtime::Function* c_function, | 
| -               int argument_count) | 
| -      : HCall<1>(argument_count), c_function_(c_function), name_(name) { | 
| -    SetOperandAt(0, context); | 
| +  static HCallRuntime* New(Zone* zone, | 
| +                           HValue* context, | 
| +                           Handle<String> name, | 
| +                           const Runtime::Function* c_function, | 
| +                           int argument_count) { | 
| +    return new(zone) HCallRuntime(context, name, c_function, argument_count); | 
| } | 
|  | 
| virtual void PrintDataTo(StringStream* stream); | 
| @@ -2504,6 +2646,14 @@ class HCallRuntime: public HCall<1> { | 
| DECLARE_CONCRETE_INSTRUCTION(CallRuntime) | 
|  | 
| private: | 
| +  HCallRuntime(HValue* context, | 
| +               Handle<String> name, | 
| +               const Runtime::Function* c_function, | 
| +               int argument_count) | 
| +      : HCall<1>(argument_count), c_function_(c_function), name_(name) { | 
| +    SetOperandAt(0, context); | 
| +  } | 
| + | 
| const Runtime::Function* c_function_; | 
| Handle<String> name_; | 
| }; | 
| @@ -2511,12 +2661,7 @@ class HCallRuntime: public HCall<1> { | 
|  | 
| class HMapEnumLength: public HUnaryOperation { | 
| public: | 
| -  explicit HMapEnumLength(HValue* value) | 
| -      : HUnaryOperation(value, HType::Smi()) { | 
| -    set_representation(Representation::Smi()); | 
| -    SetFlag(kUseGVN); | 
| -    SetGVNFlag(kDependsOnMaps); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HMapEnumLength, HValue*); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| @@ -2528,6 +2673,13 @@ class HMapEnumLength: public HUnaryOperation { | 
| virtual bool DataEquals(HValue* other) { return true; } | 
|  | 
| private: | 
| +  explicit HMapEnumLength(HValue* value) | 
| +      : HUnaryOperation(value, HType::Smi()) { | 
| +    set_representation(Representation::Smi()); | 
| +    SetFlag(kUseGVN); | 
| +    SetGVNFlag(kDependsOnMaps); | 
| +  } | 
| + | 
| virtual bool IsDeletable() const { return true; } | 
| }; | 
|  | 
| @@ -2556,13 +2708,7 @@ class HElementsKind: public HUnaryOperation { | 
|  | 
| class HBitNot: public HUnaryOperation { | 
| public: | 
| -  explicit HBitNot(HValue* value) | 
| -      : HUnaryOperation(value, HType::TaggedNumber()) { | 
| -    set_representation(Representation::Integer32()); | 
| -    SetFlag(kUseGVN); | 
| -    SetFlag(kTruncatingToInt32); | 
| -    SetFlag(kAllowUndefinedAsNaN); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HBitNot, HValue*); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Integer32(); | 
| @@ -2579,6 +2725,14 @@ class HBitNot: public HUnaryOperation { | 
| virtual bool DataEquals(HValue* other) { return true; } | 
|  | 
| private: | 
| +  explicit HBitNot(HValue* value) | 
| +      : HUnaryOperation(value, HType::TaggedNumber()) { | 
| +    set_representation(Representation::Integer32()); | 
| +    SetFlag(kUseGVN); | 
| +    SetFlag(kTruncatingToInt32); | 
| +    SetFlag(kAllowUndefinedAsNaN); | 
| +  } | 
| + | 
| virtual bool IsDeletable() const { return true; } | 
| }; | 
|  | 
| @@ -2683,15 +2837,7 @@ class HUnaryMathOperation: public HTemplateInstruction<2> { | 
|  | 
| class HLoadExternalArrayPointer: public HUnaryOperation { | 
| public: | 
| -  explicit HLoadExternalArrayPointer(HValue* value) | 
| -      : HUnaryOperation(value) { | 
| -    set_representation(Representation::External()); | 
| -    // The result of this instruction is idempotent as long as its inputs don't | 
| -    // change.  The external array of a specialized array elements object cannot | 
| -    // change once set, so it's no necessary to introduce any additional | 
| -    // dependencies on top of the inputs. | 
| -    SetFlag(kUseGVN); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HLoadExternalArrayPointer, HValue*); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| @@ -2707,15 +2853,27 @@ class HLoadExternalArrayPointer: public HUnaryOperation { | 
| virtual bool DataEquals(HValue* other) { return true; } | 
|  | 
| private: | 
| -  virtual bool IsDeletable() const { return true; } | 
| -}; | 
| - | 
| - | 
| -class HCheckMaps: public HTemplateInstruction<2> { | 
| - public: | 
| -  static HCheckMaps* New(HValue* value, Handle<Map> map, Zone* zone, | 
| -                         CompilationInfo* info, HValue *typecheck = NULL); | 
| -  static HCheckMaps* New(HValue* value, SmallMapList* maps, Zone* zone, | 
| +  explicit HLoadExternalArrayPointer(HValue* value) | 
| +      : HUnaryOperation(value) { | 
| +    set_representation(Representation::External()); | 
| +    // The result of this instruction is idempotent as long as its inputs don't | 
| +    // change.  The external array of a specialized array elements object cannot | 
| +    // change once set, so it's no necessary to introduce any additional | 
| +    // dependencies on top of the inputs. | 
| +    SetFlag(kUseGVN); | 
| +  } | 
| + | 
| +  virtual bool IsDeletable() const { return true; } | 
| +}; | 
| + | 
| + | 
| +class HCheckMaps: public HTemplateInstruction<2> { | 
| + public: | 
| +  static HCheckMaps* New(Zone* zone, HValue* context, HValue* value, | 
| +                         Handle<Map> map, CompilationInfo* info, | 
| +                         HValue *typecheck = NULL); | 
| +  static HCheckMaps* New(Zone* zone, HValue* context, | 
| +                         HValue* value, SmallMapList* maps, | 
| HValue *typecheck = NULL) { | 
| HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); | 
| for (int i = 0; i < maps->length(); i++) { | 
| @@ -2791,13 +2949,7 @@ class HCheckMaps: public HTemplateInstruction<2> { | 
|  | 
| class HCheckFunction: public HUnaryOperation { | 
| public: | 
| -  HCheckFunction(HValue* value, Handle<JSFunction> function) | 
| -      : HUnaryOperation(value, value->type()), | 
| -        target_(function), target_unique_id_() { | 
| -    set_representation(Representation::Tagged()); | 
| -    SetFlag(kUseGVN); | 
| -    target_in_new_space_ = Isolate::Current()->heap()->InNewSpace(*function); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P2(HCheckFunction, HValue*, Handle<JSFunction>); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| @@ -2826,6 +2978,14 @@ class HCheckFunction: public HUnaryOperation { | 
| } | 
|  | 
| private: | 
| +  HCheckFunction(HValue* value, Handle<JSFunction> function) | 
| +      : HUnaryOperation(value, value->type()), | 
| +        target_(function), target_unique_id_() { | 
| +    set_representation(Representation::Tagged()); | 
| +    SetFlag(kUseGVN); | 
| +    target_in_new_space_ = Isolate::Current()->heap()->InNewSpace(*function); | 
| +  } | 
| + | 
| Handle<JSFunction> target_; | 
| UniqueValueId target_unique_id_; | 
| bool target_in_new_space_; | 
| @@ -2894,10 +3054,7 @@ class HCheckInstanceType: public HUnaryOperation { | 
|  | 
| class HCheckSmi: public HUnaryOperation { | 
| public: | 
| -  explicit HCheckSmi(HValue* value) : HUnaryOperation(value, HType::Smi()) { | 
| -    set_representation(Representation::Smi()); | 
| -    SetFlag(kUseGVN); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HCheckSmi, HValue*); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| @@ -2915,6 +3072,12 @@ class HCheckSmi: public HUnaryOperation { | 
|  | 
| protected: | 
| virtual bool DataEquals(HValue* other) { return true; } | 
| + | 
| + private: | 
| +  explicit HCheckSmi(HValue* value) : HUnaryOperation(value, HType::Smi()) { | 
| +    set_representation(Representation::Smi()); | 
| +    SetFlag(kUseGVN); | 
| +  } | 
| }; | 
|  | 
|  | 
| @@ -2935,11 +3098,7 @@ class HIsNumberAndBranch: public HUnaryControlInstruction { | 
|  | 
| class HCheckHeapObject: public HUnaryOperation { | 
| public: | 
| -  explicit HCheckHeapObject(HValue* value) | 
| -      : HUnaryOperation(value, HType::NonPrimitive()) { | 
| -    set_representation(Representation::Tagged()); | 
| -    SetFlag(kUseGVN); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| @@ -2957,40 +3116,24 @@ class HCheckHeapObject: public HUnaryOperation { | 
|  | 
| protected: | 
| virtual bool DataEquals(HValue* other) { return true; } | 
| + | 
| + private: | 
| +  explicit HCheckHeapObject(HValue* value) | 
| +      : HUnaryOperation(value, HType::NonPrimitive()) { | 
| +    set_representation(Representation::Tagged()); | 
| +    SetFlag(kUseGVN); | 
| +  } | 
| }; | 
|  | 
|  | 
| class HCheckPrototypeMaps: public HTemplateInstruction<0> { | 
| public: | 
| -  HCheckPrototypeMaps(Handle<JSObject> prototype, | 
| -                      Handle<JSObject> holder, | 
| -                      Zone* zone, | 
| -                      CompilationInfo* info) | 
| -      : prototypes_(2, zone), | 
| -        maps_(2, zone), | 
| -        first_prototype_unique_id_(), | 
| -        last_prototype_unique_id_(), | 
| -        can_omit_prototype_maps_(true) { | 
| -    SetFlag(kUseGVN); | 
| -    SetGVNFlag(kDependsOnMaps); | 
| -    // Keep a list of all objects on the prototype chain up to the holder | 
| -    // and the expected maps. | 
| -    while (true) { | 
| -      prototypes_.Add(prototype, zone); | 
| -      Handle<Map> map(prototype->map()); | 
| -      maps_.Add(map, zone); | 
| -      can_omit_prototype_maps_ &= map->CanOmitPrototypeChecks(); | 
| -      if (prototype.is_identical_to(holder)) break; | 
| -      prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype())); | 
| -    } | 
| -    if (can_omit_prototype_maps_) { | 
| -      // Mark in-flight compilation as dependent on those maps. | 
| -      for (int i = 0; i < maps()->length(); i++) { | 
| -        Handle<Map> map = maps()->at(i); | 
| -        map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup, | 
| -                                         info); | 
| -      } | 
| -    } | 
| +  static HCheckPrototypeMaps* New(Zone* zone, | 
| +                                  HValue* context, | 
| +                                  Handle<JSObject> prototype, | 
| +                                  Handle<JSObject> holder, | 
| +                                  CompilationInfo* info) { | 
| +    return new(zone) HCheckPrototypeMaps(prototype, holder, zone, info); | 
| } | 
|  | 
| ZoneList<Handle<JSObject> >* prototypes() { return &prototypes_; } | 
| @@ -3025,6 +3168,37 @@ class HCheckPrototypeMaps: public HTemplateInstruction<0> { | 
| } | 
|  | 
| private: | 
| +  HCheckPrototypeMaps(Handle<JSObject> prototype, | 
| +                      Handle<JSObject> holder, | 
| +                      Zone* zone, | 
| +                      CompilationInfo* info) | 
| +      : prototypes_(2, zone), | 
| +        maps_(2, zone), | 
| +        first_prototype_unique_id_(), | 
| +        last_prototype_unique_id_(), | 
| +        can_omit_prototype_maps_(true) { | 
| +    SetFlag(kUseGVN); | 
| +    SetGVNFlag(kDependsOnMaps); | 
| +    // Keep a list of all objects on the prototype chain up to the holder | 
| +    // and the expected maps. | 
| +    while (true) { | 
| +      prototypes_.Add(prototype, zone); | 
| +      Handle<Map> map(prototype->map()); | 
| +      maps_.Add(map, zone); | 
| +      can_omit_prototype_maps_ &= map->CanOmitPrototypeChecks(); | 
| +      if (prototype.is_identical_to(holder)) break; | 
| +      prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype())); | 
| +    } | 
| +    if (can_omit_prototype_maps_) { | 
| +      // Mark in-flight compilation as dependent on those maps. | 
| +      for (int i = 0; i < maps()->length(); i++) { | 
| +        Handle<Map> map = maps()->at(i); | 
| +        map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup, | 
| +                                         info); | 
| +      } | 
| +    } | 
| +  } | 
| + | 
| ZoneList<Handle<JSObject> > prototypes_; | 
| ZoneList<Handle<Map> > maps_; | 
| UniqueValueId first_prototype_unique_id_; | 
| @@ -3426,9 +3600,10 @@ class HInductionVariableAnnotation : public HUnaryOperation { | 
|  | 
| class HArgumentsObject: public HTemplateInstruction<0> { | 
| public: | 
| -  HArgumentsObject(int count, Zone* zone) : values_(count, zone) { | 
| -    set_representation(Representation::Tagged()); | 
| -    SetFlag(kIsArguments); | 
| +  static HArgumentsObject* New(Zone* zone, | 
| +                               HValue* context, | 
| +                               int count) { | 
| +    return new(zone) HArgumentsObject(count, zone); | 
| } | 
|  | 
| const ZoneList<HValue*>* arguments_values() const { return &values_; } | 
| @@ -3455,6 +3630,11 @@ class HArgumentsObject: public HTemplateInstruction<0> { | 
| } | 
|  | 
| private: | 
| +  HArgumentsObject(int count, Zone* zone) : values_(count, zone) { | 
| +    set_representation(Representation::Tagged()); | 
| +    SetFlag(kIsArguments); | 
| +  } | 
| + | 
| virtual bool IsDeletable() const { return true; } | 
|  | 
| ZoneList<HValue*> values_; | 
| @@ -3463,24 +3643,10 @@ class HArgumentsObject: public HTemplateInstruction<0> { | 
|  | 
| class HConstant: public HTemplateInstruction<0> { | 
| public: | 
| -  HConstant(Handle<Object> handle, Representation r = Representation::None()); | 
| -  HConstant(int32_t value, | 
| -            Representation r = Representation::None(), | 
| -            bool is_not_in_new_space = true, | 
| -            Handle<Object> optional_handle = Handle<Object>::null()); | 
| -  HConstant(double value, | 
| -            Representation r = Representation::None(), | 
| -            bool is_not_in_new_space = true, | 
| -            Handle<Object> optional_handle = Handle<Object>::null()); | 
| -  HConstant(Handle<Object> handle, | 
| -            UniqueValueId unique_id, | 
| -            Representation r, | 
| -            HType type, | 
| -            bool is_internalized_string, | 
| -            bool is_not_in_new_space, | 
| -            bool is_cell, | 
| -            bool boolean_value); | 
| -  explicit HConstant(ExternalReference reference); | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HConstant, int32_t); | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double); | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>); | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference); | 
|  | 
| Handle<Object> handle() { | 
| if (handle_.is_null()) { | 
| @@ -3661,6 +3827,26 @@ class HConstant: public HTemplateInstruction<0> { | 
| } | 
|  | 
| private: | 
| +  friend class HGraph; | 
| +  HConstant(Handle<Object> handle, Representation r = Representation::None()); | 
| +  HConstant(int32_t value, | 
| +            Representation r = Representation::None(), | 
| +            bool is_not_in_new_space = true, | 
| +            Handle<Object> optional_handle = Handle<Object>::null()); | 
| +  HConstant(double value, | 
| +            Representation r = Representation::None(), | 
| +            bool is_not_in_new_space = true, | 
| +            Handle<Object> optional_handle = Handle<Object>::null()); | 
| +  HConstant(Handle<Object> handle, | 
| +            UniqueValueId unique_id, | 
| +            Representation r, | 
| +            HType type, | 
| +            bool is_internalized_string, | 
| +            bool is_not_in_new_space, | 
| +            bool is_cell, | 
| +            bool boolean_value); | 
| +  explicit HConstant(ExternalReference reference); | 
| + | 
| void Initialize(Representation r); | 
|  | 
| virtual bool IsDeletable() const { return true; } | 
| @@ -3780,11 +3966,7 @@ class HBinaryOperation: public HTemplateInstruction<3> { | 
|  | 
| class HWrapReceiver: public HTemplateInstruction<2> { | 
| public: | 
| -  HWrapReceiver(HValue* receiver, HValue* function) { | 
| -    set_representation(Representation::Tagged()); | 
| -    SetOperandAt(0, receiver); | 
| -    SetOperandAt(1, function); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P2(HWrapReceiver, HValue*, HValue*); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| @@ -3798,6 +3980,13 @@ class HWrapReceiver: public HTemplateInstruction<2> { | 
| virtual void PrintDataTo(StringStream* stream); | 
|  | 
| DECLARE_CONCRETE_INSTRUCTION(WrapReceiver) | 
| + | 
| + private: | 
| +  HWrapReceiver(HValue* receiver, HValue* function) { | 
| +    set_representation(Representation::Tagged()); | 
| +    SetOperandAt(0, receiver); | 
| +    SetOperandAt(1, function); | 
| +  } | 
| }; | 
|  | 
|  | 
| @@ -3833,12 +4022,7 @@ class HApplyArguments: public HTemplateInstruction<4> { | 
|  | 
| class HArgumentsElements: public HTemplateInstruction<0> { | 
| public: | 
| -  explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) { | 
| -    // The value produced by this instruction is a pointer into the stack | 
| -    // that looks as if it was a smi because of alignment. | 
| -    set_representation(Representation::Tagged()); | 
| -    SetFlag(kUseGVN); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HArgumentsElements, bool); | 
|  | 
| DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements) | 
|  | 
| @@ -3852,6 +4036,13 @@ class HArgumentsElements: public HTemplateInstruction<0> { | 
| virtual bool DataEquals(HValue* other) { return true; } | 
|  | 
| private: | 
| +  explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) { | 
| +    // The value produced by this instruction is a pointer into the stack | 
| +    // that looks as if it was a smi because of alignment. | 
| +    set_representation(Representation::Tagged()); | 
| +    SetFlag(kUseGVN); | 
| +  } | 
| + | 
| virtual bool IsDeletable() const { return true; } | 
|  | 
| bool from_inlined_; | 
| @@ -3860,10 +4051,7 @@ class HArgumentsElements: public HTemplateInstruction<0> { | 
|  | 
| class HArgumentsLength: public HUnaryOperation { | 
| public: | 
| -  explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) { | 
| -    set_representation(Representation::Integer32()); | 
| -    SetFlag(kUseGVN); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HArgumentsLength, HValue*); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| @@ -3875,6 +4063,11 @@ class HArgumentsLength: public HUnaryOperation { | 
| virtual bool DataEquals(HValue* other) { return true; } | 
|  | 
| private: | 
| +  explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) { | 
| +    set_representation(Representation::Integer32()); | 
| +    SetFlag(kUseGVN); | 
| +  } | 
| + | 
| virtual bool IsDeletable() const { return true; } | 
| }; | 
|  | 
| @@ -3913,23 +4106,11 @@ class HBoundsCheckBaseIndexInformation; | 
|  | 
| class HBoundsCheck: public HTemplateInstruction<2> { | 
| public: | 
| -  // Normally HBoundsCheck should be created using the | 
| -  // HGraphBuilder::AddBoundsCheck() helper. | 
| -  // However when building stubs, where we know that the arguments are Int32, | 
| -  // it makes sense to invoke this constructor directly. | 
| -  HBoundsCheck(HValue* index, HValue* length) | 
| -    : skip_check_(false), | 
| -      base_(NULL), offset_(0), scale_(0), | 
| -      responsibility_direction_(DIRECTION_NONE), | 
| -      allow_equality_(false) { | 
| -    SetOperandAt(0, index); | 
| -    SetOperandAt(1, length); | 
| -    SetFlag(kFlexibleRepresentation); | 
| -    SetFlag(kUseGVN); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P2(HBoundsCheck, HValue*, HValue*); | 
|  | 
| bool skip_check() const { return skip_check_; } | 
| void set_skip_check() { skip_check_ = true; } | 
| + | 
| HValue* base() { return base_; } | 
| int offset() { return offset_; } | 
| int scale() { return scale_; } | 
| @@ -3999,6 +4180,21 @@ class HBoundsCheck: public HTemplateInstruction<2> { | 
| bool allow_equality_; | 
|  | 
| private: | 
| +  // Normally HBoundsCheck should be created using the | 
| +  // HGraphBuilder::AddBoundsCheck() helper. | 
| +  // However when building stubs, where we know that the arguments are Int32, | 
| +  // it makes sense to invoke this constructor directly. | 
| +  HBoundsCheck(HValue* index, HValue* length) | 
| +    : skip_check_(false), | 
| +      base_(NULL), offset_(0), scale_(0), | 
| +      responsibility_direction_(DIRECTION_NONE), | 
| +      allow_equality_(false) { | 
| +    SetOperandAt(0, index); | 
| +    SetOperandAt(1, length); | 
| +    SetFlag(kFlexibleRepresentation); | 
| +    SetFlag(kUseGVN); | 
| +  } | 
| + | 
| virtual bool IsDeletable() const { | 
| return skip_check() && !FLAG_debug_code; | 
| } | 
| @@ -4095,15 +4291,11 @@ class HBitwiseBinaryOperation: public HBinaryOperation { | 
|  | 
| class HMathFloorOfDiv: public HBinaryOperation { | 
| public: | 
| -  HMathFloorOfDiv(HValue* context, HValue* left, HValue* right) | 
| -      : HBinaryOperation(context, left, right) { | 
| -    set_representation(Representation::Integer32()); | 
| -    SetFlag(kUseGVN); | 
| -    SetFlag(kCanOverflow); | 
| -    if (!right->IsConstant()) { | 
| -      SetFlag(kCanBeDivByZero); | 
| -    } | 
| -    SetFlag(kAllowUndefinedAsNaN); | 
| +  static HMathFloorOfDiv* New(Zone* zone, | 
| +                              HValue* context, | 
| +                              HValue* left, | 
| +                              HValue* right) { | 
| +    return new(zone) HMathFloorOfDiv(context, left, right); | 
| } | 
|  | 
| virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 
| @@ -4118,6 +4310,17 @@ class HMathFloorOfDiv: public HBinaryOperation { | 
| virtual bool DataEquals(HValue* other) { return true; } | 
|  | 
| private: | 
| +  HMathFloorOfDiv(HValue* context, HValue* left, HValue* right) | 
| +      : HBinaryOperation(context, left, right) { | 
| +    set_representation(Representation::Integer32()); | 
| +    SetFlag(kUseGVN); | 
| +    SetFlag(kCanOverflow); | 
| +    if (!right->IsConstant()) { | 
| +      SetFlag(kCanBeDivByZero); | 
| +    } | 
| +    SetFlag(kAllowUndefinedAsNaN); | 
| +  } | 
| + | 
| virtual bool IsDeletable() const { return true; } | 
| }; | 
|  | 
| @@ -4219,11 +4422,16 @@ class HCompareNumericAndBranch: public HTemplateControlInstruction<2, 2> { | 
|  | 
| class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> { | 
| public: | 
| -  HCompareObjectEqAndBranch(HValue* left, HValue* right) { | 
| +  // TODO(danno): make this private when the IfBuilder properly constructs | 
| +  // control flow instructions. | 
| +  HCompareObjectEqAndBranch(HValue* left, | 
| +                            HValue* right) { | 
| SetOperandAt(0, left); | 
| SetOperandAt(1, right); | 
| } | 
|  | 
| +  DECLARE_INSTRUCTION_FACTORY_P2(HCompareObjectEqAndBranch, HValue*, HValue*); | 
| + | 
| HValue* left() { return OperandAt(0); } | 
| HValue* right() { return OperandAt(1); } | 
|  | 
| @@ -4509,7 +4717,10 @@ class HInstanceSize: public HTemplateInstruction<1> { | 
|  | 
| class HPower: public HTemplateInstruction<2> { | 
| public: | 
| -  static HInstruction* New(Zone* zone, HValue* left, HValue* right); | 
| +  static HInstruction* New(Zone* zone, | 
| +                           HValue* context, | 
| +                           HValue* left, | 
| +                           HValue* right); | 
|  | 
| HValue* left() { return OperandAt(0); } | 
| HValue* right() const { return OperandAt(1); } | 
| @@ -4844,8 +5055,8 @@ class HMathMinMax: public HArithmeticBinaryOperation { | 
| class HBitwise: public HBitwiseBinaryOperation { | 
| public: | 
| static HInstruction* New(Zone* zone, | 
| -                           Token::Value op, | 
| HValue* context, | 
| +                           Token::Value op, | 
| HValue* left, | 
| HValue* right); | 
|  | 
| @@ -4867,7 +5078,10 @@ class HBitwise: public HBitwiseBinaryOperation { | 
| virtual Range* InferRange(Zone* zone); | 
|  | 
| private: | 
| -  HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right) | 
| +  HBitwise(HValue* context, | 
| +           Token::Value op, | 
| +           HValue* left, | 
| +           HValue* right) | 
| : HBitwiseBinaryOperation(context, left, right, HType::TaggedNumber()), | 
| op_(op) { | 
| ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); | 
| @@ -5030,10 +5244,7 @@ class HRor: public HBitwiseBinaryOperation { | 
|  | 
| class HOsrEntry: public HTemplateInstruction<0> { | 
| public: | 
| -  explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { | 
| -    SetGVNFlag(kChangesOsrEntries); | 
| -    SetGVNFlag(kChangesNewSpacePromotion); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HOsrEntry, BailoutId); | 
|  | 
| BailoutId ast_id() const { return ast_id_; } | 
|  | 
| @@ -5044,8 +5255,13 @@ class HOsrEntry: public HTemplateInstruction<0> { | 
| DECLARE_CONCRETE_INSTRUCTION(OsrEntry) | 
|  | 
| private: | 
| -  BailoutId ast_id_; | 
| -}; | 
| +  explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { | 
| +    SetGVNFlag(kChangesOsrEntries); | 
| +    SetGVNFlag(kChangesNewSpacePromotion); | 
| +  } | 
| + | 
| +  BailoutId ast_id_; | 
| +}; | 
|  | 
|  | 
| class HParameter: public HTemplateInstruction<0> { | 
| @@ -5055,6 +5271,23 @@ class HParameter: public HTemplateInstruction<0> { | 
| REGISTER_PARAMETER | 
| }; | 
|  | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HParameter, unsigned); | 
| +  DECLARE_INSTRUCTION_FACTORY_P2(HParameter, unsigned, ParameterKind); | 
| +  DECLARE_INSTRUCTION_FACTORY_P3(HParameter, unsigned, ParameterKind, | 
| +                                 Representation); | 
| + | 
| +  unsigned index() const { return index_; } | 
| +  ParameterKind kind() const { return kind_; } | 
| + | 
| +  virtual void PrintDataTo(StringStream* stream); | 
| + | 
| +  virtual Representation RequiredInputRepresentation(int index) { | 
| +    return Representation::None(); | 
| +  } | 
| + | 
| +  DECLARE_CONCRETE_INSTRUCTION(Parameter) | 
| + | 
| + private: | 
| explicit HParameter(unsigned index, | 
| ParameterKind kind = STACK_PARAMETER) | 
| : index_(index), | 
| @@ -5070,18 +5303,6 @@ class HParameter: public HTemplateInstruction<0> { | 
| set_representation(r); | 
| } | 
|  | 
| -  unsigned index() const { return index_; } | 
| -  ParameterKind kind() const { return kind_; } | 
| - | 
| -  virtual void PrintDataTo(StringStream* stream); | 
| - | 
| -  virtual Representation RequiredInputRepresentation(int index) { | 
| -    return Representation::None(); | 
| -  } | 
| - | 
| -  DECLARE_CONCRETE_INSTRUCTION(Parameter) | 
| - | 
| - private: | 
| unsigned index_; | 
| ParameterKind kind_; | 
| }; | 
| @@ -5122,10 +5343,7 @@ class HCallStub: public HUnaryCall { | 
|  | 
| class HUnknownOSRValue: public HTemplateInstruction<0> { | 
| public: | 
| -  HUnknownOSRValue() | 
| -      : incoming_value_(NULL) { | 
| -    set_representation(Representation::Tagged()); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P0(HUnknownOSRValue) | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::None(); | 
| @@ -5147,6 +5365,11 @@ class HUnknownOSRValue: public HTemplateInstruction<0> { | 
| DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue) | 
|  | 
| private: | 
| +  HUnknownOSRValue() | 
| +      : incoming_value_(NULL) { | 
| +    set_representation(Representation::Tagged()); | 
| +  } | 
| + | 
| HPhi* incoming_value_; | 
| }; | 
|  | 
| @@ -5229,32 +5452,13 @@ class HLoadGlobalGeneric: public HTemplateInstruction<2> { | 
|  | 
| class HAllocate: public HTemplateInstruction<2> { | 
| public: | 
| -  HAllocate(HValue* context, | 
| -            HValue* size, | 
| -            HType type, | 
| -            bool pretenure, | 
| -            ElementsKind kind = FAST_ELEMENTS) | 
| -      : HTemplateInstruction<2>(type) { | 
| -    SetOperandAt(0, context); | 
| -    SetOperandAt(1, size); | 
| -    set_representation(Representation::Tagged()); | 
| -    SetFlag(kTrackSideEffectDominators); | 
| -    SetGVNFlag(kChangesNewSpacePromotion); | 
| -    SetGVNFlag(kDependsOnNewSpacePromotion); | 
| -    if (pretenure) { | 
| -      if (IsFastDoubleElementsKind(kind)) { | 
| -        flags_ = static_cast<HAllocate::Flags>(ALLOCATE_IN_OLD_DATA_SPACE | | 
| -             ALLOCATE_DOUBLE_ALIGNED); | 
| -      } else { | 
| -        flags_ = ALLOCATE_IN_OLD_POINTER_SPACE; | 
| -      } | 
| -    } else { | 
| -      flags_ = ALLOCATE_IN_NEW_SPACE; | 
| -      if (IsFastDoubleElementsKind(kind)) { | 
| -        flags_ = static_cast<HAllocate::Flags>(flags_ | | 
| -            ALLOCATE_DOUBLE_ALIGNED); | 
| -      } | 
| -    } | 
| +  static HAllocate* New(Zone* zone, | 
| +                        HValue* context, | 
| +                        HValue* size, | 
| +                        HType type, | 
| +                        bool pretenure, | 
| +                        ElementsKind kind = FAST_ELEMENTS) { | 
| +    return new(zone) HAllocate(context, size, type, pretenure, kind); | 
| } | 
|  | 
| // Maximum instance size for which allocations will be inlined. | 
| @@ -5327,6 +5531,34 @@ class HAllocate: public HTemplateInstruction<2> { | 
| PREFILL_WITH_FILLER = 1 << 4 | 
| }; | 
|  | 
| +  HAllocate(HValue* context, | 
| +            HValue* size, | 
| +            HType type, | 
| +            bool pretenure, | 
| +            ElementsKind kind) | 
| +      : HTemplateInstruction<2>(type) { | 
| +    SetOperandAt(0, context); | 
| +    SetOperandAt(1, size); | 
| +    set_representation(Representation::Tagged()); | 
| +    SetFlag(kTrackSideEffectDominators); | 
| +    SetGVNFlag(kChangesNewSpacePromotion); | 
| +    SetGVNFlag(kDependsOnNewSpacePromotion); | 
| +    if (pretenure) { | 
| +      if (IsFastDoubleElementsKind(kind)) { | 
| +        flags_ = static_cast<HAllocate::Flags>(ALLOCATE_IN_OLD_DATA_SPACE | | 
| +             ALLOCATE_DOUBLE_ALIGNED); | 
| +      } else { | 
| +        flags_ = ALLOCATE_IN_OLD_POINTER_SPACE; | 
| +      } | 
| +    } else { | 
| +      flags_ = ALLOCATE_IN_NEW_SPACE; | 
| +      if (IsFastDoubleElementsKind(kind)) { | 
| +        flags_ = static_cast<HAllocate::Flags>(flags_ | | 
| +            ALLOCATE_DOUBLE_ALIGNED); | 
| +      } | 
| +    } | 
| +  } | 
| + | 
| Flags flags_; | 
| Handle<Map> known_initial_map_; | 
| }; | 
| @@ -5334,11 +5566,12 @@ class HAllocate: public HTemplateInstruction<2> { | 
|  | 
| class HInnerAllocatedObject: public HTemplateInstruction<1> { | 
| public: | 
| -  HInnerAllocatedObject(HValue* value, int offset, HType type = HType::Tagged()) | 
| -      : HTemplateInstruction<1>(type), offset_(offset) { | 
| -    ASSERT(value->IsAllocate()); | 
| -    SetOperandAt(0, value); | 
| -    set_representation(Representation::Tagged()); | 
| +  static HInnerAllocatedObject* New(Zone* zone, | 
| +                                    HValue* context, | 
| +                                    HValue* value, | 
| +                                    int offset, | 
| +                                    HType type = HType::Tagged()) { | 
| +    return new(zone) HInnerAllocatedObject(value, offset, type); | 
| } | 
|  | 
| HValue* base_object() { return OperandAt(0); } | 
| @@ -5353,6 +5586,14 @@ class HInnerAllocatedObject: public HTemplateInstruction<1> { | 
| DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject) | 
|  | 
| private: | 
| +  HInnerAllocatedObject(HValue* value, int offset, HType type = HType::Tagged()) | 
| +      : HTemplateInstruction<1>(type), offset_(offset) { | 
| +    ASSERT(value->IsAllocate()); | 
| +    SetOperandAt(0, value); | 
| +    set_type(type); | 
| +    set_representation(Representation::Tagged()); | 
| +  } | 
| + | 
| int offset_; | 
| }; | 
|  | 
| @@ -5389,14 +5630,8 @@ inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, | 
|  | 
| class HStoreGlobalCell: public HUnaryOperation { | 
| public: | 
| -  HStoreGlobalCell(HValue* value, | 
| -                   Handle<PropertyCell> cell, | 
| -                   PropertyDetails details) | 
| -      : HUnaryOperation(value), | 
| -        cell_(cell), | 
| -        details_(details) { | 
| -    SetGVNFlag(kChangesGlobalVars); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P3(HStoreGlobalCell, HValue*, | 
| +                                 Handle<PropertyCell>, PropertyDetails); | 
|  | 
| Handle<PropertyCell> cell() const { return cell_; } | 
| bool RequiresHoleCheck() { | 
| @@ -5414,6 +5649,15 @@ class HStoreGlobalCell: public HUnaryOperation { | 
| DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell) | 
|  | 
| private: | 
| +  HStoreGlobalCell(HValue* value, | 
| +                   Handle<PropertyCell> cell, | 
| +                   PropertyDetails details) | 
| +      : HUnaryOperation(value), | 
| +        cell_(cell), | 
| +        details_(details) { | 
| +    SetGVNFlag(kChangesGlobalVars); | 
| +  } | 
| + | 
| Handle<PropertyCell> cell_; | 
| PropertyDetails details_; | 
| }; | 
| @@ -5421,18 +5665,14 @@ class HStoreGlobalCell: public HUnaryOperation { | 
|  | 
| class HStoreGlobalGeneric: public HTemplateInstruction<3> { | 
| public: | 
| -  HStoreGlobalGeneric(HValue* context, | 
| -                      HValue* global_object, | 
| -                      Handle<Object> name, | 
| -                      HValue* value, | 
| -                      StrictModeFlag strict_mode_flag) | 
| -      : name_(name), | 
| -        strict_mode_flag_(strict_mode_flag) { | 
| -    SetOperandAt(0, context); | 
| -    SetOperandAt(1, global_object); | 
| -    SetOperandAt(2, value); | 
| -    set_representation(Representation::Tagged()); | 
| -    SetAllSideEffects(); | 
| +  inline static HStoreGlobalGeneric* New(Zone* zone, | 
| +                                         HValue* context, | 
| +                                         HValue* global_object, | 
| +                                         Handle<Object> name, | 
| +                                         HValue* value, | 
| +                                         StrictModeFlag strict_mode_flag) { | 
| +    return new(zone) HStoreGlobalGeneric(context, global_object, | 
| +                                         name, value, strict_mode_flag); | 
| } | 
|  | 
| HValue* context() { return OperandAt(0); } | 
| @@ -5450,6 +5690,20 @@ class HStoreGlobalGeneric: public HTemplateInstruction<3> { | 
| DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric) | 
|  | 
| private: | 
| +  HStoreGlobalGeneric(HValue* context, | 
| +                      HValue* global_object, | 
| +                      Handle<Object> name, | 
| +                      HValue* value, | 
| +                      StrictModeFlag strict_mode_flag) | 
| +      : name_(name), | 
| +        strict_mode_flag_(strict_mode_flag) { | 
| +    SetOperandAt(0, context); | 
| +    SetOperandAt(1, global_object); | 
| +    SetOperandAt(2, value); | 
| +    set_representation(Representation::Tagged()); | 
| +    SetAllSideEffects(); | 
| +  } | 
| + | 
| Handle<Object> name_; | 
| StrictModeFlag strict_mode_flag_; | 
| }; | 
| @@ -5537,12 +5791,8 @@ class HStoreContextSlot: public HTemplateInstruction<2> { | 
| kCheckIgnoreAssignment | 
| }; | 
|  | 
| -  HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value) | 
| -      : slot_index_(slot_index), mode_(mode) { | 
| -    SetOperandAt(0, context); | 
| -    SetOperandAt(1, value); | 
| -    SetGVNFlag(kChangesContextSlots); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P4(HStoreContextSlot, HValue*, int, | 
| +                                 Mode, HValue*); | 
|  | 
| HValue* context() { return OperandAt(0); } | 
| HValue* value() { return OperandAt(1); } | 
| @@ -5570,6 +5820,13 @@ class HStoreContextSlot: public HTemplateInstruction<2> { | 
| DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot) | 
|  | 
| private: | 
| +  HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value) | 
| +      : slot_index_(slot_index), mode_(mode) { | 
| +    SetOperandAt(0, context); | 
| +    SetOperandAt(1, value); | 
| +    SetGVNFlag(kChangesContextSlots); | 
| +  } | 
| + | 
| int slot_index_; | 
| Mode mode_; | 
| }; | 
| @@ -5741,31 +5998,9 @@ class HObjectAccess { | 
|  | 
| class HLoadNamedField: public HTemplateInstruction<2> { | 
| public: | 
| -  HLoadNamedField(HValue* object, | 
| -                  HObjectAccess access, | 
| -                  HValue* typecheck = NULL) | 
| -      : access_(access) { | 
| -    ASSERT(object != NULL); | 
| -    SetOperandAt(0, object); | 
| -    SetOperandAt(1, typecheck != NULL ? typecheck : object); | 
| - | 
| -    Representation representation = access.representation(); | 
| -    if (representation.IsSmi()) { | 
| -      set_type(HType::Smi()); | 
| -      set_representation(representation); | 
| -    } else if (representation.IsDouble() || | 
| -               representation.IsExternal() || | 
| -               representation.IsInteger32()) { | 
| -      set_representation(representation); | 
| -    } else if (FLAG_track_heap_object_fields && | 
| -               representation.IsHeapObject()) { | 
| -      set_type(HType::NonPrimitive()); | 
| -      set_representation(Representation::Tagged()); | 
| -    } else { | 
| -      set_representation(Representation::Tagged()); | 
| -    } | 
| -    access.SetGVNFlags(this, false); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P2(HLoadNamedField, HValue*, HObjectAccess); | 
| +  DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, HObjectAccess, | 
| +                                 HValue*); | 
|  | 
| HValue* object() { return OperandAt(0); } | 
| HValue* typecheck() { | 
| @@ -5798,6 +6033,32 @@ class HLoadNamedField: public HTemplateInstruction<2> { | 
| } | 
|  | 
| private: | 
| +  HLoadNamedField(HValue* object, | 
| +                  HObjectAccess access, | 
| +                  HValue* typecheck = NULL) | 
| +      : access_(access) { | 
| +    ASSERT(object != NULL); | 
| +    SetOperandAt(0, object); | 
| +    SetOperandAt(1, typecheck != NULL ? typecheck : object); | 
| + | 
| +    Representation representation = access.representation(); | 
| +    if (representation.IsSmi()) { | 
| +      set_type(HType::Smi()); | 
| +      set_representation(representation); | 
| +    } else if (representation.IsDouble() || | 
| +               representation.IsExternal() || | 
| +               representation.IsInteger32()) { | 
| +      set_representation(representation); | 
| +    } else if (FLAG_track_heap_object_fields && | 
| +               representation.IsHeapObject()) { | 
| +      set_type(HType::NonPrimitive()); | 
| +      set_representation(Representation::Tagged()); | 
| +    } else { | 
| +      set_representation(Representation::Tagged()); | 
| +    } | 
| +    access.SetGVNFlags(this, false); | 
| +  } | 
| + | 
| virtual bool IsDeletable() const { return true; } | 
|  | 
| HObjectAccess access_; | 
| @@ -5916,55 +6177,10 @@ enum LoadKeyedHoleMode { | 
| class HLoadKeyed | 
| : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 
| public: | 
| -  HLoadKeyed(HValue* obj, | 
| -             HValue* key, | 
| -             HValue* dependency, | 
| -             ElementsKind elements_kind, | 
| -             LoadKeyedHoleMode mode = NEVER_RETURN_HOLE) | 
| -      : bit_field_(0) { | 
| -    bit_field_ = ElementsKindField::encode(elements_kind) | | 
| -        HoleModeField::encode(mode); | 
| - | 
| -    SetOperandAt(0, obj); | 
| -    SetOperandAt(1, key); | 
| -    SetOperandAt(2, dependency != NULL ? dependency : obj); | 
| - | 
| -    if (!is_external()) { | 
| -      // I can detect the case between storing double (holey and fast) and | 
| -      // smi/object by looking at elements_kind_. | 
| -      ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || | 
| -             IsFastDoubleElementsKind(elements_kind)); | 
| - | 
| -      if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 
| -        if (IsFastSmiElementsKind(elements_kind) && | 
| -            (!IsHoleyElementsKind(elements_kind) || | 
| -             mode == NEVER_RETURN_HOLE)) { | 
| -          set_type(HType::Smi()); | 
| -          set_representation(Representation::Smi()); | 
| -        } else { | 
| -          set_representation(Representation::Tagged()); | 
| -        } | 
| - | 
| -        SetGVNFlag(kDependsOnArrayElements); | 
| -      } else { | 
| -        set_representation(Representation::Double()); | 
| -        SetGVNFlag(kDependsOnDoubleArrayElements); | 
| -      } | 
| -    } else { | 
| -      if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 
| -          elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 
| -        set_representation(Representation::Double()); | 
| -      } else { | 
| -        set_representation(Representation::Integer32()); | 
| -      } | 
| - | 
| -      SetGVNFlag(kDependsOnExternalMemory); | 
| -      // Native code could change the specialized array. | 
| -      SetGVNFlag(kDependsOnCalls); | 
| -    } | 
| - | 
| -    SetFlag(kUseGVN); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P4(HLoadKeyed, HValue*, HValue*, HValue*, | 
| +                                 ElementsKind); | 
| +  DECLARE_INSTRUCTION_FACTORY_P5(HLoadKeyed, HValue*, HValue*, HValue*, | 
| +                                 ElementsKind, LoadKeyedHoleMode); | 
|  | 
| bool is_external() const { | 
| return IsExternalArrayElementsKind(elements_kind()); | 
| @@ -6020,19 +6236,69 @@ class HLoadKeyed | 
|  | 
| virtual Range* InferRange(Zone* zone); | 
|  | 
| -  DECLARE_CONCRETE_INSTRUCTION(LoadKeyed) | 
| +  DECLARE_CONCRETE_INSTRUCTION(LoadKeyed) | 
| + | 
| + protected: | 
| +  virtual bool DataEquals(HValue* other) { | 
| +    if (!other->IsLoadKeyed()) return false; | 
| +    HLoadKeyed* other_load = HLoadKeyed::cast(other); | 
| + | 
| +    if (IsDehoisted() && index_offset() != other_load->index_offset()) | 
| +      return false; | 
| +    return elements_kind() == other_load->elements_kind(); | 
| +  } | 
| + | 
| + private: | 
| +  HLoadKeyed(HValue* obj, | 
| +             HValue* key, | 
| +             HValue* dependency, | 
| +             ElementsKind elements_kind, | 
| +             LoadKeyedHoleMode mode = NEVER_RETURN_HOLE) | 
| +      : bit_field_(0) { | 
| +    bit_field_ = ElementsKindField::encode(elements_kind) | | 
| +        HoleModeField::encode(mode); | 
| + | 
| +    SetOperandAt(0, obj); | 
| +    SetOperandAt(1, key); | 
| +    SetOperandAt(2, dependency != NULL ? dependency : obj); | 
| + | 
| +    if (!is_external()) { | 
| +      // I can detect the case between storing double (holey and fast) and | 
| +      // smi/object by looking at elements_kind_. | 
| +      ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || | 
| +             IsFastDoubleElementsKind(elements_kind)); | 
| + | 
| +      if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 
| +        if (IsFastSmiElementsKind(elements_kind) && | 
| +            (!IsHoleyElementsKind(elements_kind) || | 
| +             mode == NEVER_RETURN_HOLE)) { | 
| +          set_type(HType::Smi()); | 
| +          set_representation(Representation::Smi()); | 
| +        } else { | 
| +          set_representation(Representation::Tagged()); | 
| +        } | 
| + | 
| +        SetGVNFlag(kDependsOnArrayElements); | 
| +      } else { | 
| +        set_representation(Representation::Double()); | 
| +        SetGVNFlag(kDependsOnDoubleArrayElements); | 
| +      } | 
| +    } else { | 
| +      if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 
| +          elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 
| +        set_representation(Representation::Double()); | 
| +      } else { | 
| +        set_representation(Representation::Integer32()); | 
| +      } | 
|  | 
| - protected: | 
| -  virtual bool DataEquals(HValue* other) { | 
| -    if (!other->IsLoadKeyed()) return false; | 
| -    HLoadKeyed* other_load = HLoadKeyed::cast(other); | 
| +      SetGVNFlag(kDependsOnExternalMemory); | 
| +      // Native code could change the specialized array. | 
| +      SetGVNFlag(kDependsOnCalls); | 
| +    } | 
|  | 
| -    if (IsDehoisted() && index_offset() != other_load->index_offset()) | 
| -      return false; | 
| -    return elements_kind() == other_load->elements_kind(); | 
| +    SetFlag(kUseGVN); | 
| } | 
|  | 
| - private: | 
| virtual bool IsDeletable() const { | 
| return !RequiresHoleCheck(); | 
| } | 
| @@ -6098,18 +6364,8 @@ class HLoadKeyedGeneric: public HTemplateInstruction<3> { | 
|  | 
| class HStoreNamedField: public HTemplateInstruction<2> { | 
| public: | 
| -  HStoreNamedField(HValue* obj, | 
| -                   HObjectAccess access, | 
| -                   HValue* val) | 
| -      : access_(access), | 
| -        transition_(), | 
| -        transition_unique_id_(), | 
| -        new_space_dominator_(NULL), | 
| -        write_barrier_mode_(UPDATE_WRITE_BARRIER) { | 
| -    SetOperandAt(0, obj); | 
| -    SetOperandAt(1, val); | 
| -    access.SetGVNFlags(this, true); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*, | 
| +                                 HObjectAccess, HValue*); | 
|  | 
| DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) | 
|  | 
| @@ -6179,6 +6435,19 @@ class HStoreNamedField: public HTemplateInstruction<2> { | 
| } | 
|  | 
| private: | 
| +  HStoreNamedField(HValue* obj, | 
| +                   HObjectAccess access, | 
| +                   HValue* val) | 
| +      : access_(access), | 
| +        transition_(), | 
| +        transition_unique_id_(), | 
| +        new_space_dominator_(NULL), | 
| +        write_barrier_mode_(UPDATE_WRITE_BARRIER) { | 
| +    SetOperandAt(0, obj); | 
| +    SetOperandAt(1, val); | 
| +    access.SetGVNFlags(this, true); | 
| +  } | 
| + | 
| HObjectAccess access_; | 
| Handle<Map> transition_; | 
| UniqueValueId transition_unique_id_; | 
| @@ -6225,38 +6494,8 @@ class HStoreNamedGeneric: public HTemplateInstruction<3> { | 
| class HStoreKeyed | 
| : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 
| public: | 
| -  HStoreKeyed(HValue* obj, HValue* key, HValue* val, | 
| -              ElementsKind elements_kind) | 
| -      : elements_kind_(elements_kind), | 
| -      index_offset_(0), | 
| -      is_dehoisted_(false), | 
| -      is_uninitialized_(false), | 
| -      new_space_dominator_(NULL) { | 
| -    SetOperandAt(0, obj); | 
| -    SetOperandAt(1, key); | 
| -    SetOperandAt(2, val); | 
| - | 
| -    if (IsFastObjectElementsKind(elements_kind)) { | 
| -      SetFlag(kTrackSideEffectDominators); | 
| -      SetGVNFlag(kDependsOnNewSpacePromotion); | 
| -    } | 
| -    if (is_external()) { | 
| -      SetGVNFlag(kChangesExternalMemory); | 
| -      SetFlag(kAllowUndefinedAsNaN); | 
| -    } else if (IsFastDoubleElementsKind(elements_kind)) { | 
| -      SetGVNFlag(kChangesDoubleArrayElements); | 
| -    } else if (IsFastSmiElementsKind(elements_kind)) { | 
| -      SetGVNFlag(kChangesArrayElements); | 
| -    } else { | 
| -      SetGVNFlag(kChangesArrayElements); | 
| -    } | 
| - | 
| -    // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | 
| -    if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && | 
| -        elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { | 
| -      SetFlag(kTruncatingToInt32); | 
| -    } | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P4(HStoreKeyed, HValue*, HValue*, HValue*, | 
| +                                 ElementsKind); | 
|  | 
| virtual bool HasEscapingOperandAt(int index) { return index != 0; } | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| @@ -6353,6 +6592,39 @@ class HStoreKeyed | 
| DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) | 
|  | 
| private: | 
| +  HStoreKeyed(HValue* obj, HValue* key, HValue* val, | 
| +              ElementsKind elements_kind) | 
| +      : elements_kind_(elements_kind), | 
| +      index_offset_(0), | 
| +      is_dehoisted_(false), | 
| +      is_uninitialized_(false), | 
| +      new_space_dominator_(NULL) { | 
| +    SetOperandAt(0, obj); | 
| +    SetOperandAt(1, key); | 
| +    SetOperandAt(2, val); | 
| + | 
| +    if (IsFastObjectElementsKind(elements_kind)) { | 
| +      SetFlag(kTrackSideEffectDominators); | 
| +      SetGVNFlag(kDependsOnNewSpacePromotion); | 
| +    } | 
| +    if (is_external()) { | 
| +      SetGVNFlag(kChangesExternalMemory); | 
| +      SetFlag(kAllowUndefinedAsNaN); | 
| +    } else if (IsFastDoubleElementsKind(elements_kind)) { | 
| +      SetGVNFlag(kChangesDoubleArrayElements); | 
| +    } else if (IsFastSmiElementsKind(elements_kind)) { | 
| +      SetGVNFlag(kChangesArrayElements); | 
| +    } else { | 
| +      SetGVNFlag(kChangesArrayElements); | 
| +    } | 
| + | 
| +    // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | 
| +    if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && | 
| +        elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { | 
| +      SetFlag(kTruncatingToInt32); | 
| +    } | 
| +  } | 
| + | 
| ElementsKind elements_kind_; | 
| uint32_t index_offset_; | 
| bool is_dehoisted_ : 1; | 
| @@ -6398,29 +6670,13 @@ class HStoreKeyedGeneric: public HTemplateInstruction<4> { | 
|  | 
| class HTransitionElementsKind: public HTemplateInstruction<2> { | 
| public: | 
| -  HTransitionElementsKind(HValue* context, | 
| -                          HValue* object, | 
| -                          Handle<Map> original_map, | 
| -                          Handle<Map> transitioned_map) | 
| -      : original_map_(original_map), | 
| -        transitioned_map_(transitioned_map), | 
| -        original_map_unique_id_(), | 
| -        transitioned_map_unique_id_(), | 
| -        from_kind_(original_map->elements_kind()), | 
| -        to_kind_(transitioned_map->elements_kind()) { | 
| -    SetOperandAt(0, object); | 
| -    SetOperandAt(1, context); | 
| -    SetFlag(kUseGVN); | 
| -    SetGVNFlag(kChangesElementsKind); | 
| -    if (original_map->has_fast_double_elements()) { | 
| -      SetGVNFlag(kChangesElementsPointer); | 
| -      SetGVNFlag(kChangesNewSpacePromotion); | 
| -    } | 
| -    if (transitioned_map->has_fast_double_elements()) { | 
| -      SetGVNFlag(kChangesElementsPointer); | 
| -      SetGVNFlag(kChangesNewSpacePromotion); | 
| -    } | 
| -    set_representation(Representation::Tagged()); | 
| +  inline static HTransitionElementsKind* New(Zone* zone, | 
| +                                             HValue* context, | 
| +                                             HValue* object, | 
| +                                             Handle<Map> original_map, | 
| +                                             Handle<Map> transitioned_map) { | 
| +    return new(zone) HTransitionElementsKind(context, object, | 
| +                                             original_map, transitioned_map); | 
| } | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| @@ -6451,6 +6707,31 @@ class HTransitionElementsKind: public HTemplateInstruction<2> { | 
| } | 
|  | 
| private: | 
| +  HTransitionElementsKind(HValue* context, | 
| +                          HValue* object, | 
| +                          Handle<Map> original_map, | 
| +                          Handle<Map> transitioned_map) | 
| +      : original_map_(original_map), | 
| +        transitioned_map_(transitioned_map), | 
| +        original_map_unique_id_(), | 
| +        transitioned_map_unique_id_(), | 
| +        from_kind_(original_map->elements_kind()), | 
| +        to_kind_(transitioned_map->elements_kind()) { | 
| +    SetOperandAt(0, object); | 
| +    SetOperandAt(1, context); | 
| +    SetFlag(kUseGVN); | 
| +    SetGVNFlag(kChangesElementsKind); | 
| +    if (original_map->has_fast_double_elements()) { | 
| +      SetGVNFlag(kChangesElementsPointer); | 
| +      SetGVNFlag(kChangesNewSpacePromotion); | 
| +    } | 
| +    if (transitioned_map->has_fast_double_elements()) { | 
| +      SetGVNFlag(kChangesElementsPointer); | 
| +      SetGVNFlag(kChangesNewSpacePromotion); | 
| +    } | 
| +    set_representation(Representation::Tagged()); | 
| +  } | 
| + | 
| Handle<Map> original_map_; | 
| Handle<Map> transitioned_map_; | 
| UniqueValueId original_map_unique_id_; | 
| @@ -6498,14 +6779,11 @@ class HStringAdd: public HBinaryOperation { | 
|  | 
| class HStringCharCodeAt: public HTemplateInstruction<3> { | 
| public: | 
| -  HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { | 
| -    SetOperandAt(0, context); | 
| -    SetOperandAt(1, string); | 
| -    SetOperandAt(2, index); | 
| -    set_representation(Representation::Integer32()); | 
| -    SetFlag(kUseGVN); | 
| -    SetGVNFlag(kDependsOnMaps); | 
| -    SetGVNFlag(kChangesNewSpacePromotion); | 
| +  static HStringCharCodeAt* New(Zone* zone, | 
| +                                HValue* context, | 
| +                                HValue* string, | 
| +                                HValue* index) { | 
| +    return new(zone) HStringCharCodeAt(context, string, index); | 
| } | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| @@ -6529,6 +6807,16 @@ class HStringCharCodeAt: public HTemplateInstruction<3> { | 
| } | 
|  | 
| private: | 
| +  HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { | 
| +    SetOperandAt(0, context); | 
| +    SetOperandAt(1, string); | 
| +    SetOperandAt(2, index); | 
| +    set_representation(Representation::Integer32()); | 
| +    SetFlag(kUseGVN); | 
| +    SetGVNFlag(kDependsOnMaps); | 
| +    SetGVNFlag(kChangesNewSpacePromotion); | 
| +  } | 
| + | 
| // No side effects: runtime function assumes string + number inputs. | 
| virtual bool IsDeletable() const { return true; } | 
| }; | 
| @@ -6571,7 +6859,7 @@ class HStringCharFromCode: public HTemplateInstruction<2> { | 
|  | 
| class HStringLength: public HUnaryOperation { | 
| public: | 
| -  static HInstruction* New(Zone* zone, HValue* string); | 
| +  static HInstruction* New(Zone* zone, HValue* context, HValue* string); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| @@ -6729,9 +7017,7 @@ class HTypeof: public HTemplateInstruction<2> { | 
|  | 
| class HTrapAllocationMemento : public HTemplateInstruction<1> { | 
| public: | 
| -  explicit HTrapAllocationMemento(HValue* obj) { | 
| -    SetOperandAt(0, obj); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HTrapAllocationMemento, HValue*); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| @@ -6740,11 +7026,25 @@ class HTrapAllocationMemento : public HTemplateInstruction<1> { | 
| HValue* object() { return OperandAt(0); } | 
|  | 
| DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento) | 
| + | 
| + private: | 
| +  explicit HTrapAllocationMemento(HValue* obj) { | 
| +    SetOperandAt(0, obj); | 
| +  } | 
| }; | 
|  | 
|  | 
| class HToFastProperties: public HUnaryOperation { | 
| public: | 
| +  DECLARE_INSTRUCTION_FACTORY_P1(HToFastProperties, HValue*); | 
| + | 
| +  virtual Representation RequiredInputRepresentation(int index) { | 
| +    return Representation::Tagged(); | 
| +  } | 
| + | 
| +  DECLARE_CONCRETE_INSTRUCTION(ToFastProperties) | 
| + | 
| + private: | 
| explicit HToFastProperties(HValue* value) : HUnaryOperation(value) { | 
| // This instruction is not marked as having side effects, but | 
| // changes the map of the input operand. Use it only when creating | 
| @@ -6758,13 +7058,6 @@ class HToFastProperties: public HUnaryOperation { | 
| set_representation(Representation::Tagged()); | 
| } | 
|  | 
| -  virtual Representation RequiredInputRepresentation(int index) { | 
| -    return Representation::Tagged(); | 
| -  } | 
| - | 
| -  DECLARE_CONCRETE_INSTRUCTION(ToFastProperties) | 
| - | 
| - private: | 
| virtual bool IsDeletable() const { return true; } | 
| }; | 
|  | 
| @@ -6837,15 +7130,7 @@ class HSeqStringSetChar: public HTemplateInstruction<3> { | 
|  | 
| class HCheckMapValue: public HTemplateInstruction<2> { | 
| public: | 
| -  HCheckMapValue(HValue* value, | 
| -                 HValue* map) { | 
| -    SetOperandAt(0, value); | 
| -    SetOperandAt(1, map); | 
| -    set_representation(Representation::Tagged()); | 
| -    SetFlag(kUseGVN); | 
| -    SetGVNFlag(kDependsOnMaps); | 
| -    SetGVNFlag(kDependsOnElementsKind); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P2(HCheckMapValue, HValue*, HValue*); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| @@ -6866,17 +7151,26 @@ class HCheckMapValue: public HTemplateInstruction<2> { | 
| virtual bool DataEquals(HValue* other) { | 
| return true; | 
| } | 
| + | 
| + private: | 
| +  HCheckMapValue(HValue* value, | 
| +                 HValue* map) { | 
| +    SetOperandAt(0, value); | 
| +    SetOperandAt(1, map); | 
| +    set_representation(Representation::Tagged()); | 
| +    SetFlag(kUseGVN); | 
| +    SetGVNFlag(kDependsOnMaps); | 
| +    SetGVNFlag(kDependsOnElementsKind); | 
| +  } | 
| }; | 
|  | 
|  | 
| class HForInPrepareMap : public HTemplateInstruction<2> { | 
| public: | 
| -  HForInPrepareMap(HValue* context, | 
| -                   HValue* object) { | 
| -    SetOperandAt(0, context); | 
| -    SetOperandAt(1, object); | 
| -    set_representation(Representation::Tagged()); | 
| -    SetAllSideEffects(); | 
| +  static HForInPrepareMap* New(Zone* zone, | 
| +                               HValue* context, | 
| +                               HValue* object) { | 
| +    return new(zone) HForInPrepareMap(context, object); | 
| } | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| @@ -6893,18 +7187,21 @@ class HForInPrepareMap : public HTemplateInstruction<2> { | 
| } | 
|  | 
| DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap); | 
| + | 
| + private: | 
| +  HForInPrepareMap(HValue* context, | 
| +                   HValue* object) { | 
| +    SetOperandAt(0, context); | 
| +    SetOperandAt(1, object); | 
| +    set_representation(Representation::Tagged()); | 
| +    SetAllSideEffects(); | 
| +  } | 
| }; | 
|  | 
|  | 
| class HForInCacheArray : public HTemplateInstruction<2> { | 
| public: | 
| -  HForInCacheArray(HValue* enumerable, | 
| -                   HValue* keys, | 
| -                   int idx) : idx_(idx) { | 
| -    SetOperandAt(0, enumerable); | 
| -    SetOperandAt(1, keys); | 
| -    set_representation(Representation::Tagged()); | 
| -  } | 
| +  DECLARE_INSTRUCTION_FACTORY_P3(HForInCacheArray, HValue*, HValue*, int); | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| return Representation::Tagged(); | 
| @@ -6931,6 +7228,14 @@ class HForInCacheArray : public HTemplateInstruction<2> { | 
| DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray); | 
|  | 
| private: | 
| +  HForInCacheArray(HValue* enumerable, | 
| +                   HValue* keys, | 
| +                   int idx) : idx_(idx) { | 
| +    SetOperandAt(0, enumerable); | 
| +    SetOperandAt(1, keys); | 
| +    set_representation(Representation::Tagged()); | 
| +  } | 
| + | 
| int idx_; | 
| HForInCacheArray* index_cache_; | 
| }; | 
|  |