| 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_;
|
| };
|
|
|