| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_ | 28 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_ |
| 29 #define V8_HYDROGEN_INSTRUCTIONS_H_ | 29 #define V8_HYDROGEN_INSTRUCTIONS_H_ |
| 30 | 30 |
| 31 #include "v8.h" | 31 #include "v8.h" |
| 32 | 32 |
| 33 #include "allocation.h" | 33 #include "allocation.h" |
| 34 #include "code-stubs.h" | 34 #include "code-stubs.h" |
| 35 #include "data-flow.h" | 35 #include "data-flow.h" |
| 36 #include "small-pointer-list.h" | 36 #include "small-pointer-list.h" |
| 37 #include "string-stream.h" | 37 #include "string-stream.h" |
| 38 #include "v8conversions.h" |
| 39 #include "v8utils.h" |
| 38 #include "zone.h" | 40 #include "zone.h" |
| 39 | 41 |
| 40 namespace v8 { | 42 namespace v8 { |
| 41 namespace internal { | 43 namespace internal { |
| 42 | 44 |
| 43 // Forward declarations. | 45 // Forward declarations. |
| 44 class HBasicBlock; | 46 class HBasicBlock; |
| 45 class HEnvironment; | 47 class HEnvironment; |
| 46 class HInstruction; | 48 class HInstruction; |
| 47 class HLoopInformation; | 49 class HLoopInformation; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 64 V(ArgumentsElements) \ | 66 V(ArgumentsElements) \ |
| 65 V(ArgumentsLength) \ | 67 V(ArgumentsLength) \ |
| 66 V(ArgumentsObject) \ | 68 V(ArgumentsObject) \ |
| 67 V(ArrayLiteral) \ | 69 V(ArrayLiteral) \ |
| 68 V(BitAnd) \ | 70 V(BitAnd) \ |
| 69 V(BitNot) \ | 71 V(BitNot) \ |
| 70 V(BitOr) \ | 72 V(BitOr) \ |
| 71 V(BitXor) \ | 73 V(BitXor) \ |
| 72 V(BlockEntry) \ | 74 V(BlockEntry) \ |
| 73 V(BoundsCheck) \ | 75 V(BoundsCheck) \ |
| 76 V(Branch) \ |
| 74 V(CallConstantFunction) \ | 77 V(CallConstantFunction) \ |
| 75 V(CallFunction) \ | 78 V(CallFunction) \ |
| 76 V(CallGlobal) \ | 79 V(CallGlobal) \ |
| 77 V(CallKeyed) \ | 80 V(CallKeyed) \ |
| 78 V(CallKnownGlobal) \ | 81 V(CallKnownGlobal) \ |
| 79 V(CallNamed) \ | 82 V(CallNamed) \ |
| 80 V(CallNew) \ | 83 V(CallNew) \ |
| 81 V(CallRuntime) \ | 84 V(CallRuntime) \ |
| 82 V(CallStub) \ | 85 V(CallStub) \ |
| 83 V(Change) \ | 86 V(Change) \ |
| 84 V(CheckFunction) \ | 87 V(CheckFunction) \ |
| 85 V(CheckInstanceType) \ | 88 V(CheckInstanceType) \ |
| 86 V(CheckMap) \ | 89 V(CheckMap) \ |
| 87 V(CheckNonSmi) \ | 90 V(CheckNonSmi) \ |
| 88 V(CheckPrototypeMaps) \ | 91 V(CheckPrototypeMaps) \ |
| 89 V(CheckSmi) \ | 92 V(CheckSmi) \ |
| 90 V(ClampToUint8) \ | 93 V(ClampToUint8) \ |
| 91 V(ClassOfTest) \ | 94 V(ClassOfTestAndBranch) \ |
| 92 V(Compare) \ | 95 V(CompareIDAndBranch) \ |
| 93 V(CompareJSObjectEq) \ | 96 V(CompareGeneric) \ |
| 97 V(CompareObjectEqAndBranch) \ |
| 94 V(CompareMap) \ | 98 V(CompareMap) \ |
| 95 V(CompareSymbolEq) \ | 99 V(CompareConstantEqAndBranch) \ |
| 96 V(Constant) \ | 100 V(Constant) \ |
| 97 V(Context) \ | 101 V(Context) \ |
| 98 V(DeleteProperty) \ | 102 V(DeleteProperty) \ |
| 99 V(Deoptimize) \ | 103 V(Deoptimize) \ |
| 100 V(Div) \ | 104 V(Div) \ |
| 105 V(ElementsKind) \ |
| 101 V(EnterInlined) \ | 106 V(EnterInlined) \ |
| 102 V(ExternalArrayLength) \ | 107 V(ExternalArrayLength) \ |
| 103 V(FixedArrayLength) \ | 108 V(FixedArrayLength) \ |
| 104 V(ForceRepresentation) \ | 109 V(ForceRepresentation) \ |
| 105 V(FunctionLiteral) \ | 110 V(FunctionLiteral) \ |
| 106 V(GetCachedArrayIndex) \ | 111 V(GetCachedArrayIndex) \ |
| 107 V(GlobalObject) \ | 112 V(GlobalObject) \ |
| 108 V(GlobalReceiver) \ | 113 V(GlobalReceiver) \ |
| 109 V(Goto) \ | 114 V(Goto) \ |
| 110 V(HasInstanceType) \ | 115 V(HasCachedArrayIndexAndBranch) \ |
| 111 V(HasCachedArrayIndex) \ | 116 V(HasInstanceTypeAndBranch) \ |
| 112 V(In) \ | 117 V(In) \ |
| 113 V(InstanceOf) \ | 118 V(InstanceOf) \ |
| 114 V(InstanceOfKnownGlobal) \ | 119 V(InstanceOfKnownGlobal) \ |
| 115 V(InvokeFunction) \ | 120 V(InvokeFunction) \ |
| 116 V(IsConstructCall) \ | 121 V(IsConstructCallAndBranch) \ |
| 117 V(IsNull) \ | 122 V(IsNullAndBranch) \ |
| 118 V(IsObject) \ | 123 V(IsObjectAndBranch) \ |
| 119 V(IsSmi) \ | 124 V(IsSmiAndBranch) \ |
| 120 V(IsUndetectable) \ | 125 V(IsUndetectableAndBranch) \ |
| 121 V(JSArrayLength) \ | 126 V(JSArrayLength) \ |
| 122 V(LeaveInlined) \ | 127 V(LeaveInlined) \ |
| 123 V(LoadContextSlot) \ | 128 V(LoadContextSlot) \ |
| 124 V(LoadElements) \ | 129 V(LoadElements) \ |
| 125 V(LoadExternalArrayPointer) \ | 130 V(LoadExternalArrayPointer) \ |
| 126 V(LoadFunctionPrototype) \ | 131 V(LoadFunctionPrototype) \ |
| 127 V(LoadGlobalCell) \ | 132 V(LoadGlobalCell) \ |
| 128 V(LoadGlobalGeneric) \ | 133 V(LoadGlobalGeneric) \ |
| 129 V(LoadKeyedFastElement) \ | 134 V(LoadKeyedFastElement) \ |
| 130 V(LoadKeyedGeneric) \ | 135 V(LoadKeyedGeneric) \ |
| 131 V(LoadKeyedSpecializedArrayElement) \ | 136 V(LoadKeyedSpecializedArrayElement) \ |
| 132 V(LoadNamedField) \ | 137 V(LoadNamedField) \ |
| 133 V(LoadNamedFieldPolymorphic) \ | 138 V(LoadNamedFieldPolymorphic) \ |
| 134 V(LoadNamedGeneric) \ | 139 V(LoadNamedGeneric) \ |
| 135 V(Mod) \ | 140 V(Mod) \ |
| 136 V(Mul) \ | 141 V(Mul) \ |
| 137 V(ObjectLiteral) \ | 142 V(ObjectLiteral) \ |
| 138 V(OsrEntry) \ | 143 V(OsrEntry) \ |
| 139 V(OuterContext) \ | 144 V(OuterContext) \ |
| 140 V(Parameter) \ | 145 V(Parameter) \ |
| 141 V(Power) \ | 146 V(Power) \ |
| 142 V(PushArgument) \ | 147 V(PushArgument) \ |
| 143 V(RegExpLiteral) \ | 148 V(RegExpLiteral) \ |
| 144 V(Return) \ | 149 V(Return) \ |
| 145 V(Sar) \ | 150 V(Sar) \ |
| 146 V(Shl) \ | 151 V(Shl) \ |
| 147 V(Shr) \ | 152 V(Shr) \ |
| 148 V(Simulate) \ | 153 V(Simulate) \ |
| 154 V(SoftDeoptimize) \ |
| 149 V(StackCheck) \ | 155 V(StackCheck) \ |
| 150 V(StoreContextSlot) \ | 156 V(StoreContextSlot) \ |
| 151 V(StoreGlobalCell) \ | 157 V(StoreGlobalCell) \ |
| 152 V(StoreGlobalGeneric) \ | 158 V(StoreGlobalGeneric) \ |
| 153 V(StoreKeyedFastElement) \ | 159 V(StoreKeyedFastElement) \ |
| 160 V(StoreKeyedGeneric) \ |
| 154 V(StoreKeyedSpecializedArrayElement) \ | 161 V(StoreKeyedSpecializedArrayElement) \ |
| 155 V(StoreKeyedGeneric) \ | |
| 156 V(StoreNamedField) \ | 162 V(StoreNamedField) \ |
| 157 V(StoreNamedGeneric) \ | 163 V(StoreNamedGeneric) \ |
| 158 V(StringAdd) \ | 164 V(StringAdd) \ |
| 159 V(StringCharCodeAt) \ | 165 V(StringCharCodeAt) \ |
| 160 V(StringCharFromCode) \ | 166 V(StringCharFromCode) \ |
| 161 V(StringLength) \ | 167 V(StringLength) \ |
| 162 V(Sub) \ | 168 V(Sub) \ |
| 163 V(Test) \ | 169 V(ThisFunction) \ |
| 164 V(Throw) \ | 170 V(Throw) \ |
| 165 V(ToFastProperties) \ | 171 V(ToFastProperties) \ |
| 172 V(ToInt32) \ |
| 166 V(Typeof) \ | 173 V(Typeof) \ |
| 167 V(TypeofIs) \ | 174 V(TypeofIsAndBranch) \ |
| 168 V(UnaryMathOperation) \ | 175 V(UnaryMathOperation) \ |
| 169 V(UnknownOSRValue) \ | 176 V(UnknownOSRValue) \ |
| 177 V(UseConst) \ |
| 170 V(ValueOf) | 178 V(ValueOf) |
| 171 | 179 |
| 172 #define GVN_FLAG_LIST(V) \ | 180 #define GVN_FLAG_LIST(V) \ |
| 173 V(Calls) \ | 181 V(Calls) \ |
| 174 V(InobjectFields) \ | 182 V(InobjectFields) \ |
| 175 V(BackingStoreFields) \ | 183 V(BackingStoreFields) \ |
| 176 V(ArrayElements) \ | 184 V(ArrayElements) \ |
| 177 V(SpecializedArrayElements) \ | 185 V(SpecializedArrayElements) \ |
| 178 V(GlobalVars) \ | 186 V(GlobalVars) \ |
| 179 V(Maps) \ | 187 V(Maps) \ |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 enum Type { | 398 enum Type { |
| 391 kTagged = 0x1, // 0000 0000 0000 0001 | 399 kTagged = 0x1, // 0000 0000 0000 0001 |
| 392 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 | 400 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 |
| 393 kTaggedNumber = 0xd, // 0000 0000 0000 1101 | 401 kTaggedNumber = 0xd, // 0000 0000 0000 1101 |
| 394 kSmi = 0x1d, // 0000 0000 0001 1101 | 402 kSmi = 0x1d, // 0000 0000 0001 1101 |
| 395 kHeapNumber = 0x2d, // 0000 0000 0010 1101 | 403 kHeapNumber = 0x2d, // 0000 0000 0010 1101 |
| 396 kString = 0x45, // 0000 0000 0100 0101 | 404 kString = 0x45, // 0000 0000 0100 0101 |
| 397 kBoolean = 0x85, // 0000 0000 1000 0101 | 405 kBoolean = 0x85, // 0000 0000 1000 0101 |
| 398 kNonPrimitive = 0x101, // 0000 0001 0000 0001 | 406 kNonPrimitive = 0x101, // 0000 0001 0000 0001 |
| 399 kJSObject = 0x301, // 0000 0011 0000 0001 | 407 kJSObject = 0x301, // 0000 0011 0000 0001 |
| 400 kJSArray = 0x701, // 0000 0111 1000 0001 | 408 kJSArray = 0x701, // 0000 0111 0000 0001 |
| 401 kUninitialized = 0x1fff // 0001 1111 1111 1111 | 409 kUninitialized = 0x1fff // 0001 1111 1111 1111 |
| 402 }; | 410 }; |
| 403 | 411 |
| 404 // Make sure type fits in int16. | 412 // Make sure type fits in int16. |
| 405 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte))); | 413 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte))); |
| 406 | 414 |
| 407 explicit HType(Type t) : type_(t) { } | 415 explicit HType(Type t) : type_(t) { } |
| 408 | 416 |
| 409 int16_t type_; | 417 int16_t type_; |
| 410 }; | 418 }; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 | 480 |
| 473 // There must be one corresponding kDepends flag for every kChanges flag and | 481 // There must be one corresponding kDepends flag for every kChanges flag and |
| 474 // the order of the kChanges flags must be exactly the same as of the kDepends | 482 // the order of the kChanges flags must be exactly the same as of the kDepends |
| 475 // flags. | 483 // flags. |
| 476 enum Flag { | 484 enum Flag { |
| 477 // Declare global value numbering flags. | 485 // Declare global value numbering flags. |
| 478 #define DECLARE_DO(type) kChanges##type, kDependsOn##type, | 486 #define DECLARE_DO(type) kChanges##type, kDependsOn##type, |
| 479 GVN_FLAG_LIST(DECLARE_DO) | 487 GVN_FLAG_LIST(DECLARE_DO) |
| 480 #undef DECLARE_DO | 488 #undef DECLARE_DO |
| 481 kFlexibleRepresentation, | 489 kFlexibleRepresentation, |
| 490 // Participate in Global Value Numbering, i.e. elimination of |
| 491 // unnecessary recomputations. If an instruction sets this flag, it must |
| 492 // implement DataEquals(), which will be used to determine if other |
| 493 // occurrences of the instruction are indeed the same. |
| 482 kUseGVN, | 494 kUseGVN, |
| 483 kCanOverflow, | 495 kCanOverflow, |
| 484 kBailoutOnMinusZero, | 496 kBailoutOnMinusZero, |
| 485 kCanBeDivByZero, | 497 kCanBeDivByZero, |
| 498 kDeoptimizeOnUndefined, |
| 486 kIsArguments, | 499 kIsArguments, |
| 487 kTruncatingToInt32, | 500 kTruncatingToInt32, |
| 488 kLastFlag = kTruncatingToInt32 | 501 kLastFlag = kTruncatingToInt32 |
| 489 }; | 502 }; |
| 490 | 503 |
| 491 STATIC_ASSERT(kLastFlag < kBitsPerInt); | 504 STATIC_ASSERT(kLastFlag < kBitsPerInt); |
| 492 | 505 |
| 493 static const int kChangesToDependsFlagsLeftShift = 1; | 506 static const int kChangesToDependsFlagsLeftShift = 1; |
| 494 | 507 |
| 495 static int ChangesFlagsMask() { | 508 static int ChangesFlagsMask() { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 } | 597 } |
| 585 | 598 |
| 586 bool IsDefinedAfter(HBasicBlock* other) const; | 599 bool IsDefinedAfter(HBasicBlock* other) const; |
| 587 | 600 |
| 588 // Operands. | 601 // Operands. |
| 589 virtual int OperandCount() = 0; | 602 virtual int OperandCount() = 0; |
| 590 virtual HValue* OperandAt(int index) = 0; | 603 virtual HValue* OperandAt(int index) = 0; |
| 591 void SetOperandAt(int index, HValue* value); | 604 void SetOperandAt(int index, HValue* value); |
| 592 | 605 |
| 593 void DeleteAndReplaceWith(HValue* other); | 606 void DeleteAndReplaceWith(HValue* other); |
| 607 void ReplaceAllUsesWith(HValue* other); |
| 594 bool HasNoUses() const { return use_list_ == NULL; } | 608 bool HasNoUses() const { return use_list_ == NULL; } |
| 595 bool HasMultipleUses() const { | 609 bool HasMultipleUses() const { |
| 596 return use_list_ != NULL && use_list_->tail() != NULL; | 610 return use_list_ != NULL && use_list_->tail() != NULL; |
| 597 } | 611 } |
| 598 int UseCount() const; | 612 int UseCount() const; |
| 599 void ClearOperands(); | 613 void ClearOperands(); |
| 600 | 614 |
| 601 int flags() const { return flags_; } | 615 int flags() const { return flags_; } |
| 602 void SetFlag(Flag f) { flags_ |= (1 << f); } | 616 void SetFlag(Flag f) { flags_ |= (1 << f); } |
| 603 void ClearFlag(Flag f) { flags_ &= ~(1 << f); } | 617 void ClearFlag(Flag f) { flags_ &= ~(1 << f); } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 private: | 687 private: |
| 674 // A flag mask to mark an instruction as having arbitrary side effects. | 688 // A flag mask to mark an instruction as having arbitrary side effects. |
| 675 static int AllSideEffects() { | 689 static int AllSideEffects() { |
| 676 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries); | 690 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries); |
| 677 } | 691 } |
| 678 | 692 |
| 679 // Remove the matching use from the use list if present. Returns the | 693 // Remove the matching use from the use list if present. Returns the |
| 680 // removed list node or NULL. | 694 // removed list node or NULL. |
| 681 HUseListNode* RemoveUse(HValue* value, int index); | 695 HUseListNode* RemoveUse(HValue* value, int index); |
| 682 | 696 |
| 683 void ReplaceAllUsesWith(HValue* other); | |
| 684 | |
| 685 void RegisterUse(int index, HValue* new_value); | 697 void RegisterUse(int index, HValue* new_value); |
| 686 | 698 |
| 687 HBasicBlock* block_; | 699 HBasicBlock* block_; |
| 688 | 700 |
| 689 // The id of this instruction in the hydrogen graph, assigned when first | 701 // The id of this instruction in the hydrogen graph, assigned when first |
| 690 // added to the graph. Reflects creation order. | 702 // added to the graph. Reflects creation order. |
| 691 int id_; | 703 int id_; |
| 692 | 704 |
| 693 Representation representation_; | 705 Representation representation_; |
| 694 HType type_; | 706 HType type_; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 716 int position() const { return position_; } | 728 int position() const { return position_; } |
| 717 bool has_position() const { return position_ != RelocInfo::kNoPosition; } | 729 bool has_position() const { return position_ != RelocInfo::kNoPosition; } |
| 718 void set_position(int position) { position_ = position; } | 730 void set_position(int position) { position_ = position; } |
| 719 | 731 |
| 720 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0; | 732 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0; |
| 721 | 733 |
| 722 #ifdef DEBUG | 734 #ifdef DEBUG |
| 723 virtual void Verify(); | 735 virtual void Verify(); |
| 724 #endif | 736 #endif |
| 725 | 737 |
| 726 // Returns whether this is some kind of deoptimizing check | |
| 727 // instruction. | |
| 728 virtual bool IsCheckInstruction() const { return false; } | |
| 729 | |
| 730 virtual bool IsCall() { return false; } | 738 virtual bool IsCall() { return false; } |
| 731 | 739 |
| 732 DECLARE_ABSTRACT_INSTRUCTION(Instruction) | 740 DECLARE_ABSTRACT_INSTRUCTION(Instruction) |
| 733 | 741 |
| 734 protected: | 742 protected: |
| 735 HInstruction() | 743 HInstruction() |
| 736 : next_(NULL), | 744 : next_(NULL), |
| 737 previous_(NULL), | 745 previous_(NULL), |
| 738 position_(RelocInfo::kNoPosition) { | 746 position_(RelocInfo::kNoPosition) { |
| 739 SetFlag(kDependsOnOsrEntries); | 747 SetFlag(kDependsOnOsrEntries); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 750 void PrintMnemonicTo(StringStream* stream); | 758 void PrintMnemonicTo(StringStream* stream); |
| 751 | 759 |
| 752 HInstruction* next_; | 760 HInstruction* next_; |
| 753 HInstruction* previous_; | 761 HInstruction* previous_; |
| 754 int position_; | 762 int position_; |
| 755 | 763 |
| 756 friend class HBasicBlock; | 764 friend class HBasicBlock; |
| 757 }; | 765 }; |
| 758 | 766 |
| 759 | 767 |
| 760 class HControlInstruction: public HInstruction { | |
| 761 public: | |
| 762 HControlInstruction(HBasicBlock* first, HBasicBlock* second) | |
| 763 : first_successor_(first), second_successor_(second) { | |
| 764 } | |
| 765 | |
| 766 HBasicBlock* FirstSuccessor() const { return first_successor_; } | |
| 767 HBasicBlock* SecondSuccessor() const { return second_successor_; } | |
| 768 | |
| 769 virtual void PrintDataTo(StringStream* stream); | |
| 770 | |
| 771 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction) | |
| 772 | |
| 773 private: | |
| 774 HBasicBlock* first_successor_; | |
| 775 HBasicBlock* second_successor_; | |
| 776 }; | |
| 777 | |
| 778 | |
| 779 template<int NumElements> | |
| 780 class HOperandContainer { | |
| 781 public: | |
| 782 HOperandContainer() : elems_() { } | |
| 783 | |
| 784 int length() { return NumElements; } | |
| 785 HValue*& operator[](int i) { | |
| 786 ASSERT(i < length()); | |
| 787 return elems_[i]; | |
| 788 } | |
| 789 | |
| 790 private: | |
| 791 HValue* elems_[NumElements]; | |
| 792 }; | |
| 793 | |
| 794 | |
| 795 template<> | |
| 796 class HOperandContainer<0> { | |
| 797 public: | |
| 798 int length() { return 0; } | |
| 799 HValue*& operator[](int i) { | |
| 800 UNREACHABLE(); | |
| 801 static HValue* t = 0; | |
| 802 return t; | |
| 803 } | |
| 804 }; | |
| 805 | |
| 806 | |
| 807 template<int V> | 768 template<int V> |
| 808 class HTemplateInstruction : public HInstruction { | 769 class HTemplateInstruction : public HInstruction { |
| 809 public: | 770 public: |
| 810 int OperandCount() { return V; } | 771 int OperandCount() { return V; } |
| 811 HValue* OperandAt(int i) { return inputs_[i]; } | 772 HValue* OperandAt(int i) { return inputs_[i]; } |
| 812 | 773 |
| 813 protected: | 774 protected: |
| 814 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; } | 775 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; } |
| 815 | 776 |
| 816 private: | 777 private: |
| 817 HOperandContainer<V> inputs_; | 778 EmbeddedContainer<HValue*, V> inputs_; |
| 818 }; | 779 }; |
| 819 | 780 |
| 820 | 781 |
| 821 template<int V> | 782 class HControlInstruction: public HInstruction { |
| 822 class HTemplateControlInstruction : public HControlInstruction { | |
| 823 public: | 783 public: |
| 824 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second) | 784 virtual HBasicBlock* SuccessorAt(int i) = 0; |
| 825 : HControlInstruction(first, second) { } | 785 virtual int SuccessorCount() = 0; |
| 786 virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0; |
| 787 |
| 788 virtual void PrintDataTo(StringStream* stream); |
| 789 |
| 790 HBasicBlock* FirstSuccessor() { |
| 791 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL; |
| 792 } |
| 793 HBasicBlock* SecondSuccessor() { |
| 794 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL; |
| 795 } |
| 796 |
| 797 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction) |
| 798 }; |
| 799 |
| 800 |
| 801 class HSuccessorIterator BASE_EMBEDDED { |
| 802 public: |
| 803 explicit HSuccessorIterator(HControlInstruction* instr) |
| 804 : instr_(instr), current_(0) { } |
| 805 |
| 806 bool Done() { return current_ >= instr_->SuccessorCount(); } |
| 807 HBasicBlock* Current() { return instr_->SuccessorAt(current_); } |
| 808 void Advance() { current_++; } |
| 809 |
| 810 private: |
| 811 HControlInstruction* instr_; |
| 812 int current_; |
| 813 }; |
| 814 |
| 815 |
| 816 template<int S, int V> |
| 817 class HTemplateControlInstruction: public HControlInstruction { |
| 818 public: |
| 819 int SuccessorCount() { return S; } |
| 820 HBasicBlock* SuccessorAt(int i) { return successors_[i]; } |
| 821 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; } |
| 822 |
| 826 int OperandCount() { return V; } | 823 int OperandCount() { return V; } |
| 827 HValue* OperandAt(int i) { return inputs_[i]; } | 824 HValue* OperandAt(int i) { return inputs_[i]; } |
| 828 | 825 |
| 826 |
| 829 protected: | 827 protected: |
| 830 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; } | 828 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; } |
| 831 | 829 |
| 832 private: | 830 private: |
| 833 HOperandContainer<V> inputs_; | 831 EmbeddedContainer<HBasicBlock*, S> successors_; |
| 832 EmbeddedContainer<HValue*, V> inputs_; |
| 834 }; | 833 }; |
| 835 | 834 |
| 836 | 835 |
| 837 class HBlockEntry: public HTemplateInstruction<0> { | 836 class HBlockEntry: public HTemplateInstruction<0> { |
| 838 public: | 837 public: |
| 839 virtual Representation RequiredInputRepresentation(int index) const { | 838 virtual Representation RequiredInputRepresentation(int index) const { |
| 840 return Representation::None(); | 839 return Representation::None(); |
| 841 } | 840 } |
| 842 | 841 |
| 843 DECLARE_CONCRETE_INSTRUCTION(BlockEntry) | 842 DECLARE_CONCRETE_INSTRUCTION(BlockEntry) |
| 844 }; | 843 }; |
| 845 | 844 |
| 846 | 845 |
| 846 // We insert soft-deoptimize when we hit code with unknown typefeedback, |
| 847 // so that we get a chance of re-optimizing with useful typefeedback. |
| 848 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize. |
| 849 class HSoftDeoptimize: public HTemplateInstruction<0> { |
| 850 public: |
| 851 virtual Representation RequiredInputRepresentation(int index) const { |
| 852 return Representation::None(); |
| 853 } |
| 854 |
| 855 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize) |
| 856 }; |
| 857 |
| 858 |
| 847 class HDeoptimize: public HControlInstruction { | 859 class HDeoptimize: public HControlInstruction { |
| 848 public: | 860 public: |
| 849 explicit HDeoptimize(int environment_length) | 861 explicit HDeoptimize(int environment_length) : values_(environment_length) { } |
| 850 : HControlInstruction(NULL, NULL), | |
| 851 values_(environment_length) { } | |
| 852 | 862 |
| 853 virtual Representation RequiredInputRepresentation(int index) const { | 863 virtual Representation RequiredInputRepresentation(int index) const { |
| 854 return Representation::None(); | 864 return Representation::None(); |
| 855 } | 865 } |
| 856 | 866 |
| 857 virtual int OperandCount() { return values_.length(); } | 867 virtual int OperandCount() { return values_.length(); } |
| 858 virtual HValue* OperandAt(int index) { return values_[index]; } | 868 virtual HValue* OperandAt(int index) { return values_[index]; } |
| 869 virtual void PrintDataTo(StringStream* stream); |
| 870 |
| 871 virtual int SuccessorCount() { return 0; } |
| 872 virtual HBasicBlock* SuccessorAt(int i) { |
| 873 UNREACHABLE(); |
| 874 return NULL; |
| 875 } |
| 876 virtual void SetSuccessorAt(int i, HBasicBlock* block) { |
| 877 UNREACHABLE(); |
| 878 } |
| 859 | 879 |
| 860 void AddEnvironmentValue(HValue* value) { | 880 void AddEnvironmentValue(HValue* value) { |
| 861 values_.Add(NULL); | 881 values_.Add(NULL); |
| 862 SetOperandAt(values_.length() - 1, value); | 882 SetOperandAt(values_.length() - 1, value); |
| 863 } | 883 } |
| 864 | 884 |
| 865 DECLARE_CONCRETE_INSTRUCTION(Deoptimize) | 885 DECLARE_CONCRETE_INSTRUCTION(Deoptimize) |
| 866 | 886 |
| 867 enum UseEnvironment { | 887 enum UseEnvironment { |
| 868 kNoUses, | 888 kNoUses, |
| 869 kUseAll | 889 kUseAll |
| 870 }; | 890 }; |
| 871 | 891 |
| 872 protected: | 892 protected: |
| 873 virtual void InternalSetOperandAt(int index, HValue* value) { | 893 virtual void InternalSetOperandAt(int index, HValue* value) { |
| 874 values_[index] = value; | 894 values_[index] = value; |
| 875 } | 895 } |
| 876 | 896 |
| 877 private: | 897 private: |
| 878 ZoneList<HValue*> values_; | 898 ZoneList<HValue*> values_; |
| 879 }; | 899 }; |
| 880 | 900 |
| 881 | 901 |
| 882 class HGoto: public HTemplateControlInstruction<0> { | 902 class HGoto: public HTemplateControlInstruction<1, 0> { |
| 883 public: | 903 public: |
| 884 explicit HGoto(HBasicBlock* target) | 904 explicit HGoto(HBasicBlock* target) { |
| 885 : HTemplateControlInstruction<0>(target, NULL), | 905 SetSuccessorAt(0, target); |
| 886 include_stack_check_(false) { } | 906 } |
| 887 | |
| 888 void set_include_stack_check(bool include_stack_check) { | |
| 889 include_stack_check_ = include_stack_check; | |
| 890 } | |
| 891 bool include_stack_check() const { return include_stack_check_; } | |
| 892 | 907 |
| 893 virtual Representation RequiredInputRepresentation(int index) const { | 908 virtual Representation RequiredInputRepresentation(int index) const { |
| 894 return Representation::None(); | 909 return Representation::None(); |
| 895 } | 910 } |
| 896 | 911 |
| 897 DECLARE_CONCRETE_INSTRUCTION(Goto) | 912 DECLARE_CONCRETE_INSTRUCTION(Goto) |
| 898 | |
| 899 private: | |
| 900 bool include_stack_check_; | |
| 901 }; | 913 }; |
| 902 | 914 |
| 903 | 915 |
| 904 class HUnaryControlInstruction: public HTemplateControlInstruction<1> { | 916 class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> { |
| 905 public: | 917 public: |
| 906 explicit HUnaryControlInstruction(HValue* value, | 918 HUnaryControlInstruction(HValue* value, |
| 907 HBasicBlock* true_target, | 919 HBasicBlock* true_target, |
| 908 HBasicBlock* false_target) | 920 HBasicBlock* false_target) { |
| 909 : HTemplateControlInstruction<1>(true_target, false_target) { | |
| 910 SetOperandAt(0, value); | 921 SetOperandAt(0, value); |
| 922 SetSuccessorAt(0, true_target); |
| 923 SetSuccessorAt(1, false_target); |
| 911 } | 924 } |
| 912 | 925 |
| 913 virtual void PrintDataTo(StringStream* stream); | 926 virtual void PrintDataTo(StringStream* stream); |
| 914 | 927 |
| 915 HValue* value() { return OperandAt(0); } | 928 HValue* value() { return OperandAt(0); } |
| 916 }; | 929 }; |
| 917 | 930 |
| 918 | 931 |
| 919 class HTest: public HUnaryControlInstruction { | 932 class HBranch: public HUnaryControlInstruction { |
| 920 public: | 933 public: |
| 921 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target) | 934 HBranch(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target) |
| 922 : HUnaryControlInstruction(value, true_target, false_target) { | 935 : HUnaryControlInstruction(value, true_target, false_target) { |
| 923 ASSERT(true_target != NULL && false_target != NULL); | 936 ASSERT(true_target != NULL && false_target != NULL); |
| 924 } | 937 } |
| 938 explicit HBranch(HValue* value) |
| 939 : HUnaryControlInstruction(value, NULL, NULL) { } |
| 940 |
| 925 | 941 |
| 926 virtual Representation RequiredInputRepresentation(int index) const { | 942 virtual Representation RequiredInputRepresentation(int index) const { |
| 927 return Representation::None(); | 943 return Representation::None(); |
| 928 } | 944 } |
| 929 | 945 |
| 930 DECLARE_CONCRETE_INSTRUCTION(Test) | 946 DECLARE_CONCRETE_INSTRUCTION(Branch) |
| 931 }; | 947 }; |
| 932 | 948 |
| 933 | 949 |
| 934 class HCompareMap: public HUnaryControlInstruction { | 950 class HCompareMap: public HUnaryControlInstruction { |
| 935 public: | 951 public: |
| 936 HCompareMap(HValue* value, | 952 HCompareMap(HValue* value, |
| 937 Handle<Map> map, | 953 Handle<Map> map, |
| 938 HBasicBlock* true_target, | 954 HBasicBlock* true_target, |
| 939 HBasicBlock* false_target) | 955 HBasicBlock* false_target) |
| 940 : HUnaryControlInstruction(value, true_target, false_target), | 956 : HUnaryControlInstruction(value, true_target, false_target), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 952 return Representation::Tagged(); | 968 return Representation::Tagged(); |
| 953 } | 969 } |
| 954 | 970 |
| 955 DECLARE_CONCRETE_INSTRUCTION(CompareMap) | 971 DECLARE_CONCRETE_INSTRUCTION(CompareMap) |
| 956 | 972 |
| 957 private: | 973 private: |
| 958 Handle<Map> map_; | 974 Handle<Map> map_; |
| 959 }; | 975 }; |
| 960 | 976 |
| 961 | 977 |
| 962 class HReturn: public HUnaryControlInstruction { | 978 class HReturn: public HTemplateControlInstruction<0, 1> { |
| 963 public: | 979 public: |
| 964 explicit HReturn(HValue* value) | 980 explicit HReturn(HValue* value) { |
| 965 : HUnaryControlInstruction(value, NULL, NULL) { | 981 SetOperandAt(0, value); |
| 966 } | 982 } |
| 967 | 983 |
| 968 virtual Representation RequiredInputRepresentation(int index) const { | 984 virtual Representation RequiredInputRepresentation(int index) const { |
| 969 return Representation::Tagged(); | 985 return Representation::Tagged(); |
| 970 } | 986 } |
| 971 | 987 |
| 988 virtual void PrintDataTo(StringStream* stream); |
| 989 |
| 990 HValue* value() { return OperandAt(0); } |
| 991 |
| 972 DECLARE_CONCRETE_INSTRUCTION(Return) | 992 DECLARE_CONCRETE_INSTRUCTION(Return) |
| 973 }; | 993 }; |
| 974 | 994 |
| 975 | 995 |
| 976 class HAbnormalExit: public HTemplateControlInstruction<0> { | 996 class HAbnormalExit: public HTemplateControlInstruction<0, 0> { |
| 977 public: | 997 public: |
| 978 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { } | |
| 979 | |
| 980 virtual Representation RequiredInputRepresentation(int index) const { | 998 virtual Representation RequiredInputRepresentation(int index) const { |
| 981 return Representation::None(); | 999 return Representation::None(); |
| 982 } | 1000 } |
| 983 | 1001 |
| 984 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit) | 1002 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit) |
| 985 }; | 1003 }; |
| 986 | 1004 |
| 987 | 1005 |
| 988 class HUnaryOperation: public HTemplateInstruction<1> { | 1006 class HUnaryOperation: public HTemplateInstruction<1> { |
| 989 public: | 1007 public: |
| 990 explicit HUnaryOperation(HValue* value) { | 1008 explicit HUnaryOperation(HValue* value) { |
| 991 SetOperandAt(0, value); | 1009 SetOperandAt(0, value); |
| 992 } | 1010 } |
| 993 | 1011 |
| 1012 static HUnaryOperation* cast(HValue* value) { |
| 1013 return reinterpret_cast<HUnaryOperation*>(value); |
| 1014 } |
| 1015 |
| 1016 virtual bool CanTruncateToInt32() const { |
| 1017 return CheckFlag(kTruncatingToInt32); |
| 1018 } |
| 1019 |
| 994 HValue* value() { return OperandAt(0); } | 1020 HValue* value() { return OperandAt(0); } |
| 995 virtual void PrintDataTo(StringStream* stream); | 1021 virtual void PrintDataTo(StringStream* stream); |
| 996 }; | 1022 }; |
| 997 | 1023 |
| 998 | 1024 |
| 999 class HThrow: public HUnaryOperation { | 1025 class HThrow: public HTemplateInstruction<2> { |
| 1000 public: | 1026 public: |
| 1001 explicit HThrow(HValue* value) : HUnaryOperation(value) { | 1027 HThrow(HValue* context, HValue* value) { |
| 1028 SetOperandAt(0, context); |
| 1029 SetOperandAt(1, value); |
| 1002 SetAllSideEffects(); | 1030 SetAllSideEffects(); |
| 1003 } | 1031 } |
| 1004 | 1032 |
| 1005 virtual Representation RequiredInputRepresentation(int index) const { | 1033 virtual Representation RequiredInputRepresentation(int index) const { |
| 1006 return Representation::Tagged(); | 1034 return Representation::Tagged(); |
| 1007 } | 1035 } |
| 1008 | 1036 |
| 1037 HValue* context() { return OperandAt(0); } |
| 1038 HValue* value() { return OperandAt(1); } |
| 1039 |
| 1009 DECLARE_CONCRETE_INSTRUCTION(Throw) | 1040 DECLARE_CONCRETE_INSTRUCTION(Throw) |
| 1010 }; | 1041 }; |
| 1011 | 1042 |
| 1012 | 1043 |
| 1044 class HUseConst: public HUnaryOperation { |
| 1045 public: |
| 1046 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { } |
| 1047 |
| 1048 virtual Representation RequiredInputRepresentation(int index) const { |
| 1049 return Representation::None(); |
| 1050 } |
| 1051 |
| 1052 DECLARE_CONCRETE_INSTRUCTION(UseConst) |
| 1053 }; |
| 1054 |
| 1055 |
| 1013 class HForceRepresentation: public HTemplateInstruction<1> { | 1056 class HForceRepresentation: public HTemplateInstruction<1> { |
| 1014 public: | 1057 public: |
| 1015 HForceRepresentation(HValue* value, Representation required_representation) { | 1058 HForceRepresentation(HValue* value, Representation required_representation) { |
| 1016 SetOperandAt(0, value); | 1059 SetOperandAt(0, value); |
| 1017 set_representation(required_representation); | 1060 set_representation(required_representation); |
| 1018 } | 1061 } |
| 1019 | 1062 |
| 1020 HValue* value() { return OperandAt(0); } | 1063 HValue* value() { return OperandAt(0); } |
| 1021 | 1064 |
| 1022 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 1065 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
| 1023 | 1066 |
| 1024 virtual Representation RequiredInputRepresentation(int index) const { | 1067 virtual Representation RequiredInputRepresentation(int index) const { |
| 1025 return representation(); // Same as the output representation. | 1068 return representation(); // Same as the output representation. |
| 1026 } | 1069 } |
| 1027 | 1070 |
| 1028 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation) | 1071 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation) |
| 1029 }; | 1072 }; |
| 1030 | 1073 |
| 1031 | 1074 |
| 1032 class HChange: public HUnaryOperation { | 1075 class HChange: public HUnaryOperation { |
| 1033 public: | 1076 public: |
| 1034 HChange(HValue* value, | 1077 HChange(HValue* value, |
| 1035 Representation from, | 1078 Representation from, |
| 1036 Representation to, | 1079 Representation to, |
| 1037 bool is_truncating) | 1080 bool is_truncating, |
| 1038 : HUnaryOperation(value), from_(from) { | 1081 bool deoptimize_on_undefined) |
| 1082 : HUnaryOperation(value), |
| 1083 from_(from), |
| 1084 deoptimize_on_undefined_(deoptimize_on_undefined) { |
| 1039 ASSERT(!from.IsNone() && !to.IsNone()); | 1085 ASSERT(!from.IsNone() && !to.IsNone()); |
| 1040 ASSERT(!from.Equals(to)); | 1086 ASSERT(!from.Equals(to)); |
| 1041 set_representation(to); | 1087 set_representation(to); |
| 1042 SetFlag(kUseGVN); | 1088 SetFlag(kUseGVN); |
| 1043 if (is_truncating) SetFlag(kTruncatingToInt32); | 1089 if (is_truncating) SetFlag(kTruncatingToInt32); |
| 1044 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL && | 1090 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL && |
| 1045 value->range()->IsInSmiRange()) { | 1091 value->range()->IsInSmiRange()) { |
| 1046 set_type(HType::Smi()); | 1092 set_type(HType::Smi()); |
| 1047 } | 1093 } |
| 1048 } | 1094 } |
| 1049 | 1095 |
| 1050 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 1096 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
| 1051 | 1097 |
| 1052 Representation from() const { return from_; } | 1098 Representation from() const { return from_; } |
| 1053 Representation to() const { return representation(); } | 1099 Representation to() const { return representation(); } |
| 1100 bool deoptimize_on_undefined() const { return deoptimize_on_undefined_; } |
| 1054 virtual Representation RequiredInputRepresentation(int index) const { | 1101 virtual Representation RequiredInputRepresentation(int index) const { |
| 1055 return from_; | 1102 return from_; |
| 1056 } | 1103 } |
| 1057 | 1104 |
| 1058 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); } | |
| 1059 | |
| 1060 virtual void PrintDataTo(StringStream* stream); | 1105 virtual void PrintDataTo(StringStream* stream); |
| 1061 | 1106 |
| 1062 DECLARE_CONCRETE_INSTRUCTION(Change) | 1107 DECLARE_CONCRETE_INSTRUCTION(Change) |
| 1063 | 1108 |
| 1064 protected: | 1109 protected: |
| 1065 virtual bool DataEquals(HValue* other) { | 1110 virtual bool DataEquals(HValue* other) { |
| 1066 if (!other->IsChange()) return false; | 1111 if (!other->IsChange()) return false; |
| 1067 HChange* change = HChange::cast(other); | 1112 HChange* change = HChange::cast(other); |
| 1068 return value() == change->value() | 1113 return to().Equals(change->to()) |
| 1069 && to().Equals(change->to()); | 1114 && deoptimize_on_undefined() == change->deoptimize_on_undefined(); |
| 1070 } | 1115 } |
| 1071 | 1116 |
| 1072 private: | 1117 private: |
| 1073 Representation from_; | 1118 Representation from_; |
| 1119 bool deoptimize_on_undefined_; |
| 1074 }; | 1120 }; |
| 1075 | 1121 |
| 1076 | 1122 |
| 1077 class HClampToUint8: public HUnaryOperation { | 1123 class HClampToUint8: public HUnaryOperation { |
| 1078 public: | 1124 public: |
| 1079 explicit HClampToUint8(HValue* value) | 1125 explicit HClampToUint8(HValue* value) |
| 1080 : HUnaryOperation(value), | 1126 : HUnaryOperation(value), |
| 1081 input_rep_(Representation::None()) { | 1127 input_rep_(Representation::None()) { |
| 1082 SetFlag(kFlexibleRepresentation); | 1128 SetFlag(kFlexibleRepresentation); |
| 1083 set_representation(Representation::Tagged()); | 1129 set_representation(Representation::Tagged()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1107 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8) | 1153 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8) |
| 1108 | 1154 |
| 1109 protected: | 1155 protected: |
| 1110 virtual bool DataEquals(HValue* other) { return true; } | 1156 virtual bool DataEquals(HValue* other) { return true; } |
| 1111 | 1157 |
| 1112 private: | 1158 private: |
| 1113 Representation input_rep_; | 1159 Representation input_rep_; |
| 1114 }; | 1160 }; |
| 1115 | 1161 |
| 1116 | 1162 |
| 1163 class HToInt32: public HUnaryOperation { |
| 1164 public: |
| 1165 explicit HToInt32(HValue* value) |
| 1166 : HUnaryOperation(value) { |
| 1167 set_representation(Representation::Integer32()); |
| 1168 SetFlag(kUseGVN); |
| 1169 } |
| 1170 |
| 1171 virtual Representation RequiredInputRepresentation(int index) const { |
| 1172 return Representation::None(); |
| 1173 } |
| 1174 |
| 1175 virtual bool CanTruncateToInt32() const { |
| 1176 return true; |
| 1177 } |
| 1178 |
| 1179 virtual HValue* Canonicalize() { |
| 1180 if (value()->representation().IsInteger32()) { |
| 1181 return value(); |
| 1182 } else { |
| 1183 return this; |
| 1184 } |
| 1185 } |
| 1186 |
| 1187 DECLARE_CONCRETE_INSTRUCTION(ToInt32) |
| 1188 |
| 1189 protected: |
| 1190 virtual bool DataEquals(HValue* other) { return true; } |
| 1191 }; |
| 1192 |
| 1193 |
| 1117 class HSimulate: public HInstruction { | 1194 class HSimulate: public HInstruction { |
| 1118 public: | 1195 public: |
| 1119 HSimulate(int ast_id, int pop_count) | 1196 HSimulate(int ast_id, int pop_count) |
| 1120 : ast_id_(ast_id), | 1197 : ast_id_(ast_id), |
| 1121 pop_count_(pop_count), | 1198 pop_count_(pop_count), |
| 1122 values_(2), | 1199 values_(2), |
| 1123 assigned_indexes_(2) {} | 1200 assigned_indexes_(2) {} |
| 1124 virtual ~HSimulate() {} | 1201 virtual ~HSimulate() {} |
| 1125 | 1202 |
| 1126 virtual void PrintDataTo(StringStream* stream); | 1203 virtual void PrintDataTo(StringStream* stream); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1175 // use lists are correctly updated. | 1252 // use lists are correctly updated. |
| 1176 SetOperandAt(values_.length() - 1, value); | 1253 SetOperandAt(values_.length() - 1, value); |
| 1177 } | 1254 } |
| 1178 int ast_id_; | 1255 int ast_id_; |
| 1179 int pop_count_; | 1256 int pop_count_; |
| 1180 ZoneList<HValue*> values_; | 1257 ZoneList<HValue*> values_; |
| 1181 ZoneList<int> assigned_indexes_; | 1258 ZoneList<int> assigned_indexes_; |
| 1182 }; | 1259 }; |
| 1183 | 1260 |
| 1184 | 1261 |
| 1185 class HStackCheck: public HTemplateInstruction<0> { | 1262 class HStackCheck: public HTemplateInstruction<1> { |
| 1186 public: | 1263 public: |
| 1187 HStackCheck() { } | 1264 enum Type { |
| 1265 kFunctionEntry, |
| 1266 kBackwardsBranch |
| 1267 }; |
| 1268 |
| 1269 HStackCheck(HValue* context, Type type) : type_(type) { |
| 1270 SetOperandAt(0, context); |
| 1271 } |
| 1272 |
| 1273 HValue* context() { return OperandAt(0); } |
| 1188 | 1274 |
| 1189 virtual Representation RequiredInputRepresentation(int index) const { | 1275 virtual Representation RequiredInputRepresentation(int index) const { |
| 1190 return Representation::None(); | 1276 return Representation::Tagged(); |
| 1191 } | 1277 } |
| 1192 | 1278 |
| 1279 void Eliminate() { |
| 1280 // The stack check eliminator might try to eliminate the same stack |
| 1281 // check instruction multiple times. |
| 1282 if (IsLinked()) { |
| 1283 DeleteFromGraph(); |
| 1284 } |
| 1285 } |
| 1286 |
| 1287 bool is_function_entry() { return type_ == kFunctionEntry; } |
| 1288 bool is_backwards_branch() { return type_ == kBackwardsBranch; } |
| 1289 |
| 1193 DECLARE_CONCRETE_INSTRUCTION(StackCheck) | 1290 DECLARE_CONCRETE_INSTRUCTION(StackCheck) |
| 1291 |
| 1292 private: |
| 1293 Type type_; |
| 1194 }; | 1294 }; |
| 1195 | 1295 |
| 1196 | 1296 |
| 1197 class HEnterInlined: public HTemplateInstruction<0> { | 1297 class HEnterInlined: public HTemplateInstruction<0> { |
| 1198 public: | 1298 public: |
| 1199 HEnterInlined(Handle<JSFunction> closure, | 1299 HEnterInlined(Handle<JSFunction> closure, |
| 1200 FunctionLiteral* function, | 1300 FunctionLiteral* function, |
| 1201 CallKind call_kind) | 1301 CallKind call_kind) |
| 1202 : closure_(closure), | 1302 : closure_(closure), |
| 1203 function_(function), | 1303 function_(function), |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1244 virtual Representation RequiredInputRepresentation(int index) const { | 1344 virtual Representation RequiredInputRepresentation(int index) const { |
| 1245 return Representation::Tagged(); | 1345 return Representation::Tagged(); |
| 1246 } | 1346 } |
| 1247 | 1347 |
| 1248 HValue* argument() { return OperandAt(0); } | 1348 HValue* argument() { return OperandAt(0); } |
| 1249 | 1349 |
| 1250 DECLARE_CONCRETE_INSTRUCTION(PushArgument) | 1350 DECLARE_CONCRETE_INSTRUCTION(PushArgument) |
| 1251 }; | 1351 }; |
| 1252 | 1352 |
| 1253 | 1353 |
| 1354 class HThisFunction: public HTemplateInstruction<0> { |
| 1355 public: |
| 1356 HThisFunction() { |
| 1357 set_representation(Representation::Tagged()); |
| 1358 SetFlag(kUseGVN); |
| 1359 } |
| 1360 |
| 1361 virtual Representation RequiredInputRepresentation(int index) const { |
| 1362 return Representation::None(); |
| 1363 } |
| 1364 |
| 1365 DECLARE_CONCRETE_INSTRUCTION(ThisFunction) |
| 1366 |
| 1367 protected: |
| 1368 virtual bool DataEquals(HValue* other) { return true; } |
| 1369 }; |
| 1370 |
| 1371 |
| 1254 class HContext: public HTemplateInstruction<0> { | 1372 class HContext: public HTemplateInstruction<0> { |
| 1255 public: | 1373 public: |
| 1256 HContext() { | 1374 HContext() { |
| 1257 set_representation(Representation::Tagged()); | 1375 set_representation(Representation::Tagged()); |
| 1258 SetFlag(kUseGVN); | 1376 SetFlag(kUseGVN); |
| 1259 } | 1377 } |
| 1260 | 1378 |
| 1261 virtual Representation RequiredInputRepresentation(int index) const { | 1379 virtual Representation RequiredInputRepresentation(int index) const { |
| 1262 return Representation::None(); | 1380 return Representation::None(); |
| 1263 } | 1381 } |
| 1264 | 1382 |
| 1265 DECLARE_CONCRETE_INSTRUCTION(Context); | 1383 DECLARE_CONCRETE_INSTRUCTION(Context) |
| 1266 | 1384 |
| 1267 protected: | 1385 protected: |
| 1268 virtual bool DataEquals(HValue* other) { return true; } | 1386 virtual bool DataEquals(HValue* other) { return true; } |
| 1269 }; | 1387 }; |
| 1270 | 1388 |
| 1271 | 1389 |
| 1272 class HOuterContext: public HUnaryOperation { | 1390 class HOuterContext: public HUnaryOperation { |
| 1273 public: | 1391 public: |
| 1274 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) { | 1392 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) { |
| 1275 set_representation(Representation::Tagged()); | 1393 set_representation(Representation::Tagged()); |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1529 return Representation::Tagged(); | 1647 return Representation::Tagged(); |
| 1530 } | 1648 } |
| 1531 | 1649 |
| 1532 HValue* context() { return first(); } | 1650 HValue* context() { return first(); } |
| 1533 HValue* constructor() { return second(); } | 1651 HValue* constructor() { return second(); } |
| 1534 | 1652 |
| 1535 DECLARE_CONCRETE_INSTRUCTION(CallNew) | 1653 DECLARE_CONCRETE_INSTRUCTION(CallNew) |
| 1536 }; | 1654 }; |
| 1537 | 1655 |
| 1538 | 1656 |
| 1539 class HCallRuntime: public HCall<0> { | 1657 class HCallRuntime: public HCall<1> { |
| 1540 public: | 1658 public: |
| 1541 HCallRuntime(Handle<String> name, | 1659 HCallRuntime(HValue* context, |
| 1660 Handle<String> name, |
| 1542 const Runtime::Function* c_function, | 1661 const Runtime::Function* c_function, |
| 1543 int argument_count) | 1662 int argument_count) |
| 1544 : HCall<0>(argument_count), c_function_(c_function), name_(name) { } | 1663 : HCall<1>(argument_count), c_function_(c_function), name_(name) { |
| 1664 SetOperandAt(0, context); |
| 1665 } |
| 1666 |
| 1545 virtual void PrintDataTo(StringStream* stream); | 1667 virtual void PrintDataTo(StringStream* stream); |
| 1546 | 1668 |
| 1669 HValue* context() { return OperandAt(0); } |
| 1547 const Runtime::Function* function() const { return c_function_; } | 1670 const Runtime::Function* function() const { return c_function_; } |
| 1548 Handle<String> name() const { return name_; } | 1671 Handle<String> name() const { return name_; } |
| 1549 | 1672 |
| 1550 virtual Representation RequiredInputRepresentation(int index) const { | 1673 virtual Representation RequiredInputRepresentation(int index) const { |
| 1551 return Representation::None(); | 1674 return Representation::Tagged(); |
| 1552 } | 1675 } |
| 1553 | 1676 |
| 1554 DECLARE_CONCRETE_INSTRUCTION(CallRuntime) | 1677 DECLARE_CONCRETE_INSTRUCTION(CallRuntime) |
| 1555 | 1678 |
| 1556 private: | 1679 private: |
| 1557 const Runtime::Function* c_function_; | 1680 const Runtime::Function* c_function_; |
| 1558 Handle<String> name_; | 1681 Handle<String> name_; |
| 1559 }; | 1682 }; |
| 1560 | 1683 |
| 1561 | 1684 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1615 return Representation::Tagged(); | 1738 return Representation::Tagged(); |
| 1616 } | 1739 } |
| 1617 | 1740 |
| 1618 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength) | 1741 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength) |
| 1619 | 1742 |
| 1620 protected: | 1743 protected: |
| 1621 virtual bool DataEquals(HValue* other) { return true; } | 1744 virtual bool DataEquals(HValue* other) { return true; } |
| 1622 }; | 1745 }; |
| 1623 | 1746 |
| 1624 | 1747 |
| 1748 class HElementsKind: public HUnaryOperation { |
| 1749 public: |
| 1750 explicit HElementsKind(HValue* value) : HUnaryOperation(value) { |
| 1751 set_representation(Representation::Integer32()); |
| 1752 SetFlag(kUseGVN); |
| 1753 SetFlag(kDependsOnMaps); |
| 1754 } |
| 1755 |
| 1756 virtual Representation RequiredInputRepresentation(int index) const { |
| 1757 return Representation::Tagged(); |
| 1758 } |
| 1759 |
| 1760 DECLARE_CONCRETE_INSTRUCTION(ElementsKind) |
| 1761 |
| 1762 protected: |
| 1763 virtual bool DataEquals(HValue* other) { return true; } |
| 1764 }; |
| 1765 |
| 1766 |
| 1625 class HBitNot: public HUnaryOperation { | 1767 class HBitNot: public HUnaryOperation { |
| 1626 public: | 1768 public: |
| 1627 explicit HBitNot(HValue* value) : HUnaryOperation(value) { | 1769 explicit HBitNot(HValue* value) : HUnaryOperation(value) { |
| 1628 set_representation(Representation::Integer32()); | 1770 set_representation(Representation::Integer32()); |
| 1629 SetFlag(kUseGVN); | 1771 SetFlag(kUseGVN); |
| 1630 SetFlag(kTruncatingToInt32); | 1772 SetFlag(kTruncatingToInt32); |
| 1631 } | 1773 } |
| 1632 | 1774 |
| 1633 virtual Representation RequiredInputRepresentation(int index) const { | 1775 virtual Representation RequiredInputRepresentation(int index) const { |
| 1634 return Representation::Integer32(); | 1776 return Representation::Integer32(); |
| 1635 } | 1777 } |
| 1636 virtual HType CalculateInferredType(); | 1778 virtual HType CalculateInferredType(); |
| 1637 | 1779 |
| 1638 DECLARE_CONCRETE_INSTRUCTION(BitNot) | 1780 DECLARE_CONCRETE_INSTRUCTION(BitNot) |
| 1639 | 1781 |
| 1640 protected: | 1782 protected: |
| 1641 virtual bool DataEquals(HValue* other) { return true; } | 1783 virtual bool DataEquals(HValue* other) { return true; } |
| 1642 }; | 1784 }; |
| 1643 | 1785 |
| 1644 | 1786 |
| 1645 class HUnaryMathOperation: public HUnaryOperation { | 1787 class HUnaryMathOperation: public HTemplateInstruction<2> { |
| 1646 public: | 1788 public: |
| 1647 HUnaryMathOperation(HValue* value, BuiltinFunctionId op) | 1789 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) |
| 1648 : HUnaryOperation(value), op_(op) { | 1790 : op_(op) { |
| 1791 SetOperandAt(0, context); |
| 1792 SetOperandAt(1, value); |
| 1649 switch (op) { | 1793 switch (op) { |
| 1650 case kMathFloor: | 1794 case kMathFloor: |
| 1651 case kMathRound: | 1795 case kMathRound: |
| 1652 case kMathCeil: | 1796 case kMathCeil: |
| 1653 set_representation(Representation::Integer32()); | 1797 set_representation(Representation::Integer32()); |
| 1654 break; | 1798 break; |
| 1655 case kMathAbs: | 1799 case kMathAbs: |
| 1656 set_representation(Representation::Tagged()); | 1800 set_representation(Representation::Tagged()); |
| 1657 SetFlag(kFlexibleRepresentation); | 1801 SetFlag(kFlexibleRepresentation); |
| 1658 break; | 1802 break; |
| 1659 case kMathSqrt: | 1803 case kMathSqrt: |
| 1660 case kMathPowHalf: | 1804 case kMathPowHalf: |
| 1661 case kMathLog: | 1805 case kMathLog: |
| 1662 case kMathSin: | 1806 case kMathSin: |
| 1663 case kMathCos: | 1807 case kMathCos: |
| 1664 set_representation(Representation::Double()); | 1808 set_representation(Representation::Double()); |
| 1665 break; | 1809 break; |
| 1666 default: | 1810 default: |
| 1667 UNREACHABLE(); | 1811 UNREACHABLE(); |
| 1668 } | 1812 } |
| 1669 SetFlag(kUseGVN); | 1813 SetFlag(kUseGVN); |
| 1670 } | 1814 } |
| 1671 | 1815 |
| 1816 HValue* context() { return OperandAt(0); } |
| 1817 HValue* value() { return OperandAt(1); } |
| 1818 |
| 1672 virtual void PrintDataTo(StringStream* stream); | 1819 virtual void PrintDataTo(StringStream* stream); |
| 1673 | 1820 |
| 1674 virtual HType CalculateInferredType(); | 1821 virtual HType CalculateInferredType(); |
| 1675 | 1822 |
| 1676 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 1823 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
| 1677 | 1824 |
| 1678 virtual Representation RequiredInputRepresentation(int index) const { | 1825 virtual Representation RequiredInputRepresentation(int index) const { |
| 1679 switch (op_) { | 1826 if (index == 0) { |
| 1680 case kMathFloor: | 1827 return Representation::Tagged(); |
| 1681 case kMathRound: | 1828 } else { |
| 1682 case kMathCeil: | 1829 switch (op_) { |
| 1683 case kMathSqrt: | 1830 case kMathFloor: |
| 1684 case kMathPowHalf: | 1831 case kMathRound: |
| 1685 case kMathLog: | 1832 case kMathCeil: |
| 1686 case kMathSin: | 1833 case kMathSqrt: |
| 1687 case kMathCos: | 1834 case kMathPowHalf: |
| 1688 return Representation::Double(); | 1835 case kMathLog: |
| 1689 case kMathAbs: | 1836 case kMathSin: |
| 1690 return representation(); | 1837 case kMathCos: |
| 1691 default: | 1838 return Representation::Double(); |
| 1692 UNREACHABLE(); | 1839 case kMathAbs: |
| 1693 return Representation::None(); | 1840 return representation(); |
| 1841 default: |
| 1842 UNREACHABLE(); |
| 1843 return Representation::None(); |
| 1844 } |
| 1694 } | 1845 } |
| 1695 } | 1846 } |
| 1696 | 1847 |
| 1697 virtual HValue* Canonicalize() { | 1848 virtual HValue* Canonicalize() { |
| 1698 // If the input is integer32 then we replace the floor instruction | 1849 // If the input is integer32 then we replace the floor instruction |
| 1699 // with its inputs. This happens before the representation changes are | 1850 // with its inputs. This happens before the representation changes are |
| 1700 // introduced. | 1851 // introduced. |
| 1701 if (op() == kMathFloor) { | 1852 if (op() == kMathFloor) { |
| 1702 if (value()->representation().IsInteger32()) return value(); | 1853 if (value()->representation().IsInteger32()) return value(); |
| 1703 } | 1854 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1764 | 1915 |
| 1765 class HCheckMap: public HUnaryOperation { | 1916 class HCheckMap: public HUnaryOperation { |
| 1766 public: | 1917 public: |
| 1767 HCheckMap(HValue* value, Handle<Map> map) | 1918 HCheckMap(HValue* value, Handle<Map> map) |
| 1768 : HUnaryOperation(value), map_(map) { | 1919 : HUnaryOperation(value), map_(map) { |
| 1769 set_representation(Representation::Tagged()); | 1920 set_representation(Representation::Tagged()); |
| 1770 SetFlag(kUseGVN); | 1921 SetFlag(kUseGVN); |
| 1771 SetFlag(kDependsOnMaps); | 1922 SetFlag(kDependsOnMaps); |
| 1772 } | 1923 } |
| 1773 | 1924 |
| 1774 virtual bool IsCheckInstruction() const { return true; } | |
| 1775 | |
| 1776 virtual Representation RequiredInputRepresentation(int index) const { | 1925 virtual Representation RequiredInputRepresentation(int index) const { |
| 1777 return Representation::Tagged(); | 1926 return Representation::Tagged(); |
| 1778 } | 1927 } |
| 1779 virtual void PrintDataTo(StringStream* stream); | 1928 virtual void PrintDataTo(StringStream* stream); |
| 1780 virtual HType CalculateInferredType(); | 1929 virtual HType CalculateInferredType(); |
| 1781 | 1930 |
| 1782 #ifdef DEBUG | 1931 #ifdef DEBUG |
| 1783 virtual void Verify(); | 1932 virtual void Verify(); |
| 1784 #endif | 1933 #endif |
| 1785 | 1934 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1799 | 1948 |
| 1800 | 1949 |
| 1801 class HCheckFunction: public HUnaryOperation { | 1950 class HCheckFunction: public HUnaryOperation { |
| 1802 public: | 1951 public: |
| 1803 HCheckFunction(HValue* value, Handle<JSFunction> function) | 1952 HCheckFunction(HValue* value, Handle<JSFunction> function) |
| 1804 : HUnaryOperation(value), target_(function) { | 1953 : HUnaryOperation(value), target_(function) { |
| 1805 set_representation(Representation::Tagged()); | 1954 set_representation(Representation::Tagged()); |
| 1806 SetFlag(kUseGVN); | 1955 SetFlag(kUseGVN); |
| 1807 } | 1956 } |
| 1808 | 1957 |
| 1809 virtual bool IsCheckInstruction() const { return true; } | |
| 1810 | |
| 1811 virtual Representation RequiredInputRepresentation(int index) const { | 1958 virtual Representation RequiredInputRepresentation(int index) const { |
| 1812 return Representation::Tagged(); | 1959 return Representation::Tagged(); |
| 1813 } | 1960 } |
| 1814 virtual void PrintDataTo(StringStream* stream); | 1961 virtual void PrintDataTo(StringStream* stream); |
| 1815 virtual HType CalculateInferredType(); | 1962 virtual HType CalculateInferredType(); |
| 1816 | 1963 |
| 1817 #ifdef DEBUG | 1964 #ifdef DEBUG |
| 1818 virtual void Verify(); | 1965 virtual void Verify(); |
| 1819 #endif | 1966 #endif |
| 1820 | 1967 |
| 1821 Handle<JSFunction> target() const { return target_; } | 1968 Handle<JSFunction> target() const { return target_; } |
| 1822 | 1969 |
| 1823 DECLARE_CONCRETE_INSTRUCTION(CheckFunction) | 1970 DECLARE_CONCRETE_INSTRUCTION(CheckFunction) |
| 1824 | 1971 |
| 1825 protected: | 1972 protected: |
| 1826 virtual bool DataEquals(HValue* other) { | 1973 virtual bool DataEquals(HValue* other) { |
| 1827 HCheckFunction* b = HCheckFunction::cast(other); | 1974 HCheckFunction* b = HCheckFunction::cast(other); |
| 1828 return target_.is_identical_to(b->target()); | 1975 return target_.is_identical_to(b->target()); |
| 1829 } | 1976 } |
| 1830 | 1977 |
| 1831 private: | 1978 private: |
| 1832 Handle<JSFunction> target_; | 1979 Handle<JSFunction> target_; |
| 1833 }; | 1980 }; |
| 1834 | 1981 |
| 1835 | 1982 |
| 1836 class HCheckInstanceType: public HUnaryOperation { | 1983 class HCheckInstanceType: public HUnaryOperation { |
| 1837 public: | 1984 public: |
| 1838 static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value) { | 1985 static HCheckInstanceType* NewIsSpecObject(HValue* value) { |
| 1839 return new HCheckInstanceType(value, IS_JS_OBJECT_OR_JS_FUNCTION); | 1986 return new HCheckInstanceType(value, IS_SPEC_OBJECT); |
| 1840 } | 1987 } |
| 1841 static HCheckInstanceType* NewIsJSArray(HValue* value) { | 1988 static HCheckInstanceType* NewIsJSArray(HValue* value) { |
| 1842 return new HCheckInstanceType(value, IS_JS_ARRAY); | 1989 return new HCheckInstanceType(value, IS_JS_ARRAY); |
| 1843 } | 1990 } |
| 1844 static HCheckInstanceType* NewIsString(HValue* value) { | 1991 static HCheckInstanceType* NewIsString(HValue* value) { |
| 1845 return new HCheckInstanceType(value, IS_STRING); | 1992 return new HCheckInstanceType(value, IS_STRING); |
| 1846 } | 1993 } |
| 1847 static HCheckInstanceType* NewIsSymbol(HValue* value) { | 1994 static HCheckInstanceType* NewIsSymbol(HValue* value) { |
| 1848 return new HCheckInstanceType(value, IS_SYMBOL); | 1995 return new HCheckInstanceType(value, IS_SYMBOL); |
| 1849 } | 1996 } |
| 1850 | 1997 |
| 1851 virtual bool IsCheckInstruction() const { return true; } | |
| 1852 | |
| 1853 virtual Representation RequiredInputRepresentation(int index) const { | 1998 virtual Representation RequiredInputRepresentation(int index) const { |
| 1854 return Representation::Tagged(); | 1999 return Representation::Tagged(); |
| 1855 } | 2000 } |
| 1856 | 2001 |
| 1857 #ifdef DEBUG | 2002 #ifdef DEBUG |
| 1858 virtual void Verify(); | 2003 virtual void Verify(); |
| 1859 #endif | 2004 #endif |
| 1860 | 2005 |
| 1861 virtual HValue* Canonicalize() { | 2006 virtual HValue* Canonicalize(); |
| 1862 if (!value()->type().IsUninitialized() && | |
| 1863 value()->type().IsString() && | |
| 1864 check_ == IS_STRING) { | |
| 1865 return NULL; | |
| 1866 } | |
| 1867 return this; | |
| 1868 } | |
| 1869 | 2007 |
| 1870 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; } | 2008 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; } |
| 1871 void GetCheckInterval(InstanceType* first, InstanceType* last); | 2009 void GetCheckInterval(InstanceType* first, InstanceType* last); |
| 1872 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag); | 2010 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag); |
| 1873 | 2011 |
| 1874 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType) | 2012 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType) |
| 1875 | 2013 |
| 1876 protected: | 2014 protected: |
| 1877 // TODO(ager): It could be nice to allow the ommision of instance | 2015 // TODO(ager): It could be nice to allow the ommision of instance |
| 1878 // type checks if we have already performed an instance type check | 2016 // type checks if we have already performed an instance type check |
| 1879 // with a larger range. | 2017 // with a larger range. |
| 1880 virtual bool DataEquals(HValue* other) { | 2018 virtual bool DataEquals(HValue* other) { |
| 1881 HCheckInstanceType* b = HCheckInstanceType::cast(other); | 2019 HCheckInstanceType* b = HCheckInstanceType::cast(other); |
| 1882 return check_ == b->check_; | 2020 return check_ == b->check_; |
| 1883 } | 2021 } |
| 1884 | 2022 |
| 1885 private: | 2023 private: |
| 1886 enum Check { | 2024 enum Check { |
| 1887 IS_JS_OBJECT_OR_JS_FUNCTION, | 2025 IS_SPEC_OBJECT, |
| 1888 IS_JS_ARRAY, | 2026 IS_JS_ARRAY, |
| 1889 IS_STRING, | 2027 IS_STRING, |
| 1890 IS_SYMBOL, | 2028 IS_SYMBOL, |
| 1891 LAST_INTERVAL_CHECK = IS_JS_ARRAY | 2029 LAST_INTERVAL_CHECK = IS_JS_ARRAY |
| 1892 }; | 2030 }; |
| 1893 | 2031 |
| 1894 HCheckInstanceType(HValue* value, Check check) | 2032 HCheckInstanceType(HValue* value, Check check) |
| 1895 : HUnaryOperation(value), check_(check) { | 2033 : HUnaryOperation(value), check_(check) { |
| 1896 set_representation(Representation::Tagged()); | 2034 set_representation(Representation::Tagged()); |
| 1897 SetFlag(kUseGVN); | 2035 SetFlag(kUseGVN); |
| 1898 } | 2036 } |
| 1899 | 2037 |
| 1900 const Check check_; | 2038 const Check check_; |
| 1901 }; | 2039 }; |
| 1902 | 2040 |
| 1903 | 2041 |
| 1904 class HCheckNonSmi: public HUnaryOperation { | 2042 class HCheckNonSmi: public HUnaryOperation { |
| 1905 public: | 2043 public: |
| 1906 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) { | 2044 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) { |
| 1907 set_representation(Representation::Tagged()); | 2045 set_representation(Representation::Tagged()); |
| 1908 SetFlag(kUseGVN); | 2046 SetFlag(kUseGVN); |
| 1909 } | 2047 } |
| 1910 | 2048 |
| 1911 virtual bool IsCheckInstruction() const { return true; } | |
| 1912 | |
| 1913 virtual Representation RequiredInputRepresentation(int index) const { | 2049 virtual Representation RequiredInputRepresentation(int index) const { |
| 1914 return Representation::Tagged(); | 2050 return Representation::Tagged(); |
| 1915 } | 2051 } |
| 1916 | 2052 |
| 1917 virtual HType CalculateInferredType(); | 2053 virtual HType CalculateInferredType(); |
| 1918 | 2054 |
| 1919 #ifdef DEBUG | 2055 #ifdef DEBUG |
| 1920 virtual void Verify(); | 2056 virtual void Verify(); |
| 1921 #endif | 2057 #endif |
| 1922 | 2058 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1940 | 2076 |
| 1941 | 2077 |
| 1942 class HCheckPrototypeMaps: public HTemplateInstruction<0> { | 2078 class HCheckPrototypeMaps: public HTemplateInstruction<0> { |
| 1943 public: | 2079 public: |
| 1944 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder) | 2080 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder) |
| 1945 : prototype_(prototype), holder_(holder) { | 2081 : prototype_(prototype), holder_(holder) { |
| 1946 SetFlag(kUseGVN); | 2082 SetFlag(kUseGVN); |
| 1947 SetFlag(kDependsOnMaps); | 2083 SetFlag(kDependsOnMaps); |
| 1948 } | 2084 } |
| 1949 | 2085 |
| 1950 virtual bool IsCheckInstruction() const { return true; } | |
| 1951 | |
| 1952 #ifdef DEBUG | 2086 #ifdef DEBUG |
| 1953 virtual void Verify(); | 2087 virtual void Verify(); |
| 1954 #endif | 2088 #endif |
| 1955 | 2089 |
| 1956 Handle<JSObject> prototype() const { return prototype_; } | 2090 Handle<JSObject> prototype() const { return prototype_; } |
| 1957 Handle<JSObject> holder() const { return holder_; } | 2091 Handle<JSObject> holder() const { return holder_; } |
| 1958 | 2092 |
| 1959 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps) | 2093 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps) |
| 1960 | 2094 |
| 1961 virtual Representation RequiredInputRepresentation(int index) const { | 2095 virtual Representation RequiredInputRepresentation(int index) const { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1982 }; | 2116 }; |
| 1983 | 2117 |
| 1984 | 2118 |
| 1985 class HCheckSmi: public HUnaryOperation { | 2119 class HCheckSmi: public HUnaryOperation { |
| 1986 public: | 2120 public: |
| 1987 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) { | 2121 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) { |
| 1988 set_representation(Representation::Tagged()); | 2122 set_representation(Representation::Tagged()); |
| 1989 SetFlag(kUseGVN); | 2123 SetFlag(kUseGVN); |
| 1990 } | 2124 } |
| 1991 | 2125 |
| 1992 virtual bool IsCheckInstruction() const { return true; } | |
| 1993 | |
| 1994 virtual Representation RequiredInputRepresentation(int index) const { | 2126 virtual Representation RequiredInputRepresentation(int index) const { |
| 1995 return Representation::Tagged(); | 2127 return Representation::Tagged(); |
| 1996 } | 2128 } |
| 1997 virtual HType CalculateInferredType(); | 2129 virtual HType CalculateInferredType(); |
| 1998 | 2130 |
| 1999 #ifdef DEBUG | 2131 #ifdef DEBUG |
| 2000 virtual void Verify(); | 2132 virtual void Verify(); |
| 2001 #endif | 2133 #endif |
| 2002 | 2134 |
| 2003 DECLARE_CONCRETE_INSTRUCTION(CheckSmi) | 2135 DECLARE_CONCRETE_INSTRUCTION(CheckSmi) |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2198 // The following two values represent the int32 and the double value of the | 2330 // The following two values represent the int32 and the double value of the |
| 2199 // given constant if there is a lossless conversion between the constant | 2331 // given constant if there is a lossless conversion between the constant |
| 2200 // and the specific representation. | 2332 // and the specific representation. |
| 2201 bool has_int32_value_ : 1; | 2333 bool has_int32_value_ : 1; |
| 2202 bool has_double_value_ : 1; | 2334 bool has_double_value_ : 1; |
| 2203 int32_t int32_value_; | 2335 int32_t int32_value_; |
| 2204 double double_value_; | 2336 double double_value_; |
| 2205 }; | 2337 }; |
| 2206 | 2338 |
| 2207 | 2339 |
| 2208 class HBinaryOperation: public HTemplateInstruction<2> { | 2340 class HBinaryOperation: public HTemplateInstruction<3> { |
| 2209 public: | 2341 public: |
| 2210 HBinaryOperation(HValue* left, HValue* right) { | 2342 HBinaryOperation(HValue* context, HValue* left, HValue* right) { |
| 2211 ASSERT(left != NULL && right != NULL); | 2343 ASSERT(left != NULL && right != NULL); |
| 2212 SetOperandAt(0, left); | 2344 SetOperandAt(0, context); |
| 2213 SetOperandAt(1, right); | 2345 SetOperandAt(1, left); |
| 2346 SetOperandAt(2, right); |
| 2214 } | 2347 } |
| 2215 | 2348 |
| 2216 HValue* left() { return OperandAt(0); } | 2349 HValue* context() { return OperandAt(0); } |
| 2217 HValue* right() { return OperandAt(1); } | 2350 HValue* left() { return OperandAt(1); } |
| 2351 HValue* right() { return OperandAt(2); } |
| 2218 | 2352 |
| 2219 // TODO(kasperl): Move these helpers to the IA-32 Lithium | 2353 // TODO(kasperl): Move these helpers to the IA-32 Lithium |
| 2220 // instruction sequence builder. | 2354 // instruction sequence builder. |
| 2221 HValue* LeastConstantOperand() { | 2355 HValue* LeastConstantOperand() { |
| 2222 if (IsCommutative() && left()->IsConstant()) return right(); | 2356 if (IsCommutative() && left()->IsConstant()) return right(); |
| 2223 return left(); | 2357 return left(); |
| 2224 } | 2358 } |
| 2225 HValue* MostConstantOperand() { | 2359 HValue* MostConstantOperand() { |
| 2226 if (IsCommutative() && left()->IsConstant()) return left(); | 2360 if (IsCommutative() && left()->IsConstant()) return left(); |
| 2227 return right(); | 2361 return right(); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2323 HValue* arguments() { return OperandAt(0); } | 2457 HValue* arguments() { return OperandAt(0); } |
| 2324 HValue* length() { return OperandAt(1); } | 2458 HValue* length() { return OperandAt(1); } |
| 2325 HValue* index() { return OperandAt(2); } | 2459 HValue* index() { return OperandAt(2); } |
| 2326 | 2460 |
| 2327 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt) | 2461 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt) |
| 2328 | 2462 |
| 2329 virtual bool DataEquals(HValue* other) { return true; } | 2463 virtual bool DataEquals(HValue* other) { return true; } |
| 2330 }; | 2464 }; |
| 2331 | 2465 |
| 2332 | 2466 |
| 2333 class HBoundsCheck: public HBinaryOperation { | 2467 class HBoundsCheck: public HTemplateInstruction<2> { |
| 2334 public: | 2468 public: |
| 2335 HBoundsCheck(HValue* index, HValue* length) | 2469 HBoundsCheck(HValue* index, HValue* length) { |
| 2336 : HBinaryOperation(index, length) { | 2470 SetOperandAt(0, index); |
| 2471 SetOperandAt(1, length); |
| 2472 set_representation(Representation::Integer32()); |
| 2337 SetFlag(kUseGVN); | 2473 SetFlag(kUseGVN); |
| 2338 } | 2474 } |
| 2339 | 2475 |
| 2340 virtual bool IsCheckInstruction() const { return true; } | |
| 2341 | |
| 2342 virtual Representation RequiredInputRepresentation(int index) const { | 2476 virtual Representation RequiredInputRepresentation(int index) const { |
| 2343 return Representation::Integer32(); | 2477 return Representation::Integer32(); |
| 2344 } | 2478 } |
| 2345 | 2479 |
| 2346 #ifdef DEBUG | 2480 #ifdef DEBUG |
| 2347 virtual void Verify(); | 2481 virtual void Verify(); |
| 2348 #endif | 2482 #endif |
| 2349 | 2483 |
| 2350 HValue* index() { return left(); } | 2484 HValue* index() { return OperandAt(0); } |
| 2351 HValue* length() { return right(); } | 2485 HValue* length() { return OperandAt(1); } |
| 2352 | 2486 |
| 2353 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) | 2487 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) |
| 2354 | 2488 |
| 2355 protected: | 2489 protected: |
| 2356 virtual bool DataEquals(HValue* other) { return true; } | 2490 virtual bool DataEquals(HValue* other) { return true; } |
| 2357 }; | 2491 }; |
| 2358 | 2492 |
| 2359 | 2493 |
| 2360 class HBitwiseBinaryOperation: public HBinaryOperation { | 2494 class HBitwiseBinaryOperation: public HBinaryOperation { |
| 2361 public: | 2495 public: |
| 2362 HBitwiseBinaryOperation(HValue* left, HValue* right) | 2496 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) |
| 2363 : HBinaryOperation(left, right) { | 2497 : HBinaryOperation(context, left, right) { |
| 2364 set_representation(Representation::Tagged()); | 2498 set_representation(Representation::Tagged()); |
| 2365 SetFlag(kFlexibleRepresentation); | 2499 SetFlag(kFlexibleRepresentation); |
| 2366 SetAllSideEffects(); | 2500 SetAllSideEffects(); |
| 2367 } | 2501 } |
| 2368 | 2502 |
| 2369 virtual Representation RequiredInputRepresentation(int index) const { | 2503 virtual Representation RequiredInputRepresentation(int index) const { |
| 2370 return representation(); | 2504 return index == 0 |
| 2505 ? Representation::Tagged() |
| 2506 : representation(); |
| 2371 } | 2507 } |
| 2372 | 2508 |
| 2373 virtual void RepresentationChanged(Representation to) { | 2509 virtual void RepresentationChanged(Representation to) { |
| 2374 if (!to.IsTagged()) { | 2510 if (!to.IsTagged()) { |
| 2375 ASSERT(to.IsInteger32()); | 2511 ASSERT(to.IsInteger32()); |
| 2376 ClearAllSideEffects(); | 2512 ClearAllSideEffects(); |
| 2377 SetFlag(kTruncatingToInt32); | 2513 SetFlag(kTruncatingToInt32); |
| 2378 SetFlag(kUseGVN); | 2514 SetFlag(kUseGVN); |
| 2379 } | 2515 } |
| 2380 } | 2516 } |
| 2381 | 2517 |
| 2382 virtual HType CalculateInferredType(); | 2518 virtual HType CalculateInferredType(); |
| 2383 | 2519 |
| 2384 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation) | 2520 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation) |
| 2385 }; | 2521 }; |
| 2386 | 2522 |
| 2387 | 2523 |
| 2388 class HArithmeticBinaryOperation: public HBinaryOperation { | 2524 class HArithmeticBinaryOperation: public HBinaryOperation { |
| 2389 public: | 2525 public: |
| 2390 HArithmeticBinaryOperation(HValue* left, HValue* right) | 2526 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right) |
| 2391 : HBinaryOperation(left, right) { | 2527 : HBinaryOperation(context, left, right) { |
| 2392 set_representation(Representation::Tagged()); | 2528 set_representation(Representation::Tagged()); |
| 2393 SetFlag(kFlexibleRepresentation); | 2529 SetFlag(kFlexibleRepresentation); |
| 2394 SetAllSideEffects(); | 2530 SetAllSideEffects(); |
| 2395 } | 2531 } |
| 2396 | 2532 |
| 2397 virtual void RepresentationChanged(Representation to) { | 2533 virtual void RepresentationChanged(Representation to) { |
| 2398 if (!to.IsTagged()) { | 2534 if (!to.IsTagged()) { |
| 2399 ClearAllSideEffects(); | 2535 ClearAllSideEffects(); |
| 2400 SetFlag(kUseGVN); | 2536 SetFlag(kUseGVN); |
| 2401 } | 2537 } |
| 2402 } | 2538 } |
| 2403 | 2539 |
| 2404 virtual HType CalculateInferredType(); | 2540 virtual HType CalculateInferredType(); |
| 2405 virtual Representation RequiredInputRepresentation(int index) const { | 2541 virtual Representation RequiredInputRepresentation(int index) const { |
| 2406 return representation(); | 2542 return index == 0 |
| 2543 ? Representation::Tagged() |
| 2544 : representation(); |
| 2407 } | 2545 } |
| 2546 |
| 2408 virtual Representation InferredRepresentation() { | 2547 virtual Representation InferredRepresentation() { |
| 2409 if (left()->representation().Equals(right()->representation())) { | 2548 if (left()->representation().Equals(right()->representation())) { |
| 2410 return left()->representation(); | 2549 return left()->representation(); |
| 2411 } | 2550 } |
| 2412 return HValue::InferredRepresentation(); | 2551 return HValue::InferredRepresentation(); |
| 2413 } | 2552 } |
| 2414 }; | 2553 }; |
| 2415 | 2554 |
| 2416 | 2555 |
| 2417 class HCompare: public HBinaryOperation { | 2556 class HCompareGeneric: public HBinaryOperation { |
| 2418 public: | 2557 public: |
| 2419 HCompare(HValue* left, HValue* right, Token::Value token) | 2558 HCompareGeneric(HValue* context, |
| 2420 : HBinaryOperation(left, right), token_(token) { | 2559 HValue* left, |
| 2560 HValue* right, |
| 2561 Token::Value token) |
| 2562 : HBinaryOperation(context, left, right), token_(token) { |
| 2421 ASSERT(Token::IsCompareOp(token)); | 2563 ASSERT(Token::IsCompareOp(token)); |
| 2422 set_representation(Representation::Tagged()); | 2564 set_representation(Representation::Tagged()); |
| 2423 SetAllSideEffects(); | 2565 SetAllSideEffects(); |
| 2424 } | 2566 } |
| 2425 | 2567 |
| 2568 virtual Representation RequiredInputRepresentation(int index) const { |
| 2569 return Representation::Tagged(); |
| 2570 } |
| 2571 |
| 2572 Representation GetInputRepresentation() const { |
| 2573 return Representation::Tagged(); |
| 2574 } |
| 2575 |
| 2576 Token::Value token() const { return token_; } |
| 2577 virtual void PrintDataTo(StringStream* stream); |
| 2578 |
| 2579 virtual HType CalculateInferredType(); |
| 2580 |
| 2581 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric) |
| 2582 |
| 2583 private: |
| 2584 Token::Value token_; |
| 2585 }; |
| 2586 |
| 2587 |
| 2588 class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> { |
| 2589 public: |
| 2590 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token) |
| 2591 : token_(token) { |
| 2592 ASSERT(Token::IsCompareOp(token)); |
| 2593 SetOperandAt(0, left); |
| 2594 SetOperandAt(1, right); |
| 2595 } |
| 2596 |
| 2597 HValue* left() { return OperandAt(0); } |
| 2598 HValue* right() { return OperandAt(1); } |
| 2599 Token::Value token() const { return token_; } |
| 2600 |
| 2426 void SetInputRepresentation(Representation r); | 2601 void SetInputRepresentation(Representation r); |
| 2427 | 2602 Representation GetInputRepresentation() const { |
| 2428 virtual bool EmitAtUses() { | 2603 return input_representation_; |
| 2429 return !HasSideEffects() && !HasMultipleUses(); | |
| 2430 } | 2604 } |
| 2431 | 2605 |
| 2432 virtual Representation RequiredInputRepresentation(int index) const { | 2606 virtual Representation RequiredInputRepresentation(int index) const { |
| 2433 return input_representation_; | 2607 return input_representation_; |
| 2434 } | 2608 } |
| 2435 Representation GetInputRepresentation() const { | |
| 2436 return input_representation_; | |
| 2437 } | |
| 2438 Token::Value token() const { return token_; } | |
| 2439 virtual void PrintDataTo(StringStream* stream); | 2609 virtual void PrintDataTo(StringStream* stream); |
| 2440 | 2610 |
| 2441 virtual HType CalculateInferredType(); | 2611 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch) |
| 2442 | |
| 2443 virtual intptr_t Hashcode() { | |
| 2444 return HValue::Hashcode() * 7 + token_; | |
| 2445 } | |
| 2446 | |
| 2447 DECLARE_CONCRETE_INSTRUCTION(Compare) | |
| 2448 | |
| 2449 protected: | |
| 2450 virtual bool DataEquals(HValue* other) { | |
| 2451 HCompare* comp = HCompare::cast(other); | |
| 2452 return token_ == comp->token(); | |
| 2453 } | |
| 2454 | 2612 |
| 2455 private: | 2613 private: |
| 2456 Representation input_representation_; | 2614 Representation input_representation_; |
| 2457 Token::Value token_; | 2615 Token::Value token_; |
| 2458 }; | 2616 }; |
| 2459 | 2617 |
| 2460 | 2618 |
| 2461 class HCompareJSObjectEq: public HBinaryOperation { | 2619 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> { |
| 2462 public: | 2620 public: |
| 2463 HCompareJSObjectEq(HValue* left, HValue* right) | 2621 HCompareObjectEqAndBranch(HValue* left, HValue* right) { |
| 2464 : HBinaryOperation(left, right) { | 2622 SetOperandAt(0, left); |
| 2465 set_representation(Representation::Tagged()); | 2623 SetOperandAt(1, right); |
| 2466 SetFlag(kUseGVN); | |
| 2467 SetFlag(kDependsOnMaps); | |
| 2468 } | 2624 } |
| 2469 | 2625 |
| 2470 virtual bool EmitAtUses() { | 2626 HValue* left() { return OperandAt(0); } |
| 2471 return !HasSideEffects() && !HasMultipleUses(); | 2627 HValue* right() { return OperandAt(1); } |
| 2472 } | |
| 2473 | 2628 |
| 2474 virtual Representation RequiredInputRepresentation(int index) const { | 2629 virtual Representation RequiredInputRepresentation(int index) const { |
| 2475 return Representation::Tagged(); | 2630 return Representation::Tagged(); |
| 2476 } | 2631 } |
| 2477 virtual HType CalculateInferredType(); | |
| 2478 | 2632 |
| 2479 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq) | 2633 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch) |
| 2634 }; |
| 2635 |
| 2636 |
| 2637 class HCompareConstantEqAndBranch: public HUnaryControlInstruction { |
| 2638 public: |
| 2639 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op) |
| 2640 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) { |
| 2641 ASSERT(op == Token::EQ_STRICT); |
| 2642 } |
| 2643 |
| 2644 Token::Value op() const { return op_; } |
| 2645 HValue* left() { return value(); } |
| 2646 int right() const { return right_; } |
| 2647 |
| 2648 virtual Representation RequiredInputRepresentation(int index) const { |
| 2649 return Representation::Integer32(); |
| 2650 } |
| 2651 |
| 2652 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch); |
| 2653 |
| 2654 private: |
| 2655 const Token::Value op_; |
| 2656 const int right_; |
| 2657 }; |
| 2658 |
| 2659 |
| 2660 class HIsNullAndBranch: public HUnaryControlInstruction { |
| 2661 public: |
| 2662 HIsNullAndBranch(HValue* value, bool is_strict) |
| 2663 : HUnaryControlInstruction(value, NULL, NULL), is_strict_(is_strict) { } |
| 2664 |
| 2665 bool is_strict() const { return is_strict_; } |
| 2666 |
| 2667 virtual Representation RequiredInputRepresentation(int index) const { |
| 2668 return Representation::Tagged(); |
| 2669 } |
| 2670 |
| 2671 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch) |
| 2672 |
| 2673 private: |
| 2674 bool is_strict_; |
| 2675 }; |
| 2676 |
| 2677 |
| 2678 class HIsObjectAndBranch: public HUnaryControlInstruction { |
| 2679 public: |
| 2680 explicit HIsObjectAndBranch(HValue* value) |
| 2681 : HUnaryControlInstruction(value, NULL, NULL) { } |
| 2682 |
| 2683 virtual Representation RequiredInputRepresentation(int index) const { |
| 2684 return Representation::Tagged(); |
| 2685 } |
| 2686 |
| 2687 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch) |
| 2688 }; |
| 2689 |
| 2690 |
| 2691 class HIsSmiAndBranch: public HUnaryControlInstruction { |
| 2692 public: |
| 2693 explicit HIsSmiAndBranch(HValue* value) |
| 2694 : HUnaryControlInstruction(value, NULL, NULL) { } |
| 2695 |
| 2696 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch) |
| 2697 |
| 2698 virtual Representation RequiredInputRepresentation(int index) const { |
| 2699 return Representation::Tagged(); |
| 2700 } |
| 2480 | 2701 |
| 2481 protected: | 2702 protected: |
| 2482 virtual bool DataEquals(HValue* other) { return true; } | 2703 virtual bool DataEquals(HValue* other) { return true; } |
| 2483 }; | 2704 }; |
| 2484 | 2705 |
| 2485 | 2706 |
| 2486 class HCompareSymbolEq: public HBinaryOperation { | 2707 class HIsUndetectableAndBranch: public HUnaryControlInstruction { |
| 2487 public: | 2708 public: |
| 2488 HCompareSymbolEq(HValue* left, HValue* right, Token::Value op) | 2709 explicit HIsUndetectableAndBranch(HValue* value) |
| 2489 : HBinaryOperation(left, right), op_(op) { | 2710 : HUnaryControlInstruction(value, NULL, NULL) { } |
| 2490 ASSERT(op == Token::EQ || op == Token::EQ_STRICT); | |
| 2491 set_representation(Representation::Tagged()); | |
| 2492 SetFlag(kUseGVN); | |
| 2493 SetFlag(kDependsOnMaps); | |
| 2494 } | |
| 2495 | |
| 2496 Token::Value op() const { return op_; } | |
| 2497 | |
| 2498 virtual bool EmitAtUses() { | |
| 2499 return !HasSideEffects() && !HasMultipleUses(); | |
| 2500 } | |
| 2501 | 2711 |
| 2502 virtual Representation RequiredInputRepresentation(int index) const { | 2712 virtual Representation RequiredInputRepresentation(int index) const { |
| 2503 return Representation::Tagged(); | 2713 return Representation::Tagged(); |
| 2504 } | 2714 } |
| 2505 | 2715 |
| 2506 virtual HType CalculateInferredType() { return HType::Boolean(); } | 2716 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch) |
| 2507 | |
| 2508 DECLARE_CONCRETE_INSTRUCTION(CompareSymbolEq); | |
| 2509 | |
| 2510 protected: | |
| 2511 virtual bool DataEquals(HValue* other) { | |
| 2512 return op_ == HCompareSymbolEq::cast(other)->op_; | |
| 2513 } | |
| 2514 | |
| 2515 private: | |
| 2516 const Token::Value op_; | |
| 2517 }; | 2717 }; |
| 2518 | 2718 |
| 2519 | 2719 |
| 2520 class HUnaryPredicate: public HUnaryOperation { | 2720 class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> { |
| 2521 public: | 2721 public: |
| 2522 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) { | |
| 2523 set_representation(Representation::Tagged()); | |
| 2524 SetFlag(kUseGVN); | |
| 2525 } | |
| 2526 | |
| 2527 virtual bool EmitAtUses() { | |
| 2528 return !HasSideEffects() && !HasMultipleUses(); | |
| 2529 } | |
| 2530 | |
| 2531 virtual Representation RequiredInputRepresentation(int index) const { | |
| 2532 return Representation::Tagged(); | |
| 2533 } | |
| 2534 virtual HType CalculateInferredType(); | |
| 2535 }; | |
| 2536 | |
| 2537 | |
| 2538 class HIsNull: public HUnaryPredicate { | |
| 2539 public: | |
| 2540 HIsNull(HValue* value, bool is_strict) | |
| 2541 : HUnaryPredicate(value), is_strict_(is_strict) { } | |
| 2542 | |
| 2543 bool is_strict() const { return is_strict_; } | |
| 2544 | |
| 2545 DECLARE_CONCRETE_INSTRUCTION(IsNull) | |
| 2546 | |
| 2547 protected: | |
| 2548 virtual bool DataEquals(HValue* other) { | |
| 2549 HIsNull* b = HIsNull::cast(other); | |
| 2550 return is_strict_ == b->is_strict(); | |
| 2551 } | |
| 2552 | |
| 2553 private: | |
| 2554 bool is_strict_; | |
| 2555 }; | |
| 2556 | |
| 2557 | |
| 2558 class HIsObject: public HUnaryPredicate { | |
| 2559 public: | |
| 2560 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { } | |
| 2561 | |
| 2562 DECLARE_CONCRETE_INSTRUCTION(IsObject) | |
| 2563 | |
| 2564 protected: | |
| 2565 virtual bool DataEquals(HValue* other) { return true; } | |
| 2566 }; | |
| 2567 | |
| 2568 | |
| 2569 class HIsSmi: public HUnaryPredicate { | |
| 2570 public: | |
| 2571 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { } | |
| 2572 | |
| 2573 DECLARE_CONCRETE_INSTRUCTION(IsSmi) | |
| 2574 | |
| 2575 protected: | |
| 2576 virtual bool DataEquals(HValue* other) { return true; } | |
| 2577 }; | |
| 2578 | |
| 2579 | |
| 2580 class HIsUndetectable: public HUnaryPredicate { | |
| 2581 public: | |
| 2582 explicit HIsUndetectable(HValue* value) : HUnaryPredicate(value) { } | |
| 2583 | |
| 2584 DECLARE_CONCRETE_INSTRUCTION(IsUndetectable) | |
| 2585 | |
| 2586 protected: | |
| 2587 virtual bool DataEquals(HValue* other) { return true; } | |
| 2588 }; | |
| 2589 | |
| 2590 | |
| 2591 class HIsConstructCall: public HTemplateInstruction<0> { | |
| 2592 public: | |
| 2593 HIsConstructCall() { | |
| 2594 set_representation(Representation::Tagged()); | |
| 2595 SetFlag(kUseGVN); | |
| 2596 } | |
| 2597 | |
| 2598 virtual bool EmitAtUses() { | |
| 2599 return !HasSideEffects() && !HasMultipleUses(); | |
| 2600 } | |
| 2601 | |
| 2602 virtual Representation RequiredInputRepresentation(int index) const { | 2722 virtual Representation RequiredInputRepresentation(int index) const { |
| 2603 return Representation::None(); | 2723 return Representation::None(); |
| 2604 } | 2724 } |
| 2605 | 2725 |
| 2606 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall) | 2726 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch) |
| 2607 | |
| 2608 protected: | |
| 2609 virtual bool DataEquals(HValue* other) { return true; } | |
| 2610 }; | 2727 }; |
| 2611 | 2728 |
| 2612 | 2729 |
| 2613 class HHasInstanceType: public HUnaryPredicate { | 2730 class HHasInstanceTypeAndBranch: public HUnaryControlInstruction { |
| 2614 public: | 2731 public: |
| 2615 HHasInstanceType(HValue* value, InstanceType type) | 2732 HHasInstanceTypeAndBranch(HValue* value, InstanceType type) |
| 2616 : HUnaryPredicate(value), from_(type), to_(type) { } | 2733 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { } |
| 2617 HHasInstanceType(HValue* value, InstanceType from, InstanceType to) | 2734 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to) |
| 2618 : HUnaryPredicate(value), from_(from), to_(to) { | 2735 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) { |
| 2619 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend. | 2736 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend. |
| 2620 } | 2737 } |
| 2621 | 2738 |
| 2622 InstanceType from() { return from_; } | 2739 InstanceType from() { return from_; } |
| 2623 InstanceType to() { return to_; } | 2740 InstanceType to() { return to_; } |
| 2624 | 2741 |
| 2625 virtual void PrintDataTo(StringStream* stream); | 2742 virtual void PrintDataTo(StringStream* stream); |
| 2626 | 2743 |
| 2627 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType) | 2744 virtual Representation RequiredInputRepresentation(int index) const { |
| 2745 return Representation::Tagged(); |
| 2746 } |
| 2628 | 2747 |
| 2629 protected: | 2748 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch) |
| 2630 virtual bool DataEquals(HValue* other) { | |
| 2631 HHasInstanceType* b = HHasInstanceType::cast(other); | |
| 2632 return (from_ == b->from()) && (to_ == b->to()); | |
| 2633 } | |
| 2634 | 2749 |
| 2635 private: | 2750 private: |
| 2636 InstanceType from_; | 2751 InstanceType from_; |
| 2637 InstanceType to_; // Inclusive range, not all combinations work. | 2752 InstanceType to_; // Inclusive range, not all combinations work. |
| 2638 }; | 2753 }; |
| 2639 | 2754 |
| 2640 | 2755 |
| 2641 class HHasCachedArrayIndex: public HUnaryPredicate { | 2756 class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction { |
| 2642 public: | 2757 public: |
| 2643 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { } | 2758 explicit HHasCachedArrayIndexAndBranch(HValue* value) |
| 2759 : HUnaryControlInstruction(value, NULL, NULL) { } |
| 2644 | 2760 |
| 2645 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex) | 2761 virtual Representation RequiredInputRepresentation(int index) const { |
| 2762 return Representation::Tagged(); |
| 2763 } |
| 2646 | 2764 |
| 2647 protected: | 2765 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch) |
| 2648 virtual bool DataEquals(HValue* other) { return true; } | |
| 2649 }; | 2766 }; |
| 2650 | 2767 |
| 2651 | 2768 |
| 2652 class HGetCachedArrayIndex: public HUnaryPredicate { | 2769 class HGetCachedArrayIndex: public HUnaryOperation { |
| 2653 public: | 2770 public: |
| 2654 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { } | 2771 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) { |
| 2772 set_representation(Representation::Tagged()); |
| 2773 SetFlag(kUseGVN); |
| 2774 } |
| 2775 |
| 2776 virtual Representation RequiredInputRepresentation(int index) const { |
| 2777 return Representation::Tagged(); |
| 2778 } |
| 2655 | 2779 |
| 2656 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex) | 2780 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex) |
| 2657 | 2781 |
| 2658 protected: | 2782 protected: |
| 2659 virtual bool DataEquals(HValue* other) { return true; } | 2783 virtual bool DataEquals(HValue* other) { return true; } |
| 2660 }; | 2784 }; |
| 2661 | 2785 |
| 2662 | 2786 |
| 2663 class HClassOfTest: public HUnaryPredicate { | 2787 class HClassOfTestAndBranch: public HUnaryControlInstruction { |
| 2664 public: | 2788 public: |
| 2665 HClassOfTest(HValue* value, Handle<String> class_name) | 2789 HClassOfTestAndBranch(HValue* value, Handle<String> class_name) |
| 2666 : HUnaryPredicate(value), class_name_(class_name) { } | 2790 : HUnaryControlInstruction(value, NULL, NULL), |
| 2791 class_name_(class_name) { } |
| 2667 | 2792 |
| 2668 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest) | 2793 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch) |
| 2794 |
| 2795 virtual Representation RequiredInputRepresentation(int index) const { |
| 2796 return Representation::Tagged(); |
| 2797 } |
| 2669 | 2798 |
| 2670 virtual void PrintDataTo(StringStream* stream); | 2799 virtual void PrintDataTo(StringStream* stream); |
| 2671 | 2800 |
| 2672 Handle<String> class_name() const { return class_name_; } | 2801 Handle<String> class_name() const { return class_name_; } |
| 2673 | 2802 |
| 2674 protected: | |
| 2675 virtual bool DataEquals(HValue* other) { | |
| 2676 HClassOfTest* b = HClassOfTest::cast(other); | |
| 2677 return class_name_.is_identical_to(b->class_name_); | |
| 2678 } | |
| 2679 | |
| 2680 private: | 2803 private: |
| 2681 Handle<String> class_name_; | 2804 Handle<String> class_name_; |
| 2682 }; | 2805 }; |
| 2683 | 2806 |
| 2684 | 2807 |
| 2685 class HTypeofIs: public HUnaryPredicate { | 2808 class HTypeofIsAndBranch: public HUnaryControlInstruction { |
| 2686 public: | 2809 public: |
| 2687 HTypeofIs(HValue* value, Handle<String> type_literal) | 2810 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal) |
| 2688 : HUnaryPredicate(value), type_literal_(type_literal) { } | 2811 : HUnaryControlInstruction(value, NULL, NULL), |
| 2812 type_literal_(type_literal) { } |
| 2689 | 2813 |
| 2690 Handle<String> type_literal() { return type_literal_; } | 2814 Handle<String> type_literal() { return type_literal_; } |
| 2691 virtual void PrintDataTo(StringStream* stream); | 2815 virtual void PrintDataTo(StringStream* stream); |
| 2692 | 2816 |
| 2693 DECLARE_CONCRETE_INSTRUCTION(TypeofIs) | 2817 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch) |
| 2694 | 2818 |
| 2695 protected: | 2819 virtual Representation RequiredInputRepresentation(int index) const { |
| 2696 virtual bool DataEquals(HValue* other) { | 2820 return Representation::Tagged(); |
| 2697 HTypeofIs* b = HTypeofIs::cast(other); | |
| 2698 return type_literal_.is_identical_to(b->type_literal_); | |
| 2699 } | 2821 } |
| 2700 | 2822 |
| 2701 private: | 2823 private: |
| 2702 Handle<String> type_literal_; | 2824 Handle<String> type_literal_; |
| 2703 }; | 2825 }; |
| 2704 | 2826 |
| 2705 | 2827 |
| 2706 class HInstanceOf: public HTemplateInstruction<3> { | 2828 class HInstanceOf: public HBinaryOperation { |
| 2707 public: | 2829 public: |
| 2708 HInstanceOf(HValue* context, HValue* left, HValue* right) { | 2830 HInstanceOf(HValue* context, HValue* left, HValue* right) |
| 2709 SetOperandAt(0, context); | 2831 : HBinaryOperation(context, left, right) { |
| 2710 SetOperandAt(1, left); | |
| 2711 SetOperandAt(2, right); | |
| 2712 set_representation(Representation::Tagged()); | 2832 set_representation(Representation::Tagged()); |
| 2713 SetAllSideEffects(); | 2833 SetAllSideEffects(); |
| 2714 } | 2834 } |
| 2715 | 2835 |
| 2716 HValue* context() { return OperandAt(0); } | |
| 2717 HValue* left() { return OperandAt(1); } | |
| 2718 HValue* right() { return OperandAt(2); } | |
| 2719 | |
| 2720 virtual bool EmitAtUses() { | |
| 2721 return !HasSideEffects() && !HasMultipleUses(); | |
| 2722 } | |
| 2723 | |
| 2724 virtual Representation RequiredInputRepresentation(int index) const { | 2836 virtual Representation RequiredInputRepresentation(int index) const { |
| 2725 return Representation::Tagged(); | 2837 return Representation::Tagged(); |
| 2726 } | 2838 } |
| 2727 | 2839 |
| 2840 virtual HType CalculateInferredType(); |
| 2841 |
| 2728 virtual void PrintDataTo(StringStream* stream); | 2842 virtual void PrintDataTo(StringStream* stream); |
| 2729 | 2843 |
| 2730 DECLARE_CONCRETE_INSTRUCTION(InstanceOf) | 2844 DECLARE_CONCRETE_INSTRUCTION(InstanceOf) |
| 2731 }; | 2845 }; |
| 2732 | 2846 |
| 2733 | 2847 |
| 2734 class HInstanceOfKnownGlobal: public HUnaryOperation { | 2848 class HInstanceOfKnownGlobal: public HTemplateInstruction<2> { |
| 2735 public: | 2849 public: |
| 2736 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right) | 2850 HInstanceOfKnownGlobal(HValue* context, |
| 2737 : HUnaryOperation(left), function_(right) { | 2851 HValue* left, |
| 2852 Handle<JSFunction> right) |
| 2853 : function_(right) { |
| 2854 SetOperandAt(0, context); |
| 2855 SetOperandAt(1, left); |
| 2738 set_representation(Representation::Tagged()); | 2856 set_representation(Representation::Tagged()); |
| 2739 SetAllSideEffects(); | 2857 SetAllSideEffects(); |
| 2740 } | 2858 } |
| 2741 | 2859 |
| 2860 HValue* context() { return OperandAt(0); } |
| 2861 HValue* left() { return OperandAt(1); } |
| 2742 Handle<JSFunction> function() { return function_; } | 2862 Handle<JSFunction> function() { return function_; } |
| 2743 | 2863 |
| 2744 virtual Representation RequiredInputRepresentation(int index) const { | 2864 virtual Representation RequiredInputRepresentation(int index) const { |
| 2745 return Representation::Tagged(); | 2865 return Representation::Tagged(); |
| 2746 } | 2866 } |
| 2747 | 2867 |
| 2868 virtual HType CalculateInferredType(); |
| 2869 |
| 2748 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal) | 2870 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal) |
| 2749 | 2871 |
| 2750 private: | 2872 private: |
| 2751 Handle<JSFunction> function_; | 2873 Handle<JSFunction> function_; |
| 2752 }; | 2874 }; |
| 2753 | 2875 |
| 2754 | 2876 |
| 2755 class HPower: public HBinaryOperation { | 2877 class HPower: public HTemplateInstruction<2> { |
| 2756 public: | 2878 public: |
| 2757 HPower(HValue* left, HValue* right) | 2879 HPower(HValue* left, HValue* right) { |
| 2758 : HBinaryOperation(left, right) { | 2880 SetOperandAt(0, left); |
| 2881 SetOperandAt(1, right); |
| 2759 set_representation(Representation::Double()); | 2882 set_representation(Representation::Double()); |
| 2760 SetFlag(kUseGVN); | 2883 SetFlag(kUseGVN); |
| 2761 } | 2884 } |
| 2762 | 2885 |
| 2886 HValue* left() { return OperandAt(0); } |
| 2887 HValue* right() { return OperandAt(1); } |
| 2888 |
| 2763 virtual Representation RequiredInputRepresentation(int index) const { | 2889 virtual Representation RequiredInputRepresentation(int index) const { |
| 2764 return (index == 1) ? Representation::None() : Representation::Double(); | 2890 return index == 0 |
| 2891 ? Representation::Double() |
| 2892 : Representation::None(); |
| 2765 } | 2893 } |
| 2766 | 2894 |
| 2767 DECLARE_CONCRETE_INSTRUCTION(Power) | 2895 DECLARE_CONCRETE_INSTRUCTION(Power) |
| 2768 | 2896 |
| 2769 protected: | 2897 protected: |
| 2770 virtual bool DataEquals(HValue* other) { return true; } | 2898 virtual bool DataEquals(HValue* other) { return true; } |
| 2771 }; | 2899 }; |
| 2772 | 2900 |
| 2773 | 2901 |
| 2774 class HAdd: public HArithmeticBinaryOperation { | 2902 class HAdd: public HArithmeticBinaryOperation { |
| 2775 public: | 2903 public: |
| 2776 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) { | 2904 HAdd(HValue* context, HValue* left, HValue* right) |
| 2905 : HArithmeticBinaryOperation(context, left, right) { |
| 2777 SetFlag(kCanOverflow); | 2906 SetFlag(kCanOverflow); |
| 2778 } | 2907 } |
| 2779 | 2908 |
| 2780 // Add is only commutative if two integer values are added and not if two | 2909 // Add is only commutative if two integer values are added and not if two |
| 2781 // tagged values are added (because it might be a String concatenation). | 2910 // tagged values are added (because it might be a String concatenation). |
| 2782 virtual bool IsCommutative() const { | 2911 virtual bool IsCommutative() const { |
| 2783 return !representation().IsTagged(); | 2912 return !representation().IsTagged(); |
| 2784 } | 2913 } |
| 2785 | 2914 |
| 2786 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 2915 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
| 2787 | 2916 |
| 2788 virtual HType CalculateInferredType(); | 2917 virtual HType CalculateInferredType(); |
| 2789 | 2918 |
| 2790 DECLARE_CONCRETE_INSTRUCTION(Add) | 2919 DECLARE_CONCRETE_INSTRUCTION(Add) |
| 2791 | 2920 |
| 2792 protected: | 2921 protected: |
| 2793 virtual bool DataEquals(HValue* other) { return true; } | 2922 virtual bool DataEquals(HValue* other) { return true; } |
| 2794 | 2923 |
| 2795 virtual Range* InferRange(); | 2924 virtual Range* InferRange(); |
| 2796 }; | 2925 }; |
| 2797 | 2926 |
| 2798 | 2927 |
| 2799 class HSub: public HArithmeticBinaryOperation { | 2928 class HSub: public HArithmeticBinaryOperation { |
| 2800 public: | 2929 public: |
| 2801 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) { | 2930 HSub(HValue* context, HValue* left, HValue* right) |
| 2931 : HArithmeticBinaryOperation(context, left, right) { |
| 2802 SetFlag(kCanOverflow); | 2932 SetFlag(kCanOverflow); |
| 2803 } | 2933 } |
| 2804 | 2934 |
| 2805 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 2935 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
| 2806 | 2936 |
| 2807 DECLARE_CONCRETE_INSTRUCTION(Sub) | 2937 DECLARE_CONCRETE_INSTRUCTION(Sub) |
| 2808 | 2938 |
| 2809 protected: | 2939 protected: |
| 2810 virtual bool DataEquals(HValue* other) { return true; } | 2940 virtual bool DataEquals(HValue* other) { return true; } |
| 2811 | 2941 |
| 2812 virtual Range* InferRange(); | 2942 virtual Range* InferRange(); |
| 2813 }; | 2943 }; |
| 2814 | 2944 |
| 2815 | 2945 |
| 2816 class HMul: public HArithmeticBinaryOperation { | 2946 class HMul: public HArithmeticBinaryOperation { |
| 2817 public: | 2947 public: |
| 2818 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) { | 2948 HMul(HValue* context, HValue* left, HValue* right) |
| 2949 : HArithmeticBinaryOperation(context, left, right) { |
| 2819 SetFlag(kCanOverflow); | 2950 SetFlag(kCanOverflow); |
| 2820 } | 2951 } |
| 2821 | 2952 |
| 2822 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 2953 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
| 2823 | 2954 |
| 2824 // Only commutative if it is certain that not two objects are multiplicated. | 2955 // Only commutative if it is certain that not two objects are multiplicated. |
| 2825 virtual bool IsCommutative() const { | 2956 virtual bool IsCommutative() const { |
| 2826 return !representation().IsTagged(); | 2957 return !representation().IsTagged(); |
| 2827 } | 2958 } |
| 2828 | 2959 |
| 2829 DECLARE_CONCRETE_INSTRUCTION(Mul) | 2960 DECLARE_CONCRETE_INSTRUCTION(Mul) |
| 2830 | 2961 |
| 2831 protected: | 2962 protected: |
| 2832 virtual bool DataEquals(HValue* other) { return true; } | 2963 virtual bool DataEquals(HValue* other) { return true; } |
| 2833 | 2964 |
| 2834 virtual Range* InferRange(); | 2965 virtual Range* InferRange(); |
| 2835 }; | 2966 }; |
| 2836 | 2967 |
| 2837 | 2968 |
| 2838 class HMod: public HArithmeticBinaryOperation { | 2969 class HMod: public HArithmeticBinaryOperation { |
| 2839 public: | 2970 public: |
| 2840 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) { | 2971 HMod(HValue* context, HValue* left, HValue* right) |
| 2972 : HArithmeticBinaryOperation(context, left, right) { |
| 2841 SetFlag(kCanBeDivByZero); | 2973 SetFlag(kCanBeDivByZero); |
| 2842 } | 2974 } |
| 2843 | 2975 |
| 2844 bool HasPowerOf2Divisor() { | 2976 bool HasPowerOf2Divisor() { |
| 2845 if (right()->IsConstant() && | 2977 if (right()->IsConstant() && |
| 2846 HConstant::cast(right())->HasInteger32Value()) { | 2978 HConstant::cast(right())->HasInteger32Value()) { |
| 2847 int32_t value = HConstant::cast(right())->Integer32Value(); | 2979 int32_t value = HConstant::cast(right())->Integer32Value(); |
| 2848 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); | 2980 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); |
| 2849 } | 2981 } |
| 2850 | 2982 |
| 2851 return false; | 2983 return false; |
| 2852 } | 2984 } |
| 2853 | 2985 |
| 2854 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 2986 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
| 2855 | 2987 |
| 2856 DECLARE_CONCRETE_INSTRUCTION(Mod) | 2988 DECLARE_CONCRETE_INSTRUCTION(Mod) |
| 2857 | 2989 |
| 2858 protected: | 2990 protected: |
| 2859 virtual bool DataEquals(HValue* other) { return true; } | 2991 virtual bool DataEquals(HValue* other) { return true; } |
| 2860 | 2992 |
| 2861 virtual Range* InferRange(); | 2993 virtual Range* InferRange(); |
| 2862 }; | 2994 }; |
| 2863 | 2995 |
| 2864 | 2996 |
| 2865 class HDiv: public HArithmeticBinaryOperation { | 2997 class HDiv: public HArithmeticBinaryOperation { |
| 2866 public: | 2998 public: |
| 2867 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) { | 2999 HDiv(HValue* context, HValue* left, HValue* right) |
| 3000 : HArithmeticBinaryOperation(context, left, right) { |
| 2868 SetFlag(kCanBeDivByZero); | 3001 SetFlag(kCanBeDivByZero); |
| 2869 SetFlag(kCanOverflow); | 3002 SetFlag(kCanOverflow); |
| 2870 } | 3003 } |
| 2871 | 3004 |
| 2872 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 3005 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
| 2873 | 3006 |
| 2874 DECLARE_CONCRETE_INSTRUCTION(Div) | 3007 DECLARE_CONCRETE_INSTRUCTION(Div) |
| 2875 | 3008 |
| 2876 protected: | 3009 protected: |
| 2877 virtual bool DataEquals(HValue* other) { return true; } | 3010 virtual bool DataEquals(HValue* other) { return true; } |
| 2878 | 3011 |
| 2879 virtual Range* InferRange(); | 3012 virtual Range* InferRange(); |
| 2880 }; | 3013 }; |
| 2881 | 3014 |
| 2882 | 3015 |
| 2883 class HBitAnd: public HBitwiseBinaryOperation { | 3016 class HBitAnd: public HBitwiseBinaryOperation { |
| 2884 public: | 3017 public: |
| 2885 HBitAnd(HValue* left, HValue* right) | 3018 HBitAnd(HValue* context, HValue* left, HValue* right) |
| 2886 : HBitwiseBinaryOperation(left, right) { } | 3019 : HBitwiseBinaryOperation(context, left, right) { } |
| 2887 | 3020 |
| 2888 virtual bool IsCommutative() const { return true; } | 3021 virtual bool IsCommutative() const { return true; } |
| 2889 virtual HType CalculateInferredType(); | 3022 virtual HType CalculateInferredType(); |
| 2890 | 3023 |
| 2891 DECLARE_CONCRETE_INSTRUCTION(BitAnd) | 3024 DECLARE_CONCRETE_INSTRUCTION(BitAnd) |
| 2892 | 3025 |
| 2893 protected: | 3026 protected: |
| 2894 virtual bool DataEquals(HValue* other) { return true; } | 3027 virtual bool DataEquals(HValue* other) { return true; } |
| 2895 | 3028 |
| 2896 virtual Range* InferRange(); | 3029 virtual Range* InferRange(); |
| 2897 }; | 3030 }; |
| 2898 | 3031 |
| 2899 | 3032 |
| 2900 class HBitXor: public HBitwiseBinaryOperation { | 3033 class HBitXor: public HBitwiseBinaryOperation { |
| 2901 public: | 3034 public: |
| 2902 HBitXor(HValue* left, HValue* right) | 3035 HBitXor(HValue* context, HValue* left, HValue* right) |
| 2903 : HBitwiseBinaryOperation(left, right) { } | 3036 : HBitwiseBinaryOperation(context, left, right) { } |
| 2904 | 3037 |
| 2905 virtual bool IsCommutative() const { return true; } | 3038 virtual bool IsCommutative() const { return true; } |
| 2906 virtual HType CalculateInferredType(); | 3039 virtual HType CalculateInferredType(); |
| 2907 | 3040 |
| 2908 DECLARE_CONCRETE_INSTRUCTION(BitXor) | 3041 DECLARE_CONCRETE_INSTRUCTION(BitXor) |
| 2909 | 3042 |
| 2910 protected: | 3043 protected: |
| 2911 virtual bool DataEquals(HValue* other) { return true; } | 3044 virtual bool DataEquals(HValue* other) { return true; } |
| 2912 }; | 3045 }; |
| 2913 | 3046 |
| 2914 | 3047 |
| 2915 class HBitOr: public HBitwiseBinaryOperation { | 3048 class HBitOr: public HBitwiseBinaryOperation { |
| 2916 public: | 3049 public: |
| 2917 HBitOr(HValue* left, HValue* right) | 3050 HBitOr(HValue* context, HValue* left, HValue* right) |
| 2918 : HBitwiseBinaryOperation(left, right) { } | 3051 : HBitwiseBinaryOperation(context, left, right) { } |
| 2919 | 3052 |
| 2920 virtual bool IsCommutative() const { return true; } | 3053 virtual bool IsCommutative() const { return true; } |
| 2921 virtual HType CalculateInferredType(); | 3054 virtual HType CalculateInferredType(); |
| 2922 | 3055 |
| 2923 DECLARE_CONCRETE_INSTRUCTION(BitOr) | 3056 DECLARE_CONCRETE_INSTRUCTION(BitOr) |
| 2924 | 3057 |
| 2925 protected: | 3058 protected: |
| 2926 virtual bool DataEquals(HValue* other) { return true; } | 3059 virtual bool DataEquals(HValue* other) { return true; } |
| 2927 | 3060 |
| 2928 virtual Range* InferRange(); | 3061 virtual Range* InferRange(); |
| 2929 }; | 3062 }; |
| 2930 | 3063 |
| 2931 | 3064 |
| 2932 class HShl: public HBitwiseBinaryOperation { | 3065 class HShl: public HBitwiseBinaryOperation { |
| 2933 public: | 3066 public: |
| 2934 HShl(HValue* left, HValue* right) | 3067 HShl(HValue* context, HValue* left, HValue* right) |
| 2935 : HBitwiseBinaryOperation(left, right) { } | 3068 : HBitwiseBinaryOperation(context, left, right) { } |
| 2936 | 3069 |
| 2937 virtual Range* InferRange(); | 3070 virtual Range* InferRange(); |
| 2938 virtual HType CalculateInferredType(); | 3071 virtual HType CalculateInferredType(); |
| 2939 | 3072 |
| 2940 DECLARE_CONCRETE_INSTRUCTION(Shl) | 3073 DECLARE_CONCRETE_INSTRUCTION(Shl) |
| 2941 | 3074 |
| 2942 protected: | 3075 protected: |
| 2943 virtual bool DataEquals(HValue* other) { return true; } | 3076 virtual bool DataEquals(HValue* other) { return true; } |
| 2944 }; | 3077 }; |
| 2945 | 3078 |
| 2946 | 3079 |
| 2947 class HShr: public HBitwiseBinaryOperation { | 3080 class HShr: public HBitwiseBinaryOperation { |
| 2948 public: | 3081 public: |
| 2949 HShr(HValue* left, HValue* right) | 3082 HShr(HValue* context, HValue* left, HValue* right) |
| 2950 : HBitwiseBinaryOperation(left, right) { } | 3083 : HBitwiseBinaryOperation(context, left, right) { } |
| 2951 | 3084 |
| 2952 virtual HType CalculateInferredType(); | 3085 virtual HType CalculateInferredType(); |
| 2953 | 3086 |
| 2954 DECLARE_CONCRETE_INSTRUCTION(Shr) | 3087 DECLARE_CONCRETE_INSTRUCTION(Shr) |
| 2955 | 3088 |
| 2956 protected: | 3089 protected: |
| 2957 virtual bool DataEquals(HValue* other) { return true; } | 3090 virtual bool DataEquals(HValue* other) { return true; } |
| 2958 }; | 3091 }; |
| 2959 | 3092 |
| 2960 | 3093 |
| 2961 class HSar: public HBitwiseBinaryOperation { | 3094 class HSar: public HBitwiseBinaryOperation { |
| 2962 public: | 3095 public: |
| 2963 HSar(HValue* left, HValue* right) | 3096 HSar(HValue* context, HValue* left, HValue* right) |
| 2964 : HBitwiseBinaryOperation(left, right) { } | 3097 : HBitwiseBinaryOperation(context, left, right) { } |
| 2965 | 3098 |
| 2966 virtual Range* InferRange(); | 3099 virtual Range* InferRange(); |
| 2967 virtual HType CalculateInferredType(); | 3100 virtual HType CalculateInferredType(); |
| 2968 | 3101 |
| 2969 DECLARE_CONCRETE_INSTRUCTION(Sar) | 3102 DECLARE_CONCRETE_INSTRUCTION(Sar) |
| 2970 | 3103 |
| 2971 protected: | 3104 protected: |
| 2972 virtual bool DataEquals(HValue* other) { return true; } | 3105 virtual bool DataEquals(HValue* other) { return true; } |
| 2973 }; | 3106 }; |
| 2974 | 3107 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3088 HLoadGlobalCell* b = HLoadGlobalCell::cast(other); | 3221 HLoadGlobalCell* b = HLoadGlobalCell::cast(other); |
| 3089 return cell_.is_identical_to(b->cell()); | 3222 return cell_.is_identical_to(b->cell()); |
| 3090 } | 3223 } |
| 3091 | 3224 |
| 3092 private: | 3225 private: |
| 3093 Handle<JSGlobalPropertyCell> cell_; | 3226 Handle<JSGlobalPropertyCell> cell_; |
| 3094 bool check_hole_value_; | 3227 bool check_hole_value_; |
| 3095 }; | 3228 }; |
| 3096 | 3229 |
| 3097 | 3230 |
| 3098 class HLoadGlobalGeneric: public HBinaryOperation { | 3231 class HLoadGlobalGeneric: public HTemplateInstruction<2> { |
| 3099 public: | 3232 public: |
| 3100 HLoadGlobalGeneric(HValue* context, | 3233 HLoadGlobalGeneric(HValue* context, |
| 3101 HValue* global_object, | 3234 HValue* global_object, |
| 3102 Handle<Object> name, | 3235 Handle<Object> name, |
| 3103 bool for_typeof) | 3236 bool for_typeof) |
| 3104 : HBinaryOperation(context, global_object), | 3237 : name_(name), |
| 3105 name_(name), | |
| 3106 for_typeof_(for_typeof) { | 3238 for_typeof_(for_typeof) { |
| 3239 SetOperandAt(0, context); |
| 3240 SetOperandAt(1, global_object); |
| 3107 set_representation(Representation::Tagged()); | 3241 set_representation(Representation::Tagged()); |
| 3108 SetAllSideEffects(); | 3242 SetAllSideEffects(); |
| 3109 } | 3243 } |
| 3110 | 3244 |
| 3111 HValue* context() { return OperandAt(0); } | 3245 HValue* context() { return OperandAt(0); } |
| 3112 HValue* global_object() { return OperandAt(1); } | 3246 HValue* global_object() { return OperandAt(1); } |
| 3113 Handle<Object> name() const { return name_; } | 3247 Handle<Object> name() const { return name_; } |
| 3114 bool for_typeof() const { return for_typeof_; } | 3248 bool for_typeof() const { return for_typeof_; } |
| 3115 | 3249 |
| 3116 virtual void PrintDataTo(StringStream* stream); | 3250 virtual void PrintDataTo(StringStream* stream); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3214 HLoadContextSlot* b = HLoadContextSlot::cast(other); | 3348 HLoadContextSlot* b = HLoadContextSlot::cast(other); |
| 3215 return (slot_index() == b->slot_index()); | 3349 return (slot_index() == b->slot_index()); |
| 3216 } | 3350 } |
| 3217 | 3351 |
| 3218 private: | 3352 private: |
| 3219 int slot_index_; | 3353 int slot_index_; |
| 3220 }; | 3354 }; |
| 3221 | 3355 |
| 3222 | 3356 |
| 3223 static inline bool StoringValueNeedsWriteBarrier(HValue* value) { | 3357 static inline bool StoringValueNeedsWriteBarrier(HValue* value) { |
| 3358 // TODO(gc) On bleeding edge we omit write barrier when we are |
| 3359 // storing old space constant. We can't allow such an optimization |
| 3360 // on GC branch. |
| 3224 return !value->type().IsSmi(); | 3361 return !value->type().IsSmi(); |
| 3225 } | 3362 } |
| 3226 | 3363 |
| 3227 | 3364 |
| 3228 class HStoreContextSlot: public HBinaryOperation { | 3365 class HStoreContextSlot: public HTemplateInstruction<2> { |
| 3229 public: | 3366 public: |
| 3230 HStoreContextSlot(HValue* context, int slot_index, HValue* value) | 3367 HStoreContextSlot(HValue* context, int slot_index, HValue* value) |
| 3231 : HBinaryOperation(context, value), slot_index_(slot_index) { | 3368 : slot_index_(slot_index) { |
| 3369 SetOperandAt(0, context); |
| 3370 SetOperandAt(1, value); |
| 3232 SetFlag(kChangesContextSlots); | 3371 SetFlag(kChangesContextSlots); |
| 3233 } | 3372 } |
| 3234 | 3373 |
| 3235 HValue* context() { return OperandAt(0); } | 3374 HValue* context() { return OperandAt(0); } |
| 3236 HValue* value() { return OperandAt(1); } | 3375 HValue* value() { return OperandAt(1); } |
| 3237 int slot_index() const { return slot_index_; } | 3376 int slot_index() const { return slot_index_; } |
| 3238 | 3377 |
| 3239 bool NeedsWriteBarrier() { | 3378 bool NeedsWriteBarrier() { |
| 3240 return StoringValueNeedsWriteBarrier(value()); | 3379 return StoringValueNeedsWriteBarrier(value()); |
| 3241 } | 3380 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3285 HLoadNamedField* b = HLoadNamedField::cast(other); | 3424 HLoadNamedField* b = HLoadNamedField::cast(other); |
| 3286 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_; | 3425 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_; |
| 3287 } | 3426 } |
| 3288 | 3427 |
| 3289 private: | 3428 private: |
| 3290 bool is_in_object_; | 3429 bool is_in_object_; |
| 3291 int offset_; | 3430 int offset_; |
| 3292 }; | 3431 }; |
| 3293 | 3432 |
| 3294 | 3433 |
| 3295 class HLoadNamedFieldPolymorphic: public HUnaryOperation { | 3434 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { |
| 3296 public: | 3435 public: |
| 3297 HLoadNamedFieldPolymorphic(HValue* object, | 3436 HLoadNamedFieldPolymorphic(HValue* context, |
| 3437 HValue* object, |
| 3298 ZoneMapList* types, | 3438 ZoneMapList* types, |
| 3299 Handle<String> name); | 3439 Handle<String> name); |
| 3300 | 3440 |
| 3301 HValue* object() { return OperandAt(0); } | 3441 HValue* context() { return OperandAt(0); } |
| 3442 HValue* object() { return OperandAt(1); } |
| 3302 ZoneMapList* types() { return &types_; } | 3443 ZoneMapList* types() { return &types_; } |
| 3303 Handle<String> name() { return name_; } | 3444 Handle<String> name() { return name_; } |
| 3304 bool need_generic() { return need_generic_; } | 3445 bool need_generic() { return need_generic_; } |
| 3305 | 3446 |
| 3306 virtual Representation RequiredInputRepresentation(int index) const { | 3447 virtual Representation RequiredInputRepresentation(int index) const { |
| 3307 return Representation::Tagged(); | 3448 return Representation::Tagged(); |
| 3308 } | 3449 } |
| 3309 | 3450 |
| 3310 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic) | 3451 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic) |
| 3311 | 3452 |
| 3312 static const int kMaxLoadPolymorphism = 4; | 3453 static const int kMaxLoadPolymorphism = 4; |
| 3313 | 3454 |
| 3314 protected: | 3455 protected: |
| 3315 virtual bool DataEquals(HValue* value); | 3456 virtual bool DataEquals(HValue* value); |
| 3316 | 3457 |
| 3317 private: | 3458 private: |
| 3318 ZoneMapList types_; | 3459 ZoneMapList types_; |
| 3319 Handle<String> name_; | 3460 Handle<String> name_; |
| 3320 bool need_generic_; | 3461 bool need_generic_; |
| 3321 }; | 3462 }; |
| 3322 | 3463 |
| 3323 | 3464 |
| 3324 | 3465 |
| 3325 class HLoadNamedGeneric: public HBinaryOperation { | 3466 class HLoadNamedGeneric: public HTemplateInstruction<2> { |
| 3326 public: | 3467 public: |
| 3327 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name) | 3468 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name) |
| 3328 : HBinaryOperation(context, object), name_(name) { | 3469 : name_(name) { |
| 3470 SetOperandAt(0, context); |
| 3471 SetOperandAt(1, object); |
| 3329 set_representation(Representation::Tagged()); | 3472 set_representation(Representation::Tagged()); |
| 3330 SetAllSideEffects(); | 3473 SetAllSideEffects(); |
| 3331 } | 3474 } |
| 3332 | 3475 |
| 3333 HValue* context() { return OperandAt(0); } | 3476 HValue* context() { return OperandAt(0); } |
| 3334 HValue* object() { return OperandAt(1); } | 3477 HValue* object() { return OperandAt(1); } |
| 3335 Handle<Object> name() const { return name_; } | 3478 Handle<Object> name() const { return name_; } |
| 3336 | 3479 |
| 3337 virtual Representation RequiredInputRepresentation(int index) const { | 3480 virtual Representation RequiredInputRepresentation(int index) const { |
| 3338 return Representation::Tagged(); | 3481 return Representation::Tagged(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3360 return Representation::Tagged(); | 3503 return Representation::Tagged(); |
| 3361 } | 3504 } |
| 3362 | 3505 |
| 3363 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype) | 3506 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype) |
| 3364 | 3507 |
| 3365 protected: | 3508 protected: |
| 3366 virtual bool DataEquals(HValue* other) { return true; } | 3509 virtual bool DataEquals(HValue* other) { return true; } |
| 3367 }; | 3510 }; |
| 3368 | 3511 |
| 3369 | 3512 |
| 3370 class HLoadKeyedFastElement: public HBinaryOperation { | 3513 class HLoadKeyedFastElement: public HTemplateInstruction<2> { |
| 3371 public: | 3514 public: |
| 3372 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) { | 3515 HLoadKeyedFastElement(HValue* obj, HValue* key) { |
| 3516 SetOperandAt(0, obj); |
| 3517 SetOperandAt(1, key); |
| 3373 set_representation(Representation::Tagged()); | 3518 set_representation(Representation::Tagged()); |
| 3374 SetFlag(kDependsOnArrayElements); | 3519 SetFlag(kDependsOnArrayElements); |
| 3375 SetFlag(kUseGVN); | 3520 SetFlag(kUseGVN); |
| 3376 } | 3521 } |
| 3377 | 3522 |
| 3378 HValue* object() { return OperandAt(0); } | 3523 HValue* object() { return OperandAt(0); } |
| 3379 HValue* key() { return OperandAt(1); } | 3524 HValue* key() { return OperandAt(1); } |
| 3380 | 3525 |
| 3381 virtual Representation RequiredInputRepresentation(int index) const { | 3526 virtual Representation RequiredInputRepresentation(int index) const { |
| 3382 // The key is supposed to be Integer32. | 3527 // The key is supposed to be Integer32. |
| 3383 return (index == 1) ? Representation::Integer32() | 3528 return index == 0 |
| 3384 : Representation::Tagged(); | 3529 ? Representation::Tagged() |
| 3530 : Representation::Integer32(); |
| 3385 } | 3531 } |
| 3386 | 3532 |
| 3387 virtual void PrintDataTo(StringStream* stream); | 3533 virtual void PrintDataTo(StringStream* stream); |
| 3388 | 3534 |
| 3389 bool RequiresHoleCheck() const; | 3535 bool RequiresHoleCheck() const; |
| 3390 | 3536 |
| 3391 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement) | 3537 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement) |
| 3392 | 3538 |
| 3393 protected: | 3539 protected: |
| 3394 virtual bool DataEquals(HValue* other) { return true; } | 3540 virtual bool DataEquals(HValue* other) { return true; } |
| 3395 }; | 3541 }; |
| 3396 | 3542 |
| 3397 | 3543 |
| 3398 class HLoadKeyedSpecializedArrayElement: public HBinaryOperation { | 3544 class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> { |
| 3399 public: | 3545 public: |
| 3400 HLoadKeyedSpecializedArrayElement(HValue* external_elements, | 3546 HLoadKeyedSpecializedArrayElement(HValue* external_elements, |
| 3401 HValue* key, | 3547 HValue* key, |
| 3402 ExternalArrayType array_type) | 3548 JSObject::ElementsKind elements_kind) |
| 3403 : HBinaryOperation(external_elements, key), | 3549 : elements_kind_(elements_kind) { |
| 3404 array_type_(array_type) { | 3550 SetOperandAt(0, external_elements); |
| 3405 if (array_type == kExternalFloatArray || | 3551 SetOperandAt(1, key); |
| 3406 array_type == kExternalDoubleArray) { | 3552 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || |
| 3553 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { |
| 3407 set_representation(Representation::Double()); | 3554 set_representation(Representation::Double()); |
| 3408 } else { | 3555 } else { |
| 3409 set_representation(Representation::Integer32()); | 3556 set_representation(Representation::Integer32()); |
| 3410 } | 3557 } |
| 3411 SetFlag(kDependsOnSpecializedArrayElements); | 3558 SetFlag(kDependsOnSpecializedArrayElements); |
| 3412 // Native code could change the specialized array. | 3559 // Native code could change the specialized array. |
| 3413 SetFlag(kDependsOnCalls); | 3560 SetFlag(kDependsOnCalls); |
| 3414 SetFlag(kUseGVN); | 3561 SetFlag(kUseGVN); |
| 3415 } | 3562 } |
| 3416 | 3563 |
| 3417 virtual void PrintDataTo(StringStream* stream); | 3564 virtual void PrintDataTo(StringStream* stream); |
| 3418 | 3565 |
| 3419 virtual Representation RequiredInputRepresentation(int index) const { | 3566 virtual Representation RequiredInputRepresentation(int index) const { |
| 3420 // The key is supposed to be Integer32, but the base pointer | 3567 // The key is supposed to be Integer32, but the base pointer |
| 3421 // for the element load is a naked pointer. | 3568 // for the element load is a naked pointer. |
| 3422 return (index == 1) ? Representation::Integer32() | 3569 return index == 0 |
| 3423 : Representation::External(); | 3570 ? Representation::External() |
| 3571 : Representation::Integer32(); |
| 3424 } | 3572 } |
| 3425 | 3573 |
| 3426 HValue* external_pointer() { return OperandAt(0); } | 3574 HValue* external_pointer() { return OperandAt(0); } |
| 3427 HValue* key() { return OperandAt(1); } | 3575 HValue* key() { return OperandAt(1); } |
| 3428 ExternalArrayType array_type() const { return array_type_; } | 3576 JSObject::ElementsKind elements_kind() const { return elements_kind_; } |
| 3429 | 3577 |
| 3430 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement) | 3578 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement) |
| 3431 | 3579 |
| 3432 protected: | 3580 protected: |
| 3433 virtual bool DataEquals(HValue* other) { | 3581 virtual bool DataEquals(HValue* other) { |
| 3434 if (!other->IsLoadKeyedSpecializedArrayElement()) return false; | 3582 if (!other->IsLoadKeyedSpecializedArrayElement()) return false; |
| 3435 HLoadKeyedSpecializedArrayElement* cast_other = | 3583 HLoadKeyedSpecializedArrayElement* cast_other = |
| 3436 HLoadKeyedSpecializedArrayElement::cast(other); | 3584 HLoadKeyedSpecializedArrayElement::cast(other); |
| 3437 return array_type_ == cast_other->array_type(); | 3585 return elements_kind_ == cast_other->elements_kind(); |
| 3438 } | 3586 } |
| 3439 | 3587 |
| 3440 private: | 3588 private: |
| 3441 ExternalArrayType array_type_; | 3589 JSObject::ElementsKind elements_kind_; |
| 3442 }; | 3590 }; |
| 3443 | 3591 |
| 3444 | 3592 |
| 3445 class HLoadKeyedGeneric: public HTemplateInstruction<3> { | 3593 class HLoadKeyedGeneric: public HTemplateInstruction<3> { |
| 3446 public: | 3594 public: |
| 3447 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) { | 3595 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) { |
| 3448 set_representation(Representation::Tagged()); | 3596 set_representation(Representation::Tagged()); |
| 3449 SetOperandAt(0, obj); | 3597 SetOperandAt(0, obj); |
| 3450 SetOperandAt(1, key); | 3598 SetOperandAt(1, key); |
| 3451 SetOperandAt(2, context); | 3599 SetOperandAt(2, context); |
| 3452 SetAllSideEffects(); | 3600 SetAllSideEffects(); |
| 3453 } | 3601 } |
| 3454 | 3602 |
| 3455 HValue* object() { return OperandAt(0); } | 3603 HValue* object() { return OperandAt(0); } |
| 3456 HValue* key() { return OperandAt(1); } | 3604 HValue* key() { return OperandAt(1); } |
| 3457 HValue* context() { return OperandAt(2); } | 3605 HValue* context() { return OperandAt(2); } |
| 3458 | 3606 |
| 3459 virtual void PrintDataTo(StringStream* stream); | 3607 virtual void PrintDataTo(StringStream* stream); |
| 3460 | 3608 |
| 3461 virtual Representation RequiredInputRepresentation(int index) const { | 3609 virtual Representation RequiredInputRepresentation(int index) const { |
| 3462 return Representation::Tagged(); | 3610 return Representation::Tagged(); |
| 3463 } | 3611 } |
| 3464 | 3612 |
| 3465 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) | 3613 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) |
| 3466 }; | 3614 }; |
| 3467 | 3615 |
| 3468 | 3616 |
| 3469 class HStoreNamedField: public HBinaryOperation { | 3617 class HStoreNamedField: public HTemplateInstruction<2> { |
| 3470 public: | 3618 public: |
| 3471 HStoreNamedField(HValue* obj, | 3619 HStoreNamedField(HValue* obj, |
| 3472 Handle<String> name, | 3620 Handle<String> name, |
| 3473 HValue* val, | 3621 HValue* val, |
| 3474 bool in_object, | 3622 bool in_object, |
| 3475 int offset) | 3623 int offset) |
| 3476 : HBinaryOperation(obj, val), | 3624 : name_(name), |
| 3477 name_(name), | |
| 3478 is_in_object_(in_object), | 3625 is_in_object_(in_object), |
| 3479 offset_(offset) { | 3626 offset_(offset) { |
| 3627 SetOperandAt(0, obj); |
| 3628 SetOperandAt(1, val); |
| 3480 if (is_in_object_) { | 3629 if (is_in_object_) { |
| 3481 SetFlag(kChangesInobjectFields); | 3630 SetFlag(kChangesInobjectFields); |
| 3482 } else { | 3631 } else { |
| 3483 SetFlag(kChangesBackingStoreFields); | 3632 SetFlag(kChangesBackingStoreFields); |
| 3484 } | 3633 } |
| 3485 } | 3634 } |
| 3486 | 3635 |
| 3487 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) | 3636 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) |
| 3488 | 3637 |
| 3489 virtual Representation RequiredInputRepresentation(int index) const { | 3638 virtual Representation RequiredInputRepresentation(int index) const { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3551 public: | 3700 public: |
| 3552 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) { | 3701 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) { |
| 3553 SetOperandAt(0, obj); | 3702 SetOperandAt(0, obj); |
| 3554 SetOperandAt(1, key); | 3703 SetOperandAt(1, key); |
| 3555 SetOperandAt(2, val); | 3704 SetOperandAt(2, val); |
| 3556 SetFlag(kChangesArrayElements); | 3705 SetFlag(kChangesArrayElements); |
| 3557 } | 3706 } |
| 3558 | 3707 |
| 3559 virtual Representation RequiredInputRepresentation(int index) const { | 3708 virtual Representation RequiredInputRepresentation(int index) const { |
| 3560 // The key is supposed to be Integer32. | 3709 // The key is supposed to be Integer32. |
| 3561 return (index == 1) ? Representation::Integer32() | 3710 return index == 1 |
| 3711 ? Representation::Integer32() |
| 3562 : Representation::Tagged(); | 3712 : Representation::Tagged(); |
| 3563 } | 3713 } |
| 3564 | 3714 |
| 3565 HValue* object() { return OperandAt(0); } | 3715 HValue* object() { return OperandAt(0); } |
| 3566 HValue* key() { return OperandAt(1); } | 3716 HValue* key() { return OperandAt(1); } |
| 3567 HValue* value() { return OperandAt(2); } | 3717 HValue* value() { return OperandAt(2); } |
| 3568 | 3718 |
| 3569 bool NeedsWriteBarrier() { | 3719 bool NeedsWriteBarrier() { |
| 3570 return StoringValueNeedsWriteBarrier(value()); | 3720 return StoringValueNeedsWriteBarrier(value()); |
| 3571 } | 3721 } |
| 3572 | 3722 |
| 3573 virtual void PrintDataTo(StringStream* stream); | 3723 virtual void PrintDataTo(StringStream* stream); |
| 3574 | 3724 |
| 3575 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement) | 3725 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement) |
| 3576 }; | 3726 }; |
| 3577 | 3727 |
| 3578 | 3728 |
| 3579 class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> { | 3729 class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> { |
| 3580 public: | 3730 public: |
| 3581 HStoreKeyedSpecializedArrayElement(HValue* external_elements, | 3731 HStoreKeyedSpecializedArrayElement(HValue* external_elements, |
| 3582 HValue* key, | 3732 HValue* key, |
| 3583 HValue* val, | 3733 HValue* val, |
| 3584 ExternalArrayType array_type) | 3734 JSObject::ElementsKind elements_kind) |
| 3585 : array_type_(array_type) { | 3735 : elements_kind_(elements_kind) { |
| 3586 SetFlag(kChangesSpecializedArrayElements); | 3736 SetFlag(kChangesSpecializedArrayElements); |
| 3587 SetOperandAt(0, external_elements); | 3737 SetOperandAt(0, external_elements); |
| 3588 SetOperandAt(1, key); | 3738 SetOperandAt(1, key); |
| 3589 SetOperandAt(2, val); | 3739 SetOperandAt(2, val); |
| 3590 } | 3740 } |
| 3591 | 3741 |
| 3592 virtual void PrintDataTo(StringStream* stream); | 3742 virtual void PrintDataTo(StringStream* stream); |
| 3593 | 3743 |
| 3594 virtual Representation RequiredInputRepresentation(int index) const { | 3744 virtual Representation RequiredInputRepresentation(int index) const { |
| 3595 if (index == 0) { | 3745 if (index == 0) { |
| 3596 return Representation::External(); | 3746 return Representation::External(); |
| 3597 } else { | 3747 } else { |
| 3598 if (index == 2 && (array_type() == kExternalFloatArray || | 3748 bool float_or_double_elements = |
| 3599 array_type() == kExternalDoubleArray)) { | 3749 elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS || |
| 3750 elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS; |
| 3751 if (index == 2 && float_or_double_elements) { |
| 3600 return Representation::Double(); | 3752 return Representation::Double(); |
| 3601 } else { | 3753 } else { |
| 3602 return Representation::Integer32(); | 3754 return Representation::Integer32(); |
| 3603 } | 3755 } |
| 3604 } | 3756 } |
| 3605 } | 3757 } |
| 3606 | 3758 |
| 3607 HValue* external_pointer() { return OperandAt(0); } | 3759 HValue* external_pointer() { return OperandAt(0); } |
| 3608 HValue* key() { return OperandAt(1); } | 3760 HValue* key() { return OperandAt(1); } |
| 3609 HValue* value() { return OperandAt(2); } | 3761 HValue* value() { return OperandAt(2); } |
| 3610 ExternalArrayType array_type() const { return array_type_; } | 3762 JSObject::ElementsKind elements_kind() const { return elements_kind_; } |
| 3611 | 3763 |
| 3612 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement) | 3764 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement) |
| 3613 | 3765 |
| 3614 private: | 3766 private: |
| 3615 ExternalArrayType array_type_; | 3767 JSObject::ElementsKind elements_kind_; |
| 3616 }; | 3768 }; |
| 3617 | 3769 |
| 3618 | 3770 |
| 3619 class HStoreKeyedGeneric: public HTemplateInstruction<4> { | 3771 class HStoreKeyedGeneric: public HTemplateInstruction<4> { |
| 3620 public: | 3772 public: |
| 3621 HStoreKeyedGeneric(HValue* context, | 3773 HStoreKeyedGeneric(HValue* context, |
| 3622 HValue* object, | 3774 HValue* object, |
| 3623 HValue* key, | 3775 HValue* key, |
| 3624 HValue* value, | 3776 HValue* value, |
| 3625 bool strict_mode) | 3777 bool strict_mode) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3645 | 3797 |
| 3646 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) | 3798 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) |
| 3647 | 3799 |
| 3648 private: | 3800 private: |
| 3649 bool strict_mode_; | 3801 bool strict_mode_; |
| 3650 }; | 3802 }; |
| 3651 | 3803 |
| 3652 | 3804 |
| 3653 class HStringAdd: public HBinaryOperation { | 3805 class HStringAdd: public HBinaryOperation { |
| 3654 public: | 3806 public: |
| 3655 HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) { | 3807 HStringAdd(HValue* context, HValue* left, HValue* right) |
| 3808 : HBinaryOperation(context, left, right) { |
| 3656 set_representation(Representation::Tagged()); | 3809 set_representation(Representation::Tagged()); |
| 3657 SetFlag(kUseGVN); | 3810 SetFlag(kUseGVN); |
| 3658 SetFlag(kDependsOnMaps); | 3811 SetFlag(kDependsOnMaps); |
| 3659 } | 3812 } |
| 3660 | 3813 |
| 3661 virtual Representation RequiredInputRepresentation(int index) const { | 3814 virtual Representation RequiredInputRepresentation(int index) const { |
| 3662 return Representation::Tagged(); | 3815 return Representation::Tagged(); |
| 3663 } | 3816 } |
| 3664 | 3817 |
| 3665 virtual HType CalculateInferredType() { | 3818 virtual HType CalculateInferredType() { |
| 3666 return HType::String(); | 3819 return HType::String(); |
| 3667 } | 3820 } |
| 3668 | 3821 |
| 3669 DECLARE_CONCRETE_INSTRUCTION(StringAdd) | 3822 DECLARE_CONCRETE_INSTRUCTION(StringAdd) |
| 3670 | 3823 |
| 3671 protected: | 3824 protected: |
| 3672 virtual bool DataEquals(HValue* other) { return true; } | 3825 virtual bool DataEquals(HValue* other) { return true; } |
| 3673 }; | 3826 }; |
| 3674 | 3827 |
| 3675 | 3828 |
| 3676 class HStringCharCodeAt: public HBinaryOperation { | 3829 class HStringCharCodeAt: public HTemplateInstruction<3> { |
| 3677 public: | 3830 public: |
| 3678 HStringCharCodeAt(HValue* string, HValue* index) | 3831 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { |
| 3679 : HBinaryOperation(string, index) { | 3832 SetOperandAt(0, context); |
| 3833 SetOperandAt(1, string); |
| 3834 SetOperandAt(2, index); |
| 3680 set_representation(Representation::Integer32()); | 3835 set_representation(Representation::Integer32()); |
| 3681 SetFlag(kUseGVN); | 3836 SetFlag(kUseGVN); |
| 3682 SetFlag(kDependsOnMaps); | 3837 SetFlag(kDependsOnMaps); |
| 3683 } | 3838 } |
| 3684 | 3839 |
| 3685 virtual Representation RequiredInputRepresentation(int index) const { | 3840 virtual Representation RequiredInputRepresentation(int index) const { |
| 3686 // The index is supposed to be Integer32. | 3841 // The index is supposed to be Integer32. |
| 3687 return (index == 1) ? Representation::Integer32() | 3842 return index == 2 |
| 3843 ? Representation::Integer32() |
| 3688 : Representation::Tagged(); | 3844 : Representation::Tagged(); |
| 3689 } | 3845 } |
| 3690 | 3846 |
| 3691 HValue* string() { return OperandAt(0); } | 3847 HValue* context() { return OperandAt(0); } |
| 3692 HValue* index() { return OperandAt(1); } | 3848 HValue* string() { return OperandAt(1); } |
| 3849 HValue* index() { return OperandAt(2); } |
| 3693 | 3850 |
| 3694 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) | 3851 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) |
| 3695 | 3852 |
| 3696 protected: | 3853 protected: |
| 3697 virtual bool DataEquals(HValue* other) { return true; } | 3854 virtual bool DataEquals(HValue* other) { return true; } |
| 3698 | 3855 |
| 3699 virtual Range* InferRange() { | 3856 virtual Range* InferRange() { |
| 3700 return new Range(0, String::kMaxUC16CharCode); | 3857 return new Range(0, String::kMaxUC16CharCode); |
| 3701 } | 3858 } |
| 3702 }; | 3859 }; |
| 3703 | 3860 |
| 3704 | 3861 |
| 3705 class HStringCharFromCode: public HUnaryOperation { | 3862 class HStringCharFromCode: public HTemplateInstruction<2> { |
| 3706 public: | 3863 public: |
| 3707 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) { | 3864 HStringCharFromCode(HValue* context, HValue* char_code) { |
| 3708 set_representation(Representation::Tagged()); | 3865 SetOperandAt(0, context); |
| 3866 SetOperandAt(1, char_code); |
| 3867 set_representation(Representation::Tagged()); |
| 3709 SetFlag(kUseGVN); | 3868 SetFlag(kUseGVN); |
| 3710 } | 3869 } |
| 3711 | 3870 |
| 3712 virtual Representation RequiredInputRepresentation(int index) const { | 3871 virtual Representation RequiredInputRepresentation(int index) const { |
| 3713 return Representation::Integer32(); | 3872 return index == 0 |
| 3873 ? Representation::Tagged() |
| 3874 : Representation::Integer32(); |
| 3714 } | 3875 } |
| 3715 | 3876 |
| 3877 HValue* context() { return OperandAt(0); } |
| 3878 HValue* value() { return OperandAt(1); } |
| 3879 |
| 3716 virtual bool DataEquals(HValue* other) { return true; } | 3880 virtual bool DataEquals(HValue* other) { return true; } |
| 3717 | 3881 |
| 3718 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) | 3882 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) |
| 3719 }; | 3883 }; |
| 3720 | 3884 |
| 3721 | 3885 |
| 3722 class HStringLength: public HUnaryOperation { | 3886 class HStringLength: public HUnaryOperation { |
| 3723 public: | 3887 public: |
| 3724 explicit HStringLength(HValue* string) : HUnaryOperation(string) { | 3888 explicit HStringLength(HValue* string) : HUnaryOperation(string) { |
| 3725 set_representation(Representation::Tagged()); | 3889 set_representation(Representation::Tagged()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3757 | 3921 |
| 3758 int literal_index() const { return literal_index_; } | 3922 int literal_index() const { return literal_index_; } |
| 3759 int depth() const { return depth_; } | 3923 int depth() const { return depth_; } |
| 3760 | 3924 |
| 3761 private: | 3925 private: |
| 3762 int literal_index_; | 3926 int literal_index_; |
| 3763 int depth_; | 3927 int depth_; |
| 3764 }; | 3928 }; |
| 3765 | 3929 |
| 3766 | 3930 |
| 3767 class HArrayLiteral: public HMaterializedLiteral<0> { | 3931 class HArrayLiteral: public HMaterializedLiteral<1> { |
| 3768 public: | 3932 public: |
| 3769 HArrayLiteral(Handle<FixedArray> constant_elements, | 3933 HArrayLiteral(HValue* context, |
| 3934 Handle<FixedArray> constant_elements, |
| 3770 int length, | 3935 int length, |
| 3771 int literal_index, | 3936 int literal_index, |
| 3772 int depth) | 3937 int depth) |
| 3773 : HMaterializedLiteral<0>(literal_index, depth), | 3938 : HMaterializedLiteral<1>(literal_index, depth), |
| 3774 length_(length), | 3939 length_(length), |
| 3775 constant_elements_(constant_elements) {} | 3940 constant_elements_(constant_elements) { |
| 3941 SetOperandAt(0, context); |
| 3942 } |
| 3776 | 3943 |
| 3944 HValue* context() { return OperandAt(0); } |
| 3777 Handle<FixedArray> constant_elements() const { return constant_elements_; } | 3945 Handle<FixedArray> constant_elements() const { return constant_elements_; } |
| 3778 int length() const { return length_; } | 3946 int length() const { return length_; } |
| 3779 | 3947 |
| 3780 bool IsCopyOnWrite() const; | 3948 bool IsCopyOnWrite() const; |
| 3781 | 3949 |
| 3782 virtual Representation RequiredInputRepresentation(int index) const { | 3950 virtual Representation RequiredInputRepresentation(int index) const { |
| 3783 return Representation::None(); | 3951 return Representation::Tagged(); |
| 3784 } | 3952 } |
| 3785 | 3953 |
| 3786 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral) | 3954 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral) |
| 3787 | 3955 |
| 3788 private: | 3956 private: |
| 3789 int length_; | 3957 int length_; |
| 3790 Handle<FixedArray> constant_elements_; | 3958 Handle<FixedArray> constant_elements_; |
| 3791 }; | 3959 }; |
| 3792 | 3960 |
| 3793 | 3961 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3819 | 3987 |
| 3820 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral) | 3988 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral) |
| 3821 | 3989 |
| 3822 private: | 3990 private: |
| 3823 Handle<FixedArray> constant_properties_; | 3991 Handle<FixedArray> constant_properties_; |
| 3824 bool fast_elements_; | 3992 bool fast_elements_; |
| 3825 bool has_function_; | 3993 bool has_function_; |
| 3826 }; | 3994 }; |
| 3827 | 3995 |
| 3828 | 3996 |
| 3829 class HRegExpLiteral: public HMaterializedLiteral<0> { | 3997 class HRegExpLiteral: public HMaterializedLiteral<1> { |
| 3830 public: | 3998 public: |
| 3831 HRegExpLiteral(Handle<String> pattern, | 3999 HRegExpLiteral(HValue* context, |
| 4000 Handle<String> pattern, |
| 3832 Handle<String> flags, | 4001 Handle<String> flags, |
| 3833 int literal_index) | 4002 int literal_index) |
| 3834 : HMaterializedLiteral<0>(literal_index, 0), | 4003 : HMaterializedLiteral<1>(literal_index, 0), |
| 3835 pattern_(pattern), | 4004 pattern_(pattern), |
| 3836 flags_(flags) { } | 4005 flags_(flags) { |
| 4006 SetOperandAt(0, context); |
| 4007 } |
| 3837 | 4008 |
| 4009 HValue* context() { return OperandAt(0); } |
| 3838 Handle<String> pattern() { return pattern_; } | 4010 Handle<String> pattern() { return pattern_; } |
| 3839 Handle<String> flags() { return flags_; } | 4011 Handle<String> flags() { return flags_; } |
| 3840 | 4012 |
| 3841 virtual Representation RequiredInputRepresentation(int index) const { | 4013 virtual Representation RequiredInputRepresentation(int index) const { |
| 3842 return Representation::None(); | 4014 return Representation::Tagged(); |
| 3843 } | 4015 } |
| 3844 | 4016 |
| 3845 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral) | 4017 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral) |
| 3846 | 4018 |
| 3847 private: | 4019 private: |
| 3848 Handle<String> pattern_; | 4020 Handle<String> pattern_; |
| 3849 Handle<String> flags_; | 4021 Handle<String> flags_; |
| 3850 }; | 4022 }; |
| 3851 | 4023 |
| 3852 | 4024 |
| 3853 class HFunctionLiteral: public HTemplateInstruction<0> { | 4025 class HFunctionLiteral: public HTemplateInstruction<1> { |
| 3854 public: | 4026 public: |
| 3855 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure) | 4027 HFunctionLiteral(HValue* context, |
| 4028 Handle<SharedFunctionInfo> shared, |
| 4029 bool pretenure) |
| 3856 : shared_info_(shared), pretenure_(pretenure) { | 4030 : shared_info_(shared), pretenure_(pretenure) { |
| 4031 SetOperandAt(0, context); |
| 3857 set_representation(Representation::Tagged()); | 4032 set_representation(Representation::Tagged()); |
| 3858 } | 4033 } |
| 3859 | 4034 |
| 4035 HValue* context() { return OperandAt(0); } |
| 4036 |
| 3860 virtual Representation RequiredInputRepresentation(int index) const { | 4037 virtual Representation RequiredInputRepresentation(int index) const { |
| 3861 return Representation::None(); | 4038 return Representation::Tagged(); |
| 3862 } | 4039 } |
| 3863 | 4040 |
| 3864 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral) | 4041 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral) |
| 3865 | 4042 |
| 3866 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } | 4043 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } |
| 3867 bool pretenure() const { return pretenure_; } | 4044 bool pretenure() const { return pretenure_; } |
| 3868 | 4045 |
| 3869 private: | 4046 private: |
| 3870 Handle<SharedFunctionInfo> shared_info_; | 4047 Handle<SharedFunctionInfo> shared_info_; |
| 3871 bool pretenure_; | 4048 bool pretenure_; |
| 3872 }; | 4049 }; |
| 3873 | 4050 |
| 3874 | 4051 |
| 3875 class HTypeof: public HUnaryOperation { | 4052 class HTypeof: public HTemplateInstruction<2> { |
| 3876 public: | 4053 public: |
| 3877 explicit HTypeof(HValue* value) : HUnaryOperation(value) { | 4054 explicit HTypeof(HValue* context, HValue* value) { |
| 4055 SetOperandAt(0, context); |
| 4056 SetOperandAt(1, value); |
| 3878 set_representation(Representation::Tagged()); | 4057 set_representation(Representation::Tagged()); |
| 3879 } | 4058 } |
| 3880 | 4059 |
| 4060 HValue* context() { return OperandAt(0); } |
| 4061 HValue* value() { return OperandAt(1); } |
| 4062 |
| 3881 virtual Representation RequiredInputRepresentation(int index) const { | 4063 virtual Representation RequiredInputRepresentation(int index) const { |
| 3882 return Representation::Tagged(); | 4064 return Representation::Tagged(); |
| 3883 } | 4065 } |
| 3884 | 4066 |
| 3885 DECLARE_CONCRETE_INSTRUCTION(Typeof) | 4067 DECLARE_CONCRETE_INSTRUCTION(Typeof) |
| 3886 }; | 4068 }; |
| 3887 | 4069 |
| 3888 | 4070 |
| 3889 class HToFastProperties: public HUnaryOperation { | 4071 class HToFastProperties: public HUnaryOperation { |
| 3890 public: | 4072 public: |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3913 virtual Representation RequiredInputRepresentation(int index) const { | 4095 virtual Representation RequiredInputRepresentation(int index) const { |
| 3914 return Representation::Tagged(); | 4096 return Representation::Tagged(); |
| 3915 } | 4097 } |
| 3916 | 4098 |
| 3917 DECLARE_CONCRETE_INSTRUCTION(ValueOf) | 4099 DECLARE_CONCRETE_INSTRUCTION(ValueOf) |
| 3918 }; | 4100 }; |
| 3919 | 4101 |
| 3920 | 4102 |
| 3921 class HDeleteProperty: public HBinaryOperation { | 4103 class HDeleteProperty: public HBinaryOperation { |
| 3922 public: | 4104 public: |
| 3923 HDeleteProperty(HValue* obj, HValue* key) | 4105 HDeleteProperty(HValue* context, HValue* obj, HValue* key) |
| 3924 : HBinaryOperation(obj, key) { | 4106 : HBinaryOperation(context, obj, key) { |
| 3925 set_representation(Representation::Tagged()); | 4107 set_representation(Representation::Tagged()); |
| 3926 SetAllSideEffects(); | 4108 SetAllSideEffects(); |
| 3927 } | 4109 } |
| 3928 | 4110 |
| 3929 virtual Representation RequiredInputRepresentation(int index) const { | 4111 virtual Representation RequiredInputRepresentation(int index) const { |
| 3930 return Representation::Tagged(); | 4112 return Representation::Tagged(); |
| 3931 } | 4113 } |
| 3932 | 4114 |
| 4115 virtual HType CalculateInferredType(); |
| 4116 |
| 3933 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty) | 4117 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty) |
| 3934 | 4118 |
| 3935 HValue* object() { return left(); } | 4119 HValue* object() { return left(); } |
| 3936 HValue* key() { return right(); } | 4120 HValue* key() { return right(); } |
| 3937 }; | 4121 }; |
| 3938 | 4122 |
| 3939 | 4123 |
| 3940 class HIn: public HTemplateInstruction<2> { | 4124 class HIn: public HTemplateInstruction<3> { |
| 3941 public: | 4125 public: |
| 3942 HIn(HValue* key, HValue* object) { | 4126 HIn(HValue* context, HValue* key, HValue* object) { |
| 3943 SetOperandAt(0, key); | 4127 SetOperandAt(0, context); |
| 3944 SetOperandAt(1, object); | 4128 SetOperandAt(1, key); |
| 4129 SetOperandAt(2, object); |
| 3945 set_representation(Representation::Tagged()); | 4130 set_representation(Representation::Tagged()); |
| 3946 SetAllSideEffects(); | 4131 SetAllSideEffects(); |
| 3947 } | 4132 } |
| 3948 | 4133 |
| 3949 HValue* key() { return OperandAt(0); } | 4134 HValue* context() { return OperandAt(0); } |
| 3950 HValue* object() { return OperandAt(1); } | 4135 HValue* key() { return OperandAt(1); } |
| 4136 HValue* object() { return OperandAt(2); } |
| 3951 | 4137 |
| 3952 virtual Representation RequiredInputRepresentation(int index) const { | 4138 virtual Representation RequiredInputRepresentation(int index) const { |
| 3953 return Representation::Tagged(); | 4139 return Representation::Tagged(); |
| 3954 } | 4140 } |
| 3955 | 4141 |
| 3956 virtual HType CalculateInferredType() { | 4142 virtual HType CalculateInferredType() { |
| 3957 return HType::Boolean(); | 4143 return HType::Boolean(); |
| 3958 } | 4144 } |
| 3959 | 4145 |
| 3960 virtual void PrintDataTo(StringStream* stream); | 4146 virtual void PrintDataTo(StringStream* stream); |
| 3961 | 4147 |
| 3962 DECLARE_CONCRETE_INSTRUCTION(In) | 4148 DECLARE_CONCRETE_INSTRUCTION(In) |
| 3963 }; | 4149 }; |
| 3964 | 4150 |
| 3965 #undef DECLARE_INSTRUCTION | 4151 #undef DECLARE_INSTRUCTION |
| 3966 #undef DECLARE_CONCRETE_INSTRUCTION | 4152 #undef DECLARE_CONCRETE_INSTRUCTION |
| 3967 | 4153 |
| 3968 } } // namespace v8::internal | 4154 } } // namespace v8::internal |
| 3969 | 4155 |
| 3970 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 4156 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |