Chromium Code Reviews| Index: src/hydrogen-instructions.h |
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h |
| index e71b7cdf41a1b483e22320eecddd5a569fe0a541..e1f5c75b858ee1c6d278c96902ae6291632a2dec 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, \ |
|
Toon Verwaest
2013/07/31 12:56:37
Weird indentation.
danno
2013/07/31 14:10:09
Done.
|
| + 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, \ |
|
Toon Verwaest
2013/07/31 12:56:37
Weird indentation.
danno
2013/07/31 14:10:09
Done.
|
| + 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_; } |
| @@ -1517,7 +1559,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(); |
| @@ -1528,6 +1570,8 @@ class HDeoptimize: public HTemplateInstruction<0> { |
| DECLARE_CONCRETE_INSTRUCTION(Deoptimize) |
| private: |
| + explicit HDeoptimize(Deoptimizer::BailoutType type) : type_(type) {} |
| + |
| Deoptimizer::BailoutType type_; |
| }; |
| @@ -1628,12 +1672,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) { |
| @@ -1647,6 +1723,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); |
| + } |
| }; |
| @@ -1677,10 +1760,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) { |
| @@ -1691,27 +1774,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); } |
| @@ -1724,6 +1814,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); |
| + } |
| }; |
| @@ -1785,12 +1881,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(); |
| @@ -1802,6 +1893,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; } |
| }; |
| @@ -1958,10 +2056,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); } |
| @@ -1983,6 +2078,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_; |
| }; |
| @@ -2069,9 +2169,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(); |
| @@ -2080,6 +2178,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()); |
| + } |
| }; |
| @@ -2104,44 +2207,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; } |
| }; |
| @@ -2158,6 +2242,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_; } |
| @@ -2167,6 +2258,7 @@ class HDeclareGlobals: public HUnaryOperation { |
| virtual Representation RequiredInputRepresentation(int index) { |
| return Representation::Tagged(); |
| } |
| + |
| private: |
| Handle<FixedArray> pairs_; |
| int flags_; |
| @@ -2180,6 +2272,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) { |
| @@ -2196,11 +2292,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) |
| @@ -2212,6 +2304,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; } |
| }; |
| @@ -2278,6 +2376,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, |
| @@ -2288,6 +2393,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(); |
| } |
| @@ -2379,6 +2493,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(); } |
| @@ -2396,6 +2517,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(); } |
| @@ -2479,12 +2607,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); |
| @@ -2500,6 +2628,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_; |
| }; |
| @@ -2507,12 +2643,7 @@ class HCallRuntime: public HCall<1> { |
| class HMapEnumLength: public HUnaryOperation { |
| public: |
| - explicit HMapEnumLength(HValue* value) : HUnaryOperation(value) { |
| - set_type(HType::Smi()); |
| - set_representation(Representation::Smi()); |
| - SetFlag(kUseGVN); |
| - SetGVNFlag(kDependsOnMaps); |
| - } |
| + DECLARE_INSTRUCTION_FACTORY_P1(HMapEnumLength, HValue*); |
| virtual Representation RequiredInputRepresentation(int index) { |
| return Representation::Tagged(); |
| @@ -2524,6 +2655,13 @@ class HMapEnumLength: public HUnaryOperation { |
| virtual bool DataEquals(HValue* other) { return true; } |
| private: |
| + explicit HMapEnumLength(HValue* value) : HUnaryOperation(value) { |
| + set_type(HType::Smi()); |
| + set_representation(Representation::Smi()); |
| + SetFlag(kUseGVN); |
| + SetGVNFlag(kDependsOnMaps); |
| + } |
| + |
| virtual bool IsDeletable() const { return true; } |
| }; |
| @@ -2552,12 +2690,7 @@ class HElementsKind: public HUnaryOperation { |
| class HBitNot: public HUnaryOperation { |
| public: |
| - explicit HBitNot(HValue* value) : HUnaryOperation(value) { |
| - set_representation(Representation::Integer32()); |
| - SetFlag(kUseGVN); |
| - SetFlag(kTruncatingToInt32); |
| - SetFlag(kAllowUndefinedAsNaN); |
| - } |
| + DECLARE_INSTRUCTION_FACTORY_P1(HBitNot, HValue*); |
| virtual Representation RequiredInputRepresentation(int index) { |
| return Representation::Integer32(); |
| @@ -2575,6 +2708,13 @@ class HBitNot: public HUnaryOperation { |
| virtual bool DataEquals(HValue* other) { return true; } |
| private: |
| + explicit HBitNot(HValue* value) : HUnaryOperation(value) { |
| + set_representation(Representation::Integer32()); |
| + SetFlag(kUseGVN); |
| + SetFlag(kTruncatingToInt32); |
| + SetFlag(kAllowUndefinedAsNaN); |
| + } |
| + |
| virtual bool IsDeletable() const { return true; } |
| }; |
| @@ -2681,15 +2821,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(); |
| @@ -2705,6 +2837,16 @@ class HLoadExternalArrayPointer: public HUnaryOperation { |
| virtual bool DataEquals(HValue* other) { return true; } |
| private: |
| + 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; } |
| }; |
| @@ -2792,12 +2934,7 @@ class HCheckMaps: public HTemplateInstruction<2> { |
| class HCheckFunction: public HUnaryOperation { |
| public: |
| - HCheckFunction(HValue* value, Handle<JSFunction> function) |
| - : HUnaryOperation(value), 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(); |
| @@ -2827,6 +2964,13 @@ class HCheckFunction: public HUnaryOperation { |
| } |
| private: |
| + HCheckFunction(HValue* value, Handle<JSFunction> function) |
| + : HUnaryOperation(value), 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_; |
| @@ -2895,10 +3039,7 @@ class HCheckInstanceType: public HUnaryOperation { |
| class HCheckSmi: public HUnaryOperation { |
| public: |
| - explicit HCheckSmi(HValue* value) : HUnaryOperation(value) { |
| - set_representation(Representation::Smi()); |
| - SetFlag(kUseGVN); |
| - } |
| + DECLARE_INSTRUCTION_FACTORY_P1(HCheckSmi, HValue*); |
| virtual Representation RequiredInputRepresentation(int index) { |
| return Representation::Tagged(); |
| @@ -2918,6 +3059,12 @@ class HCheckSmi: public HUnaryOperation { |
| protected: |
| virtual bool DataEquals(HValue* other) { return true; } |
| + |
| + private: |
| + explicit HCheckSmi(HValue* value) : HUnaryOperation(value) { |
| + set_representation(Representation::Smi()); |
| + SetFlag(kUseGVN); |
| + } |
| }; |
| @@ -2938,10 +3085,7 @@ class HIsNumberAndBranch: public HUnaryControlInstruction { |
| class HCheckHeapObject: public HUnaryOperation { |
| public: |
| - explicit HCheckHeapObject(HValue* value) : HUnaryOperation(value) { |
| - set_representation(Representation::Tagged()); |
| - SetFlag(kUseGVN); |
| - } |
| + DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*); |
| virtual Representation RequiredInputRepresentation(int index) { |
| return Representation::Tagged(); |
| @@ -2961,40 +3105,23 @@ class HCheckHeapObject: public HUnaryOperation { |
| protected: |
| virtual bool DataEquals(HValue* other) { return true; } |
| + |
| + private: |
| + explicit HCheckHeapObject(HValue* value) : HUnaryOperation(value) { |
| + 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_; } |
| @@ -3029,6 +3156,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_; |
| @@ -3430,9 +3588,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_; } |
| @@ -3459,6 +3618,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_; |
| @@ -3467,24 +3631,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()) { |
| @@ -3665,6 +3815,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; } |
| @@ -3782,11 +3952,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(); |
| @@ -3800,6 +3966,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); |
| + } |
| }; |
| @@ -3835,12 +4008,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) |
| @@ -3854,6 +4022,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_; |
| @@ -3862,10 +4037,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(); |
| @@ -3877,6 +4049,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; } |
| }; |
| @@ -3915,23 +4092,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_; } |
| @@ -4001,6 +4166,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; |
| } |
| @@ -4098,15 +4278,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); |
| @@ -4121,6 +4297,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; } |
| }; |
| @@ -4225,11 +4412,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.lithium |
|
Toon Verwaest
2013/07/31 12:56:37
Left-over "lithium" at the end of the sentence.
danno
2013/07/31 14:10:09
Done.
|
| + 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); } |
| @@ -4519,7 +4711,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); } |
| @@ -4856,8 +5051,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); |
| @@ -4879,7 +5074,7 @@ 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), op_(op) { |
| ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); |
| // BIT_AND with a smi-range positive value will always unset the |
| @@ -5041,10 +5236,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_; } |
| @@ -5055,6 +5247,11 @@ class HOsrEntry: public HTemplateInstruction<0> { |
| DECLARE_CONCRETE_INSTRUCTION(OsrEntry) |
| private: |
| + explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { |
| + SetGVNFlag(kChangesOsrEntries); |
| + SetGVNFlag(kChangesNewSpacePromotion); |
| + } |
| + |
| BailoutId ast_id_; |
| }; |
| @@ -5066,6 +5263,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), |
| @@ -5081,18 +5295,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_; |
| }; |
| @@ -5133,10 +5335,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(); |
| @@ -5158,6 +5357,11 @@ class HUnknownOSRValue: public HTemplateInstruction<0> { |
| DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue) |
| private: |
| + HUnknownOSRValue() |
| + : incoming_value_(NULL) { |
| + set_representation(Representation::Tagged()); |
| + } |
| + |
| HPhi* incoming_value_; |
| }; |
| @@ -5248,15 +5452,12 @@ class HAllocate: public HTemplateInstruction<2> { |
| PREFILL_WITH_FILLER = 1 << 4 |
| }; |
| - HAllocate(HValue* context, HValue* size, HType type, Flags flags) |
| - : flags_(flags) { |
| - SetOperandAt(0, context); |
| - SetOperandAt(1, size); |
| - set_type(type); |
| - set_representation(Representation::Tagged()); |
| - SetFlag(kTrackSideEffectDominators); |
| - SetGVNFlag(kChangesNewSpacePromotion); |
| - SetGVNFlag(kDependsOnNewSpacePromotion); |
| + static HAllocate* New(Zone* zone, |
| + HValue* context, |
| + HValue* size, |
| + HType type, |
| + Flags flags) { |
| + return new(zone) HAllocate(context, size, type, flags); |
| } |
| // Maximum instance size for which allocations will be inlined. |
| @@ -5339,19 +5540,30 @@ class HAllocate: public HTemplateInstruction<2> { |
| DECLARE_CONCRETE_INSTRUCTION(Allocate) |
| private: |
| - Flags flags_; |
| - Handle<Map> known_initial_map_; |
| -}; |
| - |
| - |
| -class HInnerAllocatedObject: public HTemplateInstruction<1> { |
| - public: |
| - HInnerAllocatedObject(HValue* value, int offset, HType type = HType::Tagged()) |
| - : offset_(offset) { |
| - ASSERT(value->IsAllocate()); |
| - SetOperandAt(0, value); |
| + HAllocate(HValue* context, HValue* size, HType type, Flags flags) |
| + : flags_(flags) { |
| + SetOperandAt(0, context); |
| + SetOperandAt(1, size); |
| set_type(type); |
| set_representation(Representation::Tagged()); |
| + SetFlag(kTrackSideEffectDominators); |
| + SetGVNFlag(kChangesNewSpacePromotion); |
| + SetGVNFlag(kDependsOnNewSpacePromotion); |
| + } |
| + |
| + Flags flags_; |
| + Handle<Map> known_initial_map_; |
| +}; |
| + |
| + |
| +class HInnerAllocatedObject: public HTemplateInstruction<1> { |
| + public: |
| + 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); } |
| @@ -5366,6 +5578,14 @@ class HInnerAllocatedObject: public HTemplateInstruction<1> { |
| DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject) |
| private: |
| + HInnerAllocatedObject(HValue* value, int offset, HType type = HType::Tagged()) |
| + : offset_(offset) { |
| + ASSERT(value->IsAllocate()); |
| + SetOperandAt(0, value); |
| + set_type(type); |
| + set_representation(Representation::Tagged()); |
| + } |
| + |
| int offset_; |
| }; |
| @@ -5397,14 +5617,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() { |
| @@ -5422,6 +5636,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_; |
| }; |
| @@ -5429,18 +5652,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); } |
| @@ -5458,6 +5677,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_; |
| }; |
| @@ -5545,12 +5778,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); } |
| @@ -5578,6 +5807,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_; |
| }; |
| @@ -5750,13 +5986,8 @@ class HLinkObjectInList: public HUnaryOperation { |
| ALLOCATION_SITE_LIST |
| }; |
| - HLinkObjectInList(HValue* object, HObjectAccess store_field, |
| - KnownList known_list) |
| - : HUnaryOperation(object), |
| - store_field_(store_field), |
| - known_list_(known_list) { |
| - set_representation(Representation::Tagged()); |
| - } |
| + DECLARE_INSTRUCTION_FACTORY_P3(HLinkObjectInList, HValue*, |
| + HObjectAccess, KnownList); |
| HObjectAccess store_field() const { return store_field_; } |
| KnownList known_list() const { return known_list_; } |
| @@ -5770,6 +6001,14 @@ class HLinkObjectInList: public HUnaryOperation { |
| DECLARE_CONCRETE_INSTRUCTION(LinkObjectInList) |
| private: |
| + HLinkObjectInList(HValue* object, HObjectAccess store_field, |
| + KnownList known_list) |
| + : HUnaryOperation(object), |
| + store_field_(store_field), |
| + known_list_(known_list) { |
| + set_representation(Representation::Tagged()); |
| + } |
| + |
| HObjectAccess store_field_; |
| KnownList known_list_; |
| }; |
| @@ -5777,31 +6016,9 @@ class HLinkObjectInList: public HUnaryOperation { |
| 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() { |
| @@ -5834,6 +6051,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_; |
| @@ -5952,55 +6195,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()); |
| @@ -6069,6 +6267,56 @@ class HLoadKeyed |
| } |
| 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()); |
| + } |
| + |
| + SetGVNFlag(kDependsOnExternalMemory); |
| + // Native code could change the specialized array. |
| + SetGVNFlag(kDependsOnCalls); |
| + } |
| + |
| + SetFlag(kUseGVN); |
| + } |
| + |
| virtual bool IsDeletable() const { |
| return !RequiresHoleCheck(); |
| } |
| @@ -6134,18 +6382,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) |
| @@ -6214,6 +6452,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_; |
| @@ -6260,38 +6511,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) { |
| @@ -6388,6 +6609,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; |
| @@ -6433,29 +6687,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) { |
| @@ -6486,6 +6724,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_; |
| @@ -6537,14 +6800,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) { |
| @@ -6568,6 +6828,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; } |
| }; |
| @@ -6610,7 +6880,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(); |
| @@ -6771,9 +7041,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(); |
| @@ -6782,11 +7050,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 |
| @@ -6800,13 +7082,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; } |
| }; |
| @@ -6879,15 +7154,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(); |
| @@ -6908,17 +7175,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) { |
| @@ -6935,18 +7211,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(); |
| @@ -6973,6 +7252,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_; |
| }; |