| Index: src/hydrogen-instructions.h
|
| ===================================================================
|
| --- src/hydrogen-instructions.h (revision 7031)
|
| +++ src/hydrogen-instructions.h (working copy)
|
| @@ -48,16 +48,13 @@
|
|
|
| #define HYDROGEN_ALL_INSTRUCTION_LIST(V) \
|
| V(ArithmeticBinaryOperation) \
|
| + V(BinaryCall) \
|
| V(BinaryOperation) \
|
| V(BitwiseBinaryOperation) \
|
| - V(Call) \
|
| V(ControlInstruction) \
|
| V(Instruction) \
|
| - V(LoadKeyed) \
|
| - V(MaterializedLiteral) \
|
| V(Phi) \
|
| - V(StoreKeyed) \
|
| - V(StoreNamed) \
|
| + V(UnaryCall) \
|
| V(UnaryControlInstruction) \
|
| V(UnaryOperation) \
|
| HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
|
| @@ -105,6 +102,7 @@
|
| V(EnterInlined) \
|
| V(FixedArrayLength) \
|
| V(FunctionLiteral) \
|
| + V(GetCachedArrayIndex) \
|
| V(GlobalObject) \
|
| V(GlobalReceiver) \
|
| V(Goto) \
|
| @@ -127,12 +125,15 @@
|
| V(LoadKeyedGeneric) \
|
| V(LoadNamedField) \
|
| V(LoadNamedGeneric) \
|
| + V(LoadPixelArrayElement) \
|
| + V(LoadPixelArrayExternalPointer) \
|
| V(Mod) \
|
| V(Mul) \
|
| V(ObjectLiteral) \
|
| V(OsrEntry) \
|
| V(OuterContext) \
|
| V(Parameter) \
|
| + V(PixelArrayLength) \
|
| V(Power) \
|
| V(PushArgument) \
|
| V(RegExpLiteral) \
|
| @@ -145,6 +146,7 @@
|
| V(StoreContextSlot) \
|
| V(StoreGlobal) \
|
| V(StoreKeyedFastElement) \
|
| + V(StorePixelArrayElement) \
|
| V(StoreKeyedGeneric) \
|
| V(StoreNamedField) \
|
| V(StoreNamedGeneric) \
|
| @@ -164,6 +166,7 @@
|
| V(InobjectFields) \
|
| V(BackingStoreFields) \
|
| V(ArrayElements) \
|
| + V(PixelArrayElements) \
|
| V(GlobalVars) \
|
| V(Maps) \
|
| V(ArrayLengths) \
|
| @@ -185,14 +188,6 @@
|
| DECLARE_INSTRUCTION(type)
|
|
|
|
|
| -
|
| -template<int kSize>
|
| -class HOperandVector : public EmbeddedVector<HValue*, kSize> {
|
| - public:
|
| - HOperandVector() : EmbeddedVector<HValue*, kSize>(NULL) { }
|
| -};
|
| -
|
| -
|
| class Range: public ZoneObject {
|
| public:
|
| Range() : lower_(kMinInt),
|
| @@ -289,6 +284,7 @@
|
| kTagged,
|
| kDouble,
|
| kInteger32,
|
| + kExternal,
|
| kNumRepresentations
|
| };
|
|
|
| @@ -298,8 +294,9 @@
|
| static Representation Tagged() { return Representation(kTagged); }
|
| static Representation Integer32() { return Representation(kInteger32); }
|
| static Representation Double() { return Representation(kDouble); }
|
| + static Representation External() { return Representation(kExternal); }
|
|
|
| - bool Equals(const Representation& other) const {
|
| + bool Equals(const Representation& other) {
|
| return kind_ == other.kind_;
|
| }
|
|
|
| @@ -308,6 +305,7 @@
|
| bool IsTagged() const { return kind_ == kTagged; }
|
| bool IsInteger32() const { return kind_ == kInteger32; }
|
| bool IsDouble() const { return kind_ == kDouble; }
|
| + bool IsExternal() const { return kind_ == kExternal; }
|
| bool IsSpecialization() const {
|
| return kind_ == kInteger32 || kind_ == kDouble;
|
| }
|
| @@ -533,15 +531,12 @@
|
| bool IsDefinedAfter(HBasicBlock* other) const;
|
|
|
| // Operands.
|
| - virtual int OperandCount() const { return 0; }
|
| - virtual HValue* OperandAt(int index) const {
|
| - UNREACHABLE();
|
| - return NULL;
|
| - }
|
| + virtual int OperandCount() = 0;
|
| + virtual HValue* OperandAt(int index) = 0;
|
| void SetOperandAt(int index, HValue* value);
|
|
|
| - int LookupOperandIndex(int occurrence_index, HValue* op) const;
|
| - bool UsesMultipleTimes(HValue* op) const;
|
| + int LookupOperandIndex(int occurrence_index, HValue* op);
|
| + bool UsesMultipleTimes(HValue* op);
|
|
|
| void ReplaceAndDelete(HValue* other);
|
| void ReplaceValue(HValue* other);
|
| @@ -567,10 +562,9 @@
|
| void ComputeInitialRange();
|
|
|
| // Representation helpers.
|
| - virtual Representation RequiredInputRepresentation(int index) const {
|
| - return Representation::None();
|
| - }
|
| - virtual Representation InferredRepresentation() const {
|
| + virtual Representation RequiredInputRepresentation(int index) const = 0;
|
| +
|
| + virtual Representation InferredRepresentation() {
|
| return representation();
|
| }
|
|
|
| @@ -585,11 +579,11 @@
|
| HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
|
| #undef DECLARE_DO
|
|
|
| - bool Equals(HValue* other) const;
|
| - virtual intptr_t Hashcode() const;
|
| + bool Equals(HValue* other);
|
| + virtual intptr_t Hashcode();
|
|
|
| // Printing support.
|
| - virtual void PrintTo(StringStream* stream) const = 0;
|
| + virtual void PrintTo(StringStream* stream) = 0;
|
| void PrintNameTo(StringStream* stream);
|
| static void PrintTypeTo(HType type, StringStream* stream);
|
|
|
| @@ -600,11 +594,8 @@
|
| // it has changed.
|
| bool UpdateInferredType();
|
|
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
|
|
| - // Helper for type conversions used by normal and phi instructions.
|
| - void InsertInputConversion(HInstruction* previous, int index, HType type);
|
| -
|
| #ifdef DEBUG
|
| virtual void Verify() = 0;
|
| #endif
|
| @@ -612,14 +603,14 @@
|
| protected:
|
| // This function must be overridden for instructions with flag kUseGVN, to
|
| // compare the non-Operand parts of the instruction.
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| UNREACHABLE();
|
| return false;
|
| }
|
| virtual void RepresentationChanged(Representation to) { }
|
| virtual Range* InferRange();
|
| virtual void DeleteFromGraph() = 0;
|
| - virtual void InternalSetOperandAt(int index, HValue* value) { UNREACHABLE(); }
|
| + virtual void InternalSetOperandAt(int index, HValue* value) = 0;
|
| void clear_block() {
|
| ASSERT(block_ != NULL);
|
| block_ = NULL;
|
| @@ -661,8 +652,8 @@
|
| HInstruction* next() const { return next_; }
|
| HInstruction* previous() const { return previous_; }
|
|
|
| - void PrintTo(StringStream* stream) const;
|
| - virtual void PrintDataTo(StringStream* stream) const {}
|
| + virtual void PrintTo(StringStream* stream);
|
| + virtual void PrintDataTo(StringStream* stream) { }
|
|
|
| bool IsLinked() const { return block() != NULL; }
|
| void Unlink();
|
| @@ -683,6 +674,8 @@
|
| // instruction.
|
| virtual bool IsCheckInstruction() const { return false; }
|
|
|
| + virtual bool IsCall() { return false; }
|
| +
|
| DECLARE_INSTRUCTION(Instruction)
|
|
|
| protected:
|
| @@ -709,12 +702,6 @@
|
| };
|
|
|
|
|
| -class HBlockEntry: public HInstruction {
|
| - public:
|
| - DECLARE_CONCRETE_INSTRUCTION(BlockEntry, "block_entry")
|
| -};
|
| -
|
| -
|
| class HControlInstruction: public HInstruction {
|
| public:
|
| HControlInstruction(HBasicBlock* first, HBasicBlock* second)
|
| @@ -724,7 +711,7 @@
|
| HBasicBlock* FirstSuccessor() const { return first_successor_; }
|
| HBasicBlock* SecondSuccessor() const { return second_successor_; }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| DECLARE_INSTRUCTION(ControlInstruction)
|
|
|
| @@ -734,25 +721,101 @@
|
| };
|
|
|
|
|
| -class HDeoptimize: public HControlInstruction {
|
| +template<int NumElements>
|
| +class HOperandContainer {
|
| public:
|
| - HDeoptimize() : HControlInstruction(NULL, NULL) { }
|
| + HOperandContainer() : elems_() { }
|
|
|
| + int length() { return NumElements; }
|
| + HValue*& operator[](int i) {
|
| + ASSERT(i < length());
|
| + return elems_[i];
|
| + }
|
| +
|
| + private:
|
| + HValue* elems_[NumElements];
|
| +};
|
| +
|
| +
|
| +template<>
|
| +class HOperandContainer<0> {
|
| + public:
|
| + int length() { return 0; }
|
| + HValue*& operator[](int i) {
|
| + UNREACHABLE();
|
| + static HValue* t = 0;
|
| + return t;
|
| + }
|
| +};
|
| +
|
| +
|
| +template<int V>
|
| +class HTemplateInstruction : public HInstruction {
|
| + public:
|
| + int OperandCount() { return V; }
|
| + HValue* OperandAt(int i) { return inputs_[i]; }
|
| +
|
| + protected:
|
| + void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
|
| +
|
| + private:
|
| + HOperandContainer<V> inputs_;
|
| +};
|
| +
|
| +
|
| +template<int V>
|
| +class HTemplateControlInstruction : public HControlInstruction {
|
| + public:
|
| + HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
|
| + : HControlInstruction(first, second) { }
|
| + int OperandCount() { return V; }
|
| + HValue* OperandAt(int i) { return inputs_[i]; }
|
| +
|
| + protected:
|
| + void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
|
| +
|
| + private:
|
| + HOperandContainer<V> inputs_;
|
| +};
|
| +
|
| +
|
| +class HBlockEntry: public HTemplateInstruction<0> {
|
| + public:
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| + DECLARE_CONCRETE_INSTRUCTION(BlockEntry, "block_entry")
|
| +};
|
| +
|
| +
|
| +class HDeoptimize: public HTemplateControlInstruction<0> {
|
| + public:
|
| + HDeoptimize() : HTemplateControlInstruction<0>(NULL, NULL) { }
|
| +
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
|
| };
|
|
|
|
|
| -class HGoto: public HControlInstruction {
|
| +class HGoto: public HTemplateControlInstruction<0> {
|
| public:
|
| explicit HGoto(HBasicBlock* target)
|
| - : HControlInstruction(target, NULL), include_stack_check_(false) {
|
| - }
|
| + : HTemplateControlInstruction<0>(target, NULL),
|
| + include_stack_check_(false) { }
|
|
|
| void set_include_stack_check(bool include_stack_check) {
|
| include_stack_check_ = include_stack_check;
|
| }
|
| bool include_stack_check() const { return include_stack_check_; }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
|
|
|
| private:
|
| @@ -760,34 +823,20 @@
|
| };
|
|
|
|
|
| -class HUnaryControlInstruction: public HControlInstruction {
|
| +class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
|
| public:
|
| explicit HUnaryControlInstruction(HValue* value,
|
| HBasicBlock* true_target,
|
| HBasicBlock* false_target)
|
| - : HControlInstruction(true_target, false_target) {
|
| + : HTemplateControlInstruction<1>(true_target, false_target) {
|
| SetOperandAt(0, value);
|
| }
|
|
|
| - virtual Representation RequiredInputRepresentation(int index) const {
|
| - return Representation::Tagged();
|
| - }
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + HValue* value() { return OperandAt(0); }
|
|
|
| - HValue* value() const { return OperandAt(0); }
|
| - virtual int OperandCount() const { return 1; }
|
| - virtual HValue* OperandAt(int index) const { return operands_[index]; }
|
| -
|
| DECLARE_INSTRUCTION(UnaryControlInstruction)
|
| -
|
| - protected:
|
| - virtual void InternalSetOperandAt(int index, HValue* value) {
|
| - operands_[index] = value;
|
| - }
|
| -
|
| - private:
|
| - HOperandVector<1> operands_;
|
| };
|
|
|
|
|
| @@ -819,10 +868,14 @@
|
| ASSERT(!map.is_null());
|
| }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| Handle<Map> map() const { return map_; }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(CompareMap, "compare_map")
|
|
|
| private:
|
| @@ -836,38 +889,36 @@
|
| : HUnaryControlInstruction(value, NULL, NULL) {
|
| }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(Return, "return")
|
| };
|
|
|
|
|
| -class HAbnormalExit: public HControlInstruction {
|
| +class HAbnormalExit: public HTemplateControlInstruction<0> {
|
| public:
|
| - HAbnormalExit() : HControlInstruction(NULL, NULL) { }
|
| + HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(AbnormalExit, "abnormal_exit")
|
| };
|
|
|
|
|
| -class HUnaryOperation: public HInstruction {
|
| +class HUnaryOperation: public HTemplateInstruction<1> {
|
| public:
|
| explicit HUnaryOperation(HValue* value) {
|
| SetOperandAt(0, value);
|
| }
|
|
|
| - HValue* value() const { return OperandAt(0); }
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| - virtual int OperandCount() const { return 1; }
|
| - virtual HValue* OperandAt(int index) const { return operands_[index]; }
|
| + HValue* value() { return OperandAt(0); }
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| DECLARE_INSTRUCTION(UnaryOperation)
|
| -
|
| - protected:
|
| - virtual void InternalSetOperandAt(int index, HValue* value) {
|
| - operands_[index] = value;
|
| - }
|
| -
|
| - private:
|
| - HOperandVector<1> operands_;
|
| };
|
|
|
|
|
| @@ -917,13 +968,13 @@
|
| return true;
|
| }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(Change,
|
| CanTruncateToInt32() ? "truncate" : "change")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| if (!other->IsChange()) return false;
|
| HChange* change = HChange::cast(other);
|
| return value() == change->value()
|
| @@ -947,7 +998,7 @@
|
| assigned_indexes_(2) {}
|
| virtual ~HSimulate() {}
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
|
| int ast_id() const { return ast_id_; }
|
| @@ -972,9 +1023,13 @@
|
| void AddPushedValue(HValue* value) {
|
| AddValue(kNoIndex, value);
|
| }
|
| - virtual int OperandCount() const { return values_.length(); }
|
| - virtual HValue* OperandAt(int index) const { return values_[index]; }
|
| + virtual int OperandCount() { return values_.length(); }
|
| + virtual HValue* OperandAt(int index) { return values_[index]; }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(Simulate, "simulate")
|
|
|
| #ifdef DEBUG
|
| @@ -1004,25 +1059,33 @@
|
| };
|
|
|
|
|
| -class HStackCheck: public HInstruction {
|
| +class HStackCheck: public HTemplateInstruction<0> {
|
| public:
|
| HStackCheck() { }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack_check")
|
| };
|
|
|
|
|
| -class HEnterInlined: public HInstruction {
|
| +class HEnterInlined: public HTemplateInstruction<0> {
|
| public:
|
| HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
|
| : closure_(closure), function_(function) {
|
| }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| Handle<JSFunction> closure() const { return closure_; }
|
| FunctionLiteral* function() const { return function_; }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(EnterInlined, "enter_inlined")
|
|
|
| private:
|
| @@ -1031,18 +1094,21 @@
|
| };
|
|
|
|
|
| -class HLeaveInlined: public HInstruction {
|
| +class HLeaveInlined: public HTemplateInstruction<0> {
|
| public:
|
| HLeaveInlined() {}
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(LeaveInlined, "leave_inlined")
|
| };
|
|
|
|
|
| class HPushArgument: public HUnaryOperation {
|
| public:
|
| - explicit HPushArgument(HValue* value)
|
| - : HUnaryOperation(value), argument_index_(-1) {
|
| + explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
|
| set_representation(Representation::Tagged());
|
| }
|
|
|
| @@ -1050,32 +1116,27 @@
|
| return Representation::Tagged();
|
| }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| - HValue* argument() const { return OperandAt(0); }
|
| - int argument_index() const { return argument_index_; }
|
| - void set_argument_index(int index) {
|
| - ASSERT(argument_index_ == -1 || index == argument_index_);
|
| - argument_index_ = index;
|
| - }
|
| + HValue* argument() { return OperandAt(0); }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push_argument")
|
| -
|
| - private:
|
| - int argument_index_;
|
| };
|
|
|
|
|
| -class HContext: public HInstruction {
|
| +class HContext: public HTemplateInstruction<0> {
|
| public:
|
| HContext() {
|
| set_representation(Representation::Tagged());
|
| SetFlag(kUseGVN);
|
| }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(Context, "context");
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -1088,8 +1149,12 @@
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer_context");
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -1102,8 +1167,12 @@
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global_object")
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -1117,59 +1186,93 @@
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global_receiver")
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| -class HCall: public HInstruction {
|
| +template <int V>
|
| +class HCall: public HTemplateInstruction<V> {
|
| public:
|
| - // Construct a call with uninitialized arguments. The argument count
|
| - // includes the receiver.
|
| - explicit HCall(int count);
|
| + // The argument count includes the receiver.
|
| + explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
|
| + this->set_representation(Representation::Tagged());
|
| + this->SetAllSideEffects();
|
| + }
|
|
|
| - virtual HType CalculateInferredType() const { return HType::Tagged(); }
|
| + virtual HType CalculateInferredType() { return HType::Tagged(); }
|
|
|
| - // TODO(3190496): This needs a cleanup. We don't want the arguments
|
| - // be operands of the call instruction. This results in bad code quality.
|
| - virtual int argument_count() const { return arguments_.length(); }
|
| - virtual int OperandCount() const { return argument_count(); }
|
| - virtual HValue* OperandAt(int index) const { return arguments_[index]; }
|
| - virtual HPushArgument* PushArgumentAt(int index) const {
|
| - return HPushArgument::cast(OperandAt(index));
|
| + virtual int argument_count() const { return argument_count_; }
|
| +
|
| + virtual bool IsCall() { return true; }
|
| +
|
| + private:
|
| + int argument_count_;
|
| +};
|
| +
|
| +
|
| +class HUnaryCall: public HCall<1> {
|
| + public:
|
| + HUnaryCall(HValue* value, int argument_count)
|
| + : HCall<1>(argument_count) {
|
| + SetOperandAt(0, value);
|
| }
|
| - virtual HValue* ArgumentAt(int index) const {
|
| - return PushArgumentAt(index)->argument();
|
| +
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| }
|
| - virtual void SetArgumentAt(int index, HPushArgument* push_argument);
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| - DECLARE_INSTRUCTION(Call)
|
| + HValue* value() { return OperandAt(0); }
|
|
|
| - protected:
|
| - virtual void InternalSetOperandAt(int index, HValue* value) {
|
| - arguments_[index] = value;
|
| + DECLARE_INSTRUCTION(UnaryCall)
|
| +};
|
| +
|
| +
|
| +class HBinaryCall: public HCall<2> {
|
| + public:
|
| + HBinaryCall(HValue* first, HValue* second, int argument_count)
|
| + : HCall<2>(argument_count) {
|
| + SetOperandAt(0, first);
|
| + SetOperandAt(1, second);
|
| }
|
|
|
| - int argument_count_;
|
| - Vector<HValue*> arguments_;
|
| + virtual void PrintDataTo(StringStream* stream);
|
| +
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| + HValue* first() { return OperandAt(0); }
|
| + HValue* second() { return OperandAt(1); }
|
| +
|
| + DECLARE_INSTRUCTION(BinaryCall)
|
| };
|
|
|
|
|
| -class HCallConstantFunction: public HCall {
|
| +class HCallConstantFunction: public HCall<0> {
|
| public:
|
| HCallConstantFunction(Handle<JSFunction> function, int argument_count)
|
| - : HCall(argument_count), function_(function) { }
|
| + : HCall<0>(argument_count), function_(function) { }
|
|
|
| Handle<JSFunction> function() const { return function_; }
|
| +
|
| bool IsApplyFunction() const {
|
| return function_->code() ==
|
| Isolate::Current()->builtins()->builtin(Builtins::FunctionApply);
|
| }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call_constant_function")
|
|
|
| private:
|
| @@ -1177,68 +1280,76 @@
|
| };
|
|
|
|
|
| -class HCallKeyed: public HCall {
|
| +class HCallKeyed: public HBinaryCall {
|
| public:
|
| - HCallKeyed(HValue* key, int argument_count)
|
| - : HCall(argument_count + 1) {
|
| - SetOperandAt(0, key);
|
| + HCallKeyed(HValue* context, HValue* key, int argument_count)
|
| + : HBinaryCall(context, key, argument_count) {
|
| }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
|
|
| - // TODO(3190496): This is a hack to get an additional operand that
|
| - // is not an argument to work with the current setup. This _needs_ a cleanup.
|
| - // (see HCall)
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| - HValue* key() const { return OperandAt(0); }
|
| - virtual int argument_count() const { return arguments_.length() - 1; }
|
| - virtual int OperandCount() const { return arguments_.length(); }
|
| - virtual HValue* OperandAt(int index) const { return arguments_[index]; }
|
| - virtual HPushArgument* PushArgumentAt(int index) const {
|
| - return HPushArgument::cast(OperandAt(index + 1));
|
| - }
|
| - virtual void SetArgumentAt(int index, HPushArgument* push_argument) {
|
| - HCall::SetArgumentAt(index + 1, push_argument);
|
| - }
|
| + HValue* context() { return first(); }
|
| + HValue* key() { return second(); }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed")
|
| };
|
|
|
|
|
| -class HCallNamed: public HCall {
|
| +class HCallNamed: public HUnaryCall {
|
| public:
|
| - HCallNamed(Handle<String> name, int argument_count)
|
| - : HCall(argument_count), name_(name) { }
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + HCallNamed(HValue* context, Handle<String> name, int argument_count)
|
| + : HUnaryCall(context, argument_count), name_(name) {
|
| + }
|
|
|
| + virtual void PrintDataTo(StringStream* stream);
|
| +
|
| + HValue* context() { return value(); }
|
| Handle<String> name() const { return name_; }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call_named")
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| private:
|
| Handle<String> name_;
|
| };
|
|
|
|
|
| -class HCallFunction: public HCall {
|
| +class HCallFunction: public HUnaryCall {
|
| public:
|
| - explicit HCallFunction(int argument_count) : HCall(argument_count) { }
|
| + HCallFunction(HValue* context, int argument_count)
|
| + : HUnaryCall(context, argument_count) {
|
| + }
|
|
|
| + HValue* context() { return value(); }
|
| +
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call_function")
|
| };
|
|
|
|
|
| -class HCallGlobal: public HCall {
|
| +class HCallGlobal: public HUnaryCall {
|
| public:
|
| - HCallGlobal(Handle<String> name, int argument_count)
|
| - : HCall(argument_count), name_(name) { }
|
| + HCallGlobal(HValue* context, Handle<String> name, int argument_count)
|
| + : HUnaryCall(context, argument_count), name_(name) {
|
| + }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| + HValue* context() { return value(); }
|
| Handle<String> name() const { return name_; }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call_global")
|
|
|
| private:
|
| @@ -1246,14 +1357,19 @@
|
| };
|
|
|
|
|
| -class HCallKnownGlobal: public HCall {
|
| +class HCallKnownGlobal: public HCall<0> {
|
| public:
|
| - HCallKnownGlobal(Handle<JSFunction> target,
|
| - int argument_count)
|
| - : HCall(argument_count), target_(target) { }
|
| + HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
|
| + : HCall<0>(argument_count), target_(target) { }
|
|
|
| + virtual void PrintDataTo(StringStream* stream);
|
| +
|
| Handle<JSFunction> target() const { return target_; }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call_known_global")
|
|
|
| private:
|
| @@ -1261,31 +1377,38 @@
|
| };
|
|
|
|
|
| -class HCallNew: public HCall {
|
| +class HCallNew: public HBinaryCall {
|
| public:
|
| - explicit HCallNew(int argument_count) : HCall(argument_count) { }
|
| + HCallNew(HValue* context, HValue* constructor, int argument_count)
|
| + : HBinaryCall(context, constructor, argument_count) {
|
| + }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
|
|
| - HValue* constructor() const { return ArgumentAt(0); }
|
| + HValue* context() { return first(); }
|
| + HValue* constructor() { return second(); }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new")
|
| };
|
|
|
|
|
| -class HCallRuntime: public HCall {
|
| +class HCallRuntime: public HCall<0> {
|
| public:
|
| HCallRuntime(Handle<String> name,
|
| const Runtime::Function* c_function,
|
| int argument_count)
|
| - : HCall(argument_count), c_function_(c_function), name_(name) { }
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| const Runtime::Function* function() const { return c_function_; }
|
| Handle<String> name() const { return name_; }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call_runtime")
|
|
|
| private:
|
| @@ -1312,7 +1435,7 @@
|
| DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js_array_length")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -1331,10 +1454,31 @@
|
| DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed_array_length")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| +class HPixelArrayLength: public HUnaryOperation {
|
| + public:
|
| + explicit HPixelArrayLength(HValue* value) : HUnaryOperation(value) {
|
| + set_representation(Representation::Integer32());
|
| + // The result of this instruction is idempotent as long as its inputs don't
|
| + // change. The length of a pixel array cannot change once set, so it's not
|
| + // necessary to introduce a kDependsOnArrayLengths or any other dependency.
|
| + SetFlag(kUseGVN);
|
| + }
|
| +
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| + DECLARE_CONCRETE_INSTRUCTION(PixelArrayLength, "pixel_array_length")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| +};
|
| +
|
| +
|
| class HBitNot: public HUnaryOperation {
|
| public:
|
| explicit HBitNot(HValue* value) : HUnaryOperation(value) {
|
| @@ -1346,12 +1490,12 @@
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Integer32();
|
| }
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(BitNot, "bit_not")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -1382,9 +1526,9 @@
|
| SetFlag(kUseGVN);
|
| }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
|
|
| virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
|
|
|
| @@ -1399,11 +1543,10 @@
|
| case kMathSin:
|
| case kMathCos:
|
| return Representation::Double();
|
| - break;
|
| case kMathAbs:
|
| return representation();
|
| - break;
|
| default:
|
| + UNREACHABLE();
|
| return Representation::None();
|
| }
|
| }
|
| @@ -1424,7 +1567,7 @@
|
| DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary_math_operation")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
|
| return op_ == b->op();
|
| }
|
| @@ -1449,10 +1592,34 @@
|
| DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| +class HLoadPixelArrayExternalPointer: public HUnaryOperation {
|
| + public:
|
| + explicit HLoadPixelArrayExternalPointer(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 pixel 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 Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| + DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayExternalPointer,
|
| + "load-pixel-array-external-pointer")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| +};
|
| +
|
| +
|
| class HCheckMap: public HUnaryOperation {
|
| public:
|
| HCheckMap(HValue* value, Handle<Map> map)
|
| @@ -1467,8 +1634,8 @@
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| - virtual HType CalculateInferredType() const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
| + virtual HType CalculateInferredType();
|
|
|
| #ifdef DEBUG
|
| virtual void Verify();
|
| @@ -1479,7 +1646,7 @@
|
| DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check_map")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| HCheckMap* b = HCheckMap::cast(other);
|
| return map_.is_identical_to(b->map());
|
| }
|
| @@ -1502,8 +1669,8 @@
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| - virtual HType CalculateInferredType() const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
| + virtual HType CalculateInferredType();
|
|
|
| #ifdef DEBUG
|
| virtual void Verify();
|
| @@ -1514,7 +1681,7 @@
|
| DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check_function")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| HCheckFunction* b = HCheckFunction::cast(other);
|
| return target_.is_identical_to(b->target());
|
| }
|
| @@ -1562,7 +1729,7 @@
|
| // TODO(ager): It could be nice to allow the ommision of instance
|
| // type checks if we have already performed an instance type check
|
| // with a larger range.
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| HCheckInstanceType* b = HCheckInstanceType::cast(other);
|
| return (first_ == b->first()) && (last_ == b->last());
|
| }
|
| @@ -1586,7 +1753,7 @@
|
| return Representation::Tagged();
|
| }
|
|
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
|
|
| #ifdef DEBUG
|
| virtual void Verify();
|
| @@ -1595,11 +1762,11 @@
|
| DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check_non_smi")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| -class HCheckPrototypeMaps: public HInstruction {
|
| +class HCheckPrototypeMaps: public HTemplateInstruction<0> {
|
| public:
|
| HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
|
| : prototype_(prototype), holder_(holder) {
|
| @@ -1618,7 +1785,11 @@
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check_prototype_maps")
|
|
|
| - virtual intptr_t Hashcode() const {
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| + virtual intptr_t Hashcode() {
|
| ASSERT(!HEAP->IsAllocationAllowed());
|
| intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
|
| hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
|
| @@ -1626,7 +1797,7 @@
|
| }
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
|
| return prototype_.is_identical_to(b->prototype()) &&
|
| holder_.is_identical_to(b->holder());
|
| @@ -1650,7 +1821,7 @@
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
|
|
| #ifdef DEBUG
|
| virtual void Verify();
|
| @@ -1659,7 +1830,7 @@
|
| DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check_smi")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -1678,7 +1849,7 @@
|
| SetFlag(kFlexibleRepresentation);
|
| }
|
|
|
| - virtual Representation InferredRepresentation() const {
|
| + virtual Representation InferredRepresentation() {
|
| bool double_occurred = false;
|
| bool int32_occurred = false;
|
| for (int i = 0; i < OperandCount(); ++i) {
|
| @@ -1697,10 +1868,10 @@
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return representation();
|
| }
|
| - virtual HType CalculateInferredType() const;
|
| - virtual int OperandCount() const { return inputs_.length(); }
|
| - virtual HValue* OperandAt(int index) const { return inputs_[index]; }
|
| - HValue* GetRedundantReplacement() const;
|
| + virtual HType CalculateInferredType();
|
| + virtual int OperandCount() { return inputs_.length(); }
|
| + virtual HValue* OperandAt(int index) { return inputs_[index]; }
|
| + HValue* GetRedundantReplacement();
|
| void AddInput(HValue* value);
|
|
|
| bool IsReceiver() { return merged_index_ == 0; }
|
| @@ -1709,7 +1880,7 @@
|
|
|
| virtual const char* Mnemonic() const { return "phi"; }
|
|
|
| - virtual void PrintTo(StringStream* stream) const;
|
| + virtual void PrintTo(StringStream* stream);
|
|
|
| #ifdef DEBUG
|
| virtual void Verify();
|
| @@ -1757,18 +1928,22 @@
|
| };
|
|
|
|
|
| -class HArgumentsObject: public HInstruction {
|
| +class HArgumentsObject: public HTemplateInstruction<0> {
|
| public:
|
| HArgumentsObject() {
|
| set_representation(Representation::Tagged());
|
| SetFlag(kIsArguments);
|
| }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject, "arguments-object")
|
| };
|
|
|
|
|
| -class HConstant: public HInstruction {
|
| +class HConstant: public HTemplateInstruction<0> {
|
| public:
|
| HConstant(Handle<Object> handle, Representation r);
|
|
|
| @@ -1776,9 +1951,13 @@
|
|
|
| bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| virtual bool EmitAtUses() const { return !representation().IsDouble(); }
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| - virtual HType CalculateInferredType() const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
| + virtual HType CalculateInferredType();
|
| bool IsInteger() const { return handle_->IsSmi(); }
|
| HConstant* CopyToRepresentation(Representation r) const;
|
| HConstant* CopyToTruncatedInt32() const;
|
| @@ -1794,7 +1973,7 @@
|
| }
|
| bool HasStringValue() const { return handle_->IsString(); }
|
|
|
| - virtual intptr_t Hashcode() const {
|
| + virtual intptr_t Hashcode() {
|
| ASSERT(!HEAP->allow_allocation(false));
|
| return reinterpret_cast<intptr_t>(*handle());
|
| }
|
| @@ -1808,7 +1987,7 @@
|
| protected:
|
| virtual Range* InferRange();
|
|
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| HConstant* other_constant = HConstant::cast(other);
|
| return handle().is_identical_to(other_constant->handle());
|
| }
|
| @@ -1827,7 +2006,7 @@
|
| };
|
|
|
|
|
| -class HBinaryOperation: public HInstruction {
|
| +class HBinaryOperation: public HTemplateInstruction<2> {
|
| public:
|
| HBinaryOperation(HValue* left, HValue* right) {
|
| ASSERT(left != NULL && right != NULL);
|
| @@ -1835,39 +2014,29 @@
|
| SetOperandAt(1, right);
|
| }
|
|
|
| - HValue* left() const { return OperandAt(0); }
|
| - HValue* right() const { return OperandAt(1); }
|
| + HValue* left() { return OperandAt(0); }
|
| + HValue* right() { return OperandAt(1); }
|
|
|
| // TODO(kasperl): Move these helpers to the IA-32 Lithium
|
| // instruction sequence builder.
|
| - HValue* LeastConstantOperand() const {
|
| + HValue* LeastConstantOperand() {
|
| if (IsCommutative() && left()->IsConstant()) return right();
|
| return left();
|
| }
|
| - HValue* MostConstantOperand() const {
|
| + HValue* MostConstantOperand() {
|
| if (IsCommutative() && left()->IsConstant()) return left();
|
| return right();
|
| }
|
|
|
| virtual bool IsCommutative() const { return false; }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| - virtual int OperandCount() const { return operands_.length(); }
|
| - virtual HValue* OperandAt(int index) const { return operands_[index]; }
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| DECLARE_INSTRUCTION(BinaryOperation)
|
| -
|
| - protected:
|
| - virtual void InternalSetOperandAt(int index, HValue* value) {
|
| - operands_[index] = value;
|
| - }
|
| -
|
| - private:
|
| - HOperandVector<2> operands_;
|
| };
|
|
|
|
|
| -class HApplyArguments: public HInstruction {
|
| +class HApplyArguments: public HTemplateInstruction<4> {
|
| public:
|
| HApplyArguments(HValue* function,
|
| HValue* receiver,
|
| @@ -1888,27 +2057,16 @@
|
| : Representation::Tagged();
|
| }
|
|
|
| - HValue* function() const { return OperandAt(0); }
|
| - HValue* receiver() const { return OperandAt(1); }
|
| - HValue* length() const { return OperandAt(2); }
|
| - HValue* elements() const { return OperandAt(3); }
|
| + HValue* function() { return OperandAt(0); }
|
| + HValue* receiver() { return OperandAt(1); }
|
| + HValue* length() { return OperandAt(2); }
|
| + HValue* elements() { return OperandAt(3); }
|
|
|
| - virtual int OperandCount() const { return operands_.length(); }
|
| - virtual HValue* OperandAt(int index) const { return operands_[index]; }
|
| -
|
| DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply_arguments")
|
| -
|
| - protected:
|
| - virtual void InternalSetOperandAt(int index, HValue* value) {
|
| - operands_[index] = value;
|
| - }
|
| -
|
| - private:
|
| - HOperandVector<4> operands_;
|
| };
|
|
|
|
|
| -class HArgumentsElements: public HInstruction {
|
| +class HArgumentsElements: public HTemplateInstruction<0> {
|
| public:
|
| HArgumentsElements() {
|
| // The value produced by this instruction is a pointer into the stack
|
| @@ -1919,8 +2077,12 @@
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments_elements")
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -1931,14 +2093,18 @@
|
| SetFlag(kUseGVN);
|
| }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| -class HAccessArgumentsAt: public HInstruction {
|
| +class HAccessArgumentsAt: public HTemplateInstruction<3> {
|
| public:
|
| HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
|
| set_representation(Representation::Tagged());
|
| @@ -1948,7 +2114,7 @@
|
| SetOperandAt(2, index);
|
| }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| // The arguments elements is considered tagged.
|
| @@ -1957,24 +2123,13 @@
|
| : Representation::Integer32();
|
| }
|
|
|
| - HValue* arguments() const { return operands_[0]; }
|
| - HValue* length() const { return operands_[1]; }
|
| - HValue* index() const { return operands_[2]; }
|
| + HValue* arguments() { return OperandAt(0); }
|
| + HValue* length() { return OperandAt(1); }
|
| + HValue* index() { return OperandAt(2); }
|
|
|
| - virtual int OperandCount() const { return operands_.length(); }
|
| - virtual HValue* OperandAt(int index) const { return operands_[index]; }
|
| -
|
| DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access_arguments_at")
|
|
|
| - protected:
|
| - virtual void InternalSetOperandAt(int index, HValue* value) {
|
| - operands_[index] = value;
|
| - }
|
| -
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| -
|
| - private:
|
| - HOperandVector<3> operands_;
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -1995,13 +2150,13 @@
|
| virtual void Verify();
|
| #endif
|
|
|
| - HValue* index() const { return left(); }
|
| - HValue* length() const { return right(); }
|
| + HValue* index() { return left(); }
|
| + HValue* length() { return right(); }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds_check")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -2027,7 +2182,7 @@
|
| }
|
| }
|
|
|
| - HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
|
|
| DECLARE_INSTRUCTION(BitwiseBinaryOperation)
|
| };
|
| @@ -2049,11 +2204,11 @@
|
| }
|
| }
|
|
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return representation();
|
| }
|
| - virtual Representation InferredRepresentation() const {
|
| + virtual Representation InferredRepresentation() {
|
| if (left()->representation().Equals(right()->representation())) {
|
| return left()->representation();
|
| }
|
| @@ -2074,7 +2229,11 @@
|
| }
|
|
|
| void SetInputRepresentation(Representation r);
|
| - virtual bool EmitAtUses() const { return uses()->length() <= 1; }
|
| +
|
| + virtual bool EmitAtUses() const {
|
| + return !HasSideEffects() && (uses()->length() <= 1);
|
| + }
|
| +
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return input_representation_;
|
| }
|
| @@ -2082,18 +2241,18 @@
|
| return input_representation_;
|
| }
|
| Token::Value token() const { return token_; }
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
|
|
| - virtual intptr_t Hashcode() const {
|
| + virtual intptr_t Hashcode() {
|
| return HValue::Hashcode() * 7 + token_;
|
| }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(Compare, "compare")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| HCompare* comp = HCompare::cast(other);
|
| return token_ == comp->token();
|
| }
|
| @@ -2112,16 +2271,19 @@
|
| SetFlag(kUseGVN);
|
| }
|
|
|
| - virtual bool EmitAtUses() const { return uses()->length() <= 1; }
|
| + virtual bool EmitAtUses() const {
|
| + return !HasSideEffects() && (uses()->length() <= 1);
|
| + }
|
| +
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq, "compare-js-object-eq")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -2131,11 +2293,15 @@
|
| set_representation(Representation::Tagged());
|
| SetFlag(kUseGVN);
|
| }
|
| - virtual bool EmitAtUses() const { return uses()->length() <= 1; }
|
| +
|
| + virtual bool EmitAtUses() const {
|
| + return !HasSideEffects() && (uses()->length() <= 1);
|
| + }
|
| +
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
| };
|
|
|
|
|
| @@ -2149,7 +2315,7 @@
|
| DECLARE_CONCRETE_INSTRUCTION(IsNull, "is_null")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| HIsNull* b = HIsNull::cast(other);
|
| return is_strict_ == b->is_strict();
|
| }
|
| @@ -2166,7 +2332,7 @@
|
| DECLARE_CONCRETE_INSTRUCTION(IsObject, "is_object")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -2177,23 +2343,29 @@
|
| DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is_smi")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| -class HIsConstructCall: public HInstruction {
|
| +class HIsConstructCall: public HTemplateInstruction<0> {
|
| public:
|
| HIsConstructCall() {
|
| set_representation(Representation::Tagged());
|
| SetFlag(kUseGVN);
|
| }
|
|
|
| - virtual bool EmitAtUses() const { return uses()->length() <= 1; }
|
| + virtual bool EmitAtUses() const {
|
| + return !HasSideEffects() && (uses()->length() <= 1);
|
| + }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is_construct_call")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -2209,12 +2381,12 @@
|
| InstanceType from() { return from_; }
|
| InstanceType to() { return to_; }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has_instance_type")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| HHasInstanceType* b = HHasInstanceType::cast(other);
|
| return (from_ == b->from()) && (to_ == b->to());
|
| }
|
| @@ -2232,10 +2404,21 @@
|
| DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has_cached_array_index")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| +class HGetCachedArrayIndex: public HUnaryPredicate {
|
| + public:
|
| + explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
|
| +
|
| + DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get_cached_array_index")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| +};
|
| +
|
| +
|
| class HClassOfTest: public HUnaryPredicate {
|
| public:
|
| HClassOfTest(HValue* value, Handle<String> class_name)
|
| @@ -2243,12 +2426,12 @@
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class_of_test")
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| Handle<String> class_name() const { return class_name_; }
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| HClassOfTest* b = HClassOfTest::cast(other);
|
| return class_name_.is_identical_to(b->class_name_);
|
| }
|
| @@ -2264,12 +2447,12 @@
|
| : HUnaryPredicate(value), type_literal_(type_literal) { }
|
|
|
| Handle<String> type_literal() { return type_literal_; }
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof_is")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| HTypeofIs* b = HTypeofIs::cast(other);
|
| return type_literal_.is_identical_to(b->type_literal_);
|
| }
|
| @@ -2279,19 +2462,30 @@
|
| };
|
|
|
|
|
| -class HInstanceOf: public HBinaryOperation {
|
| +class HInstanceOf: public HTemplateInstruction<3> {
|
| public:
|
| - HInstanceOf(HValue* left, HValue* right) : HBinaryOperation(left, right) {
|
| + HInstanceOf(HValue* context, HValue* left, HValue* right) {
|
| + SetOperandAt(0, context);
|
| + SetOperandAt(1, left);
|
| + SetOperandAt(2, right);
|
| set_representation(Representation::Tagged());
|
| SetAllSideEffects();
|
| }
|
|
|
| - virtual bool EmitAtUses() const { return uses()->length() <= 1; }
|
| + HValue* context() { return OperandAt(0); }
|
| + HValue* left() { return OperandAt(1); }
|
| + HValue* right() { return OperandAt(2); }
|
|
|
| + virtual bool EmitAtUses() const {
|
| + return !HasSideEffects() && (uses()->length() <= 1);
|
| + }
|
| +
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
|
|
| + virtual void PrintDataTo(StringStream* stream);
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance_of")
|
| };
|
|
|
| @@ -2333,7 +2527,7 @@
|
| DECLARE_CONCRETE_INSTRUCTION(Power, "power")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -2351,12 +2545,12 @@
|
|
|
| virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
|
|
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(Add, "add")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
|
|
| virtual Range* InferRange();
|
| };
|
| @@ -2373,7 +2567,7 @@
|
| DECLARE_CONCRETE_INSTRUCTION(Sub, "sub")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
|
|
| virtual Range* InferRange();
|
| };
|
| @@ -2395,7 +2589,7 @@
|
| DECLARE_CONCRETE_INSTRUCTION(Mul, "mul")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
|
|
| virtual Range* InferRange();
|
| };
|
| @@ -2412,7 +2606,7 @@
|
| DECLARE_CONCRETE_INSTRUCTION(Mod, "mod")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
|
|
| virtual Range* InferRange();
|
| };
|
| @@ -2430,7 +2624,7 @@
|
| DECLARE_CONCRETE_INSTRUCTION(Div, "div")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
|
|
| virtual Range* InferRange();
|
| };
|
| @@ -2442,12 +2636,12 @@
|
| : HBitwiseBinaryOperation(left, right) { }
|
|
|
| virtual bool IsCommutative() const { return true; }
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(BitAnd, "bit_and")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
|
|
| virtual Range* InferRange();
|
| };
|
| @@ -2459,12 +2653,12 @@
|
| : HBitwiseBinaryOperation(left, right) { }
|
|
|
| virtual bool IsCommutative() const { return true; }
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(BitXor, "bit_xor")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -2474,12 +2668,12 @@
|
| : HBitwiseBinaryOperation(left, right) { }
|
|
|
| virtual bool IsCommutative() const { return true; }
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(BitOr, "bit_or")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
|
|
| virtual Range* InferRange();
|
| };
|
| @@ -2491,12 +2685,12 @@
|
| : HBitwiseBinaryOperation(left, right) { }
|
|
|
| virtual Range* InferRange();
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(Shl, "shl")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -2505,12 +2699,12 @@
|
| HShr(HValue* left, HValue* right)
|
| : HBitwiseBinaryOperation(left, right) { }
|
|
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(Shr, "shr")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| @@ -2520,16 +2714,16 @@
|
| : HBitwiseBinaryOperation(left, right) { }
|
|
|
| virtual Range* InferRange();
|
| - virtual HType CalculateInferredType() const;
|
| + virtual HType CalculateInferredType();
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(Sar, "sar")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| -class HOsrEntry: public HInstruction {
|
| +class HOsrEntry: public HTemplateInstruction<0> {
|
| public:
|
| explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
|
| SetFlag(kChangesOsrEntries);
|
| @@ -2537,6 +2731,10 @@
|
|
|
| int ast_id() const { return ast_id_; }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr_entry")
|
|
|
| private:
|
| @@ -2544,7 +2742,7 @@
|
| };
|
|
|
|
|
| -class HParameter: public HInstruction {
|
| +class HParameter: public HTemplateInstruction<0> {
|
| public:
|
| explicit HParameter(unsigned index) : index_(index) {
|
| set_representation(Representation::Tagged());
|
| @@ -2552,8 +2750,12 @@
|
|
|
| unsigned index() const { return index_; }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
|
|
|
| private:
|
| @@ -2561,45 +2763,52 @@
|
| };
|
|
|
|
|
| -class HCallStub: public HInstruction {
|
| +class HCallStub: public HUnaryCall {
|
| public:
|
| - HCallStub(CodeStub::Major major_key, int argument_count)
|
| - : major_key_(major_key),
|
| - argument_count_(argument_count),
|
| + HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
|
| + : HUnaryCall(context, argument_count),
|
| + major_key_(major_key),
|
| transcendental_type_(TranscendentalCache::kNumberOfCaches) {
|
| - set_representation(Representation::Tagged());
|
| - SetAllSideEffects();
|
| }
|
|
|
| CodeStub::Major major_key() { return major_key_; }
|
| - int argument_count() { return argument_count_; }
|
|
|
| + HValue* context() { return value(); }
|
| +
|
| void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
|
| transcendental_type_ = transcendental_type;
|
| }
|
| TranscendentalCache::Type transcendental_type() {
|
| return transcendental_type_;
|
| }
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
|
|
| + virtual void PrintDataTo(StringStream* stream);
|
| +
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub")
|
|
|
| private:
|
| CodeStub::Major major_key_;
|
| - int argument_count_;
|
| TranscendentalCache::Type transcendental_type_;
|
| };
|
|
|
|
|
| -class HUnknownOSRValue: public HInstruction {
|
| +class HUnknownOSRValue: public HTemplateInstruction<0> {
|
| public:
|
| HUnknownOSRValue() { set_representation(Representation::Tagged()); }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown_osr_value")
|
| };
|
|
|
|
|
| -class HLoadGlobal: public HInstruction {
|
| +class HLoadGlobal: public HTemplateInstruction<0> {
|
| public:
|
| HLoadGlobal(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
|
| : cell_(cell), check_hole_value_(check_hole_value) {
|
| @@ -2611,20 +2820,21 @@
|
| Handle<JSGlobalPropertyCell> cell() const { return cell_; }
|
| bool check_hole_value() const { return check_hole_value_; }
|
|
|
| - virtual Representation RequiredInputRepresentation(int index) const {
|
| - return Representation::Tagged();
|
| - }
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| - virtual intptr_t Hashcode() const {
|
| + virtual intptr_t Hashcode() {
|
| ASSERT(!HEAP->allow_allocation(false));
|
| return reinterpret_cast<intptr_t>(*cell_);
|
| }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(LoadGlobal, "load_global")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| HLoadGlobal* b = HLoadGlobal::cast(other);
|
| return cell_.is_identical_to(b->cell());
|
| }
|
| @@ -2652,7 +2862,7 @@
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store_global")
|
|
|
| @@ -2677,12 +2887,12 @@
|
| return Representation::Tagged();
|
| }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load_context_slot")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| HLoadContextSlot* b = HLoadContextSlot::cast(other);
|
| return (slot_index() == b->slot_index());
|
| }
|
| @@ -2705,11 +2915,11 @@
|
| SetFlag(kChangesContextSlots);
|
| }
|
|
|
| - HValue* context() const { return OperandAt(0); }
|
| - HValue* value() const { return OperandAt(1); }
|
| + HValue* context() { return OperandAt(0); }
|
| + HValue* value() { return OperandAt(1); }
|
| int slot_index() const { return slot_index_; }
|
|
|
| - bool NeedsWriteBarrier() const {
|
| + bool NeedsWriteBarrier() {
|
| return StoringValueNeedsWriteBarrier(value());
|
| }
|
|
|
| @@ -2717,7 +2927,7 @@
|
| return Representation::Tagged();
|
| }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store_context_slot")
|
|
|
| @@ -2741,19 +2951,19 @@
|
| }
|
| }
|
|
|
| - HValue* object() const { return OperandAt(0); }
|
| + HValue* object() { return OperandAt(0); }
|
| bool is_in_object() const { return is_in_object_; }
|
| int offset() const { return offset_; }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load_named_field")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const {
|
| + virtual bool DataEquals(HValue* other) {
|
| HLoadNamedField* b = HLoadNamedField::cast(other);
|
| return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
|
| }
|
| @@ -2764,15 +2974,16 @@
|
| };
|
|
|
|
|
| -class HLoadNamedGeneric: public HUnaryOperation {
|
| +class HLoadNamedGeneric: public HBinaryOperation {
|
| public:
|
| - HLoadNamedGeneric(HValue* object, Handle<Object> name)
|
| - : HUnaryOperation(object), name_(name) {
|
| + HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
|
| + : HBinaryOperation(context, object), name_(name) {
|
| set_representation(Representation::Tagged());
|
| SetAllSideEffects();
|
| }
|
|
|
| - HValue* object() const { return OperandAt(0); }
|
| + HValue* context() { return OperandAt(0); }
|
| + HValue* object() { return OperandAt(1); }
|
| Handle<Object> name() const { return name_; }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| @@ -2795,7 +3006,7 @@
|
| SetFlag(kDependsOnCalls);
|
| }
|
|
|
| - HValue* function() const { return OperandAt(0); }
|
| + HValue* function() { return OperandAt(0); }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| @@ -2804,91 +3015,101 @@
|
| DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load_function_prototype")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| -class HLoadKeyed: public HBinaryOperation {
|
| +class HLoadKeyedFastElement: public HBinaryOperation {
|
| public:
|
| - HLoadKeyed(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
|
| + HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
|
| set_representation(Representation::Tagged());
|
| + SetFlag(kDependsOnArrayElements);
|
| + SetFlag(kUseGVN);
|
| }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + HValue* object() { return OperandAt(0); }
|
| + HValue* key() { return OperandAt(1); }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| - return Representation::Tagged();
|
| + // The key is supposed to be Integer32.
|
| + return (index == 1) ? Representation::Integer32()
|
| + : Representation::Tagged();
|
| }
|
| - HValue* object() const { return OperandAt(0); }
|
| - HValue* key() const { return OperandAt(1); }
|
|
|
| - DECLARE_INSTRUCTION(LoadKeyed)
|
| + virtual void PrintDataTo(StringStream* stream);
|
| +
|
| + DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement,
|
| + "load_keyed_fast_element")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| -class HLoadKeyedFastElement: public HLoadKeyed {
|
| +class HLoadPixelArrayElement: public HBinaryOperation {
|
| public:
|
| - HLoadKeyedFastElement(HValue* obj, HValue* key) : HLoadKeyed(obj, key) {
|
| - SetFlag(kDependsOnArrayElements);
|
| + HLoadPixelArrayElement(HValue* external_elements, HValue* key)
|
| + : HBinaryOperation(external_elements, key) {
|
| + set_representation(Representation::Integer32());
|
| + SetFlag(kDependsOnPixelArrayElements);
|
| + // Native code could change the pixel array.
|
| + SetFlag(kDependsOnCalls);
|
| SetFlag(kUseGVN);
|
| }
|
|
|
| + virtual void PrintDataTo(StringStream* stream);
|
| +
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| - // The key is supposed to be Integer32.
|
| + // The key is supposed to be Integer32, but the base pointer
|
| + // for the element load is a naked pointer.
|
| return (index == 1) ? Representation::Integer32()
|
| - : Representation::Tagged();
|
| + : Representation::External();
|
| }
|
|
|
| - DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement,
|
| - "load_keyed_fast_element")
|
| + HValue* external_pointer() { return OperandAt(0); }
|
| + HValue* key() { return OperandAt(1); }
|
|
|
| + DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
|
| + "load_pixel_array_element")
|
| +
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| };
|
|
|
|
|
| -class HLoadKeyedGeneric: public HLoadKeyed {
|
| +class HLoadKeyedGeneric: public HTemplateInstruction<3> {
|
| public:
|
| - HLoadKeyedGeneric(HValue* obj, HValue* key) : HLoadKeyed(obj, key) {
|
| + HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
|
| + set_representation(Representation::Tagged());
|
| + SetOperandAt(0, obj);
|
| + SetOperandAt(1, key);
|
| + SetOperandAt(2, context);
|
| SetAllSideEffects();
|
| }
|
|
|
| - DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
|
| -};
|
| + HValue* object() { return OperandAt(0); }
|
| + HValue* key() { return OperandAt(1); }
|
| + HValue* context() { return OperandAt(2); }
|
|
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| -class HStoreNamed: public HBinaryOperation {
|
| - public:
|
| - HStoreNamed(HValue* obj, Handle<Object> name, HValue* val)
|
| - : HBinaryOperation(obj, val), name_(name) {
|
| - }
|
| -
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| -
|
| - HValue* object() const { return OperandAt(0); }
|
| - Handle<Object> name() const { return name_; }
|
| - HValue* value() const { return OperandAt(1); }
|
| - void set_value(HValue* value) { SetOperandAt(1, value); }
|
| -
|
| - DECLARE_INSTRUCTION(StoreNamed)
|
| -
|
| - private:
|
| - Handle<Object> name_;
|
| + DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
|
| };
|
|
|
|
|
| -class HStoreNamedField: public HStoreNamed {
|
| +class HStoreNamedField: public HBinaryOperation {
|
| public:
|
| HStoreNamedField(HValue* obj,
|
| - Handle<Object> name,
|
| + Handle<String> name,
|
| HValue* val,
|
| bool in_object,
|
| int offset)
|
| - : HStoreNamed(obj, name, val),
|
| + : HBinaryOperation(obj, val),
|
| + name_(name),
|
| is_in_object_(in_object),
|
| offset_(offset) {
|
| if (is_in_object_) {
|
| @@ -2903,96 +3124,142 @@
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| + HValue* object() { return OperandAt(0); }
|
| + HValue* value() { return OperandAt(1); }
|
| +
|
| + Handle<String> name() const { return name_; }
|
| bool is_in_object() const { return is_in_object_; }
|
| int offset() const { return offset_; }
|
| Handle<Map> transition() const { return transition_; }
|
| void set_transition(Handle<Map> map) { transition_ = map; }
|
|
|
| - bool NeedsWriteBarrier() const {
|
| + bool NeedsWriteBarrier() {
|
| return StoringValueNeedsWriteBarrier(value());
|
| }
|
|
|
| private:
|
| + Handle<String> name_;
|
| bool is_in_object_;
|
| int offset_;
|
| Handle<Map> transition_;
|
| };
|
|
|
|
|
| -class HStoreNamedGeneric: public HStoreNamed {
|
| +class HStoreNamedGeneric: public HTemplateInstruction<3> {
|
| public:
|
| - HStoreNamedGeneric(HValue* obj, Handle<Object> name, HValue* val)
|
| - : HStoreNamed(obj, name, val) {
|
| + HStoreNamedGeneric(HValue* context,
|
| + HValue* object,
|
| + Handle<String> name,
|
| + HValue* value)
|
| + : name_(name) {
|
| + SetOperandAt(0, object);
|
| + SetOperandAt(1, value);
|
| + SetOperandAt(2, context);
|
| SetAllSideEffects();
|
| }
|
|
|
| + HValue* object() { return OperandAt(0); }
|
| + HValue* value() { return OperandAt(1); }
|
| + HValue* context() { return OperandAt(2); }
|
| + Handle<String> name() { return name_; }
|
| +
|
| + virtual void PrintDataTo(StringStream* stream);
|
| +
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
|
| +
|
| + private:
|
| + Handle<String> name_;
|
| };
|
|
|
|
|
| -class HStoreKeyed: public HInstruction {
|
| +class HStoreKeyedFastElement: public HTemplateInstruction<3> {
|
| public:
|
| - HStoreKeyed(HValue* obj, HValue* key, HValue* val) {
|
| + HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
|
| SetOperandAt(0, obj);
|
| SetOperandAt(1, key);
|
| SetOperandAt(2, val);
|
| + SetFlag(kChangesArrayElements);
|
| }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| - virtual int OperandCount() const { return operands_.length(); }
|
| - virtual HValue* OperandAt(int index) const { return operands_[index]; }
|
| -
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| - return Representation::Tagged();
|
| + // The key is supposed to be Integer32.
|
| + return (index == 1) ? Representation::Integer32()
|
| + : Representation::Tagged();
|
| }
|
|
|
| - HValue* object() const { return OperandAt(0); }
|
| - HValue* key() const { return OperandAt(1); }
|
| - HValue* value() const { return OperandAt(2); }
|
| + HValue* object() { return OperandAt(0); }
|
| + HValue* key() { return OperandAt(1); }
|
| + HValue* value() { return OperandAt(2); }
|
|
|
| - bool NeedsWriteBarrier() const {
|
| + bool NeedsWriteBarrier() {
|
| return StoringValueNeedsWriteBarrier(value());
|
| }
|
|
|
| - DECLARE_INSTRUCTION(StoreKeyed)
|
| + virtual void PrintDataTo(StringStream* stream);
|
|
|
| - protected:
|
| - virtual void InternalSetOperandAt(int index, HValue* value) {
|
| - operands_[index] = value;
|
| - }
|
| -
|
| - private:
|
| - HOperandVector<3> operands_;
|
| + DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
|
| + "store_keyed_fast_element")
|
| };
|
|
|
|
|
| -class HStoreKeyedFastElement: public HStoreKeyed {
|
| +class HStorePixelArrayElement: public HTemplateInstruction<3> {
|
| public:
|
| - HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val)
|
| - : HStoreKeyed(obj, key, val) {
|
| - SetFlag(kChangesArrayElements);
|
| + HStorePixelArrayElement(HValue* external_elements, HValue* key, HValue* val) {
|
| + SetFlag(kChangesPixelArrayElements);
|
| + SetOperandAt(0, external_elements);
|
| + SetOperandAt(1, key);
|
| + SetOperandAt(2, val);
|
| }
|
|
|
| + virtual void PrintDataTo(StringStream* stream);
|
| +
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| - // The key is supposed to be Integer32.
|
| - return (index == 1) ? Representation::Integer32()
|
| - : Representation::Tagged();
|
| + if (index == 0) {
|
| + return Representation::External();
|
| + } else {
|
| + return Representation::Integer32();
|
| + }
|
| }
|
|
|
| - DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
|
| - "store_keyed_fast_element")
|
| + HValue* external_pointer() { return OperandAt(0); }
|
| + HValue* key() { return OperandAt(1); }
|
| + HValue* value() { return OperandAt(2); }
|
| +
|
| + DECLARE_CONCRETE_INSTRUCTION(StorePixelArrayElement,
|
| + "store_pixel_array_element")
|
| };
|
|
|
|
|
| -class HStoreKeyedGeneric: public HStoreKeyed {
|
| +class HStoreKeyedGeneric: public HTemplateInstruction<4> {
|
| public:
|
| - HStoreKeyedGeneric(HValue* obj, HValue* key, HValue* val)
|
| - : HStoreKeyed(obj, key, val) {
|
| + HStoreKeyedGeneric(HValue* context,
|
| + HValue* object,
|
| + HValue* key,
|
| + HValue* value) {
|
| + SetOperandAt(0, object);
|
| + SetOperandAt(1, key);
|
| + SetOperandAt(2, value);
|
| + SetOperandAt(3, context);
|
| SetAllSideEffects();
|
| }
|
|
|
| + HValue* object() { return OperandAt(0); }
|
| + HValue* key() { return OperandAt(1); }
|
| + HValue* value() { return OperandAt(2); }
|
| + HValue* context() { return OperandAt(3); }
|
| +
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| + virtual void PrintDataTo(StringStream* stream);
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
|
| };
|
|
|
| @@ -3011,13 +3278,13 @@
|
| : Representation::Tagged();
|
| }
|
|
|
| - HValue* string() const { return OperandAt(0); }
|
| - HValue* index() const { return OperandAt(1); }
|
| + HValue* string() { return OperandAt(0); }
|
| + HValue* index() { return OperandAt(1); }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string_char_code_at")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
|
|
| virtual Range* InferRange() {
|
| return new Range(0, String::kMaxUC16CharCode);
|
| @@ -3036,7 +3303,7 @@
|
| return Representation::Tagged();
|
| }
|
|
|
| - virtual HType CalculateInferredType() const {
|
| + virtual HType CalculateInferredType() {
|
| STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
|
| return HType::Smi();
|
| }
|
| @@ -3044,7 +3311,7 @@
|
| DECLARE_CONCRETE_INSTRUCTION(StringLength, "string_length")
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
|
|
| virtual Range* InferRange() {
|
| return new Range(0, String::kMaxLength);
|
| @@ -3052,31 +3319,30 @@
|
| };
|
|
|
|
|
| -class HMaterializedLiteral: public HInstruction {
|
| +template <int V>
|
| +class HMaterializedLiteral: public HTemplateInstruction<V> {
|
| public:
|
| - HMaterializedLiteral(int index, int depth)
|
| + HMaterializedLiteral<V>(int index, int depth)
|
| : literal_index_(index), depth_(depth) {
|
| - set_representation(Representation::Tagged());
|
| + this->set_representation(Representation::Tagged());
|
| }
|
|
|
| int literal_index() const { return literal_index_; }
|
| int depth() const { return depth_; }
|
|
|
| - DECLARE_INSTRUCTION(MaterializedLiteral)
|
| -
|
| private:
|
| int literal_index_;
|
| int depth_;
|
| };
|
|
|
|
|
| -class HArrayLiteral: public HMaterializedLiteral {
|
| +class HArrayLiteral: public HMaterializedLiteral<0> {
|
| public:
|
| HArrayLiteral(Handle<FixedArray> constant_elements,
|
| int length,
|
| int literal_index,
|
| int depth)
|
| - : HMaterializedLiteral(literal_index, depth),
|
| + : HMaterializedLiteral<0>(literal_index, depth),
|
| length_(length),
|
| constant_elements_(constant_elements) {}
|
|
|
| @@ -3085,6 +3351,10 @@
|
|
|
| bool IsCopyOnWrite() const;
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array_literal")
|
|
|
| private:
|
| @@ -3093,21 +3363,29 @@
|
| };
|
|
|
|
|
| -class HObjectLiteral: public HMaterializedLiteral {
|
| +class HObjectLiteral: public HMaterializedLiteral<1> {
|
| public:
|
| - HObjectLiteral(Handle<FixedArray> constant_properties,
|
| + HObjectLiteral(HValue* context,
|
| + Handle<FixedArray> constant_properties,
|
| bool fast_elements,
|
| int literal_index,
|
| int depth)
|
| - : HMaterializedLiteral(literal_index, depth),
|
| + : HMaterializedLiteral<1>(literal_index, depth),
|
| constant_properties_(constant_properties),
|
| - fast_elements_(fast_elements) {}
|
| + fast_elements_(fast_elements) {
|
| + SetOperandAt(0, context);
|
| + }
|
|
|
| + HValue* context() { return OperandAt(0); }
|
| Handle<FixedArray> constant_properties() const {
|
| return constant_properties_;
|
| }
|
| bool fast_elements() const { return fast_elements_; }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object_literal")
|
|
|
| private:
|
| @@ -3116,18 +3394,22 @@
|
| };
|
|
|
|
|
| -class HRegExpLiteral: public HMaterializedLiteral {
|
| +class HRegExpLiteral: public HMaterializedLiteral<0> {
|
| public:
|
| HRegExpLiteral(Handle<String> pattern,
|
| Handle<String> flags,
|
| int literal_index)
|
| - : HMaterializedLiteral(literal_index, 0),
|
| + : HMaterializedLiteral<0>(literal_index, 0),
|
| pattern_(pattern),
|
| flags_(flags) { }
|
|
|
| Handle<String> pattern() { return pattern_; }
|
| Handle<String> flags() { return flags_; }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp_literal")
|
|
|
| private:
|
| @@ -3136,13 +3418,17 @@
|
| };
|
|
|
|
|
| -class HFunctionLiteral: public HInstruction {
|
| +class HFunctionLiteral: public HTemplateInstruction<0> {
|
| public:
|
| HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
|
| : shared_info_(shared), pretenure_(pretenure) {
|
| set_representation(Representation::Tagged());
|
| }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::None();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function_literal")
|
|
|
| Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
|
| @@ -3174,6 +3460,10 @@
|
| set_representation(Representation::Tagged());
|
| }
|
|
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value_of")
|
| };
|
|
|
| @@ -3192,8 +3482,8 @@
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete_property")
|
|
|
| - HValue* object() const { return left(); }
|
| - HValue* key() const { return right(); }
|
| + HValue* object() { return left(); }
|
| + HValue* key() { return right(); }
|
| };
|
|
|
| #undef DECLARE_INSTRUCTION
|
|
|