| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ | 5 #ifndef V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ |
| 6 #define V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ | 6 #define V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ |
| 7 | 7 |
| 8 #include <cstring> | 8 #include <cstring> |
| 9 #include <iosfwd> | 9 #include <iosfwd> |
| 10 | 10 |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 type_(type), | 479 type_(type), |
| 480 use_list_(NULL), | 480 use_list_(NULL), |
| 481 range_(NULL), | 481 range_(NULL), |
| 482 #ifdef DEBUG | 482 #ifdef DEBUG |
| 483 range_poisoned_(false), | 483 range_poisoned_(false), |
| 484 #endif | 484 #endif |
| 485 flags_(0) {} | 485 flags_(0) {} |
| 486 virtual ~HValue() {} | 486 virtual ~HValue() {} |
| 487 | 487 |
| 488 virtual SourcePosition position() const { return SourcePosition::Unknown(); } | 488 virtual SourcePosition position() const { return SourcePosition::Unknown(); } |
| 489 virtual SourcePosition operand_position(int index) const { | |
| 490 return position(); | |
| 491 } | |
| 492 | 489 |
| 493 HBasicBlock* block() const { return block_; } | 490 HBasicBlock* block() const { return block_; } |
| 494 void SetBlock(HBasicBlock* block); | 491 void SetBlock(HBasicBlock* block); |
| 495 | 492 |
| 496 // Note: Never call this method for an unlinked value. | 493 // Note: Never call this method for an unlinked value. |
| 497 Isolate* isolate() const; | 494 Isolate* isolate() const; |
| 498 | 495 |
| 499 int id() const { return id_; } | 496 int id() const { return id_; } |
| 500 void set_id(int id) { id_ = id; } | 497 void set_id(int id) { id_ = id; } |
| 501 | 498 |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 941 P3 p3, P4 p4, P5 p5) { \ | 938 P3 p3, P4 p4, P5 p5) { \ |
| 942 return new (zone) I(context, p1, p2, p3, p4, p5); \ | 939 return new (zone) I(context, p1, p2, p3, p4, p5); \ |
| 943 } | 940 } |
| 944 | 941 |
| 945 #define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P6(I, P1, P2, P3, P4, P5, P6) \ | 942 #define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P6(I, P1, P2, P3, P4, P5, P6) \ |
| 946 static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \ | 943 static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \ |
| 947 P3 p3, P4 p4, P5 p5, P6 p6) { \ | 944 P3 p3, P4 p4, P5 p5, P6 p6) { \ |
| 948 return new (zone) I(context, p1, p2, p3, p4, p5, p6); \ | 945 return new (zone) I(context, p1, p2, p3, p4, p5, p6); \ |
| 949 } | 946 } |
| 950 | 947 |
| 951 | |
| 952 // A helper class to represent per-operand position information attached to | |
| 953 // the HInstruction in the compact form. Uses tagging to distinguish between | |
| 954 // case when only instruction's position is available and case when operands' | |
| 955 // positions are also available. | |
| 956 // In the first case it contains intruction's position as a tagged value. | |
| 957 // In the second case it points to an array which contains instruction's | |
| 958 // position and operands' positions. | |
| 959 class HPositionInfo { | |
| 960 public: | |
| 961 explicit HPositionInfo(int pos) : data_(TagPosition(pos)) { } | |
| 962 | |
| 963 SourcePosition position() const { | |
| 964 if (has_operand_positions()) { | |
| 965 return operand_positions()[kInstructionPosIndex]; | |
| 966 } | |
| 967 return SourcePosition::FromRaw(static_cast<int>(UntagPosition(data_))); | |
| 968 } | |
| 969 | |
| 970 void set_position(SourcePosition pos) { | |
| 971 if (has_operand_positions()) { | |
| 972 operand_positions()[kInstructionPosIndex] = pos; | |
| 973 } else { | |
| 974 data_ = TagPosition(pos.raw()); | |
| 975 } | |
| 976 } | |
| 977 | |
| 978 void ensure_storage_for_operand_positions(Zone* zone, int operand_count) { | |
| 979 if (has_operand_positions()) { | |
| 980 return; | |
| 981 } | |
| 982 | |
| 983 const int length = kFirstOperandPosIndex + operand_count; | |
| 984 SourcePosition* positions = zone->NewArray<SourcePosition>(length); | |
| 985 for (int i = 0; i < length; i++) { | |
| 986 positions[i] = SourcePosition::Unknown(); | |
| 987 } | |
| 988 | |
| 989 const SourcePosition pos = position(); | |
| 990 data_ = reinterpret_cast<intptr_t>(positions); | |
| 991 set_position(pos); | |
| 992 | |
| 993 DCHECK(has_operand_positions()); | |
| 994 } | |
| 995 | |
| 996 SourcePosition operand_position(int idx) const { | |
| 997 if (!has_operand_positions()) { | |
| 998 return position(); | |
| 999 } | |
| 1000 return *operand_position_slot(idx); | |
| 1001 } | |
| 1002 | |
| 1003 void set_operand_position(int idx, SourcePosition pos) { | |
| 1004 *operand_position_slot(idx) = pos; | |
| 1005 } | |
| 1006 | |
| 1007 private: | |
| 1008 static const intptr_t kInstructionPosIndex = 0; | |
| 1009 static const intptr_t kFirstOperandPosIndex = 1; | |
| 1010 | |
| 1011 SourcePosition* operand_position_slot(int idx) const { | |
| 1012 DCHECK(has_operand_positions()); | |
| 1013 return &(operand_positions()[kFirstOperandPosIndex + idx]); | |
| 1014 } | |
| 1015 | |
| 1016 bool has_operand_positions() const { | |
| 1017 return !IsTaggedPosition(data_); | |
| 1018 } | |
| 1019 | |
| 1020 SourcePosition* operand_positions() const { | |
| 1021 DCHECK(has_operand_positions()); | |
| 1022 return reinterpret_cast<SourcePosition*>(data_); | |
| 1023 } | |
| 1024 | |
| 1025 static const intptr_t kPositionTag = 1; | |
| 1026 static const intptr_t kPositionShift = 1; | |
| 1027 static bool IsTaggedPosition(intptr_t val) { | |
| 1028 return (val & kPositionTag) != 0; | |
| 1029 } | |
| 1030 static intptr_t UntagPosition(intptr_t val) { | |
| 1031 DCHECK(IsTaggedPosition(val)); | |
| 1032 return val >> kPositionShift; | |
| 1033 } | |
| 1034 static intptr_t TagPosition(intptr_t val) { | |
| 1035 const intptr_t result = (val << kPositionShift) | kPositionTag; | |
| 1036 DCHECK(UntagPosition(result) == val); | |
| 1037 return result; | |
| 1038 } | |
| 1039 | |
| 1040 intptr_t data_; | |
| 1041 }; | |
| 1042 | |
| 1043 | |
| 1044 class HInstruction : public HValue { | 948 class HInstruction : public HValue { |
| 1045 public: | 949 public: |
| 1046 HInstruction* next() const { return next_; } | 950 HInstruction* next() const { return next_; } |
| 1047 HInstruction* previous() const { return previous_; } | 951 HInstruction* previous() const { return previous_; } |
| 1048 | 952 |
| 1049 std::ostream& PrintTo(std::ostream& os) const override; // NOLINT | 953 std::ostream& PrintTo(std::ostream& os) const override; // NOLINT |
| 1050 virtual std::ostream& PrintDataTo(std::ostream& os) const; // NOLINT | 954 virtual std::ostream& PrintDataTo(std::ostream& os) const; // NOLINT |
| 1051 | 955 |
| 1052 bool IsLinked() const { return block() != NULL; } | 956 bool IsLinked() const { return block() != NULL; } |
| 1053 void Unlink(); | 957 void Unlink(); |
| 1054 | 958 |
| 1055 void InsertBefore(HInstruction* next); | 959 void InsertBefore(HInstruction* next); |
| 1056 | 960 |
| 1057 template<class T> T* Prepend(T* instr) { | 961 template<class T> T* Prepend(T* instr) { |
| 1058 instr->InsertBefore(this); | 962 instr->InsertBefore(this); |
| 1059 return instr; | 963 return instr; |
| 1060 } | 964 } |
| 1061 | 965 |
| 1062 void InsertAfter(HInstruction* previous); | 966 void InsertAfter(HInstruction* previous); |
| 1063 | 967 |
| 1064 template<class T> T* Append(T* instr) { | 968 template<class T> T* Append(T* instr) { |
| 1065 instr->InsertAfter(this); | 969 instr->InsertAfter(this); |
| 1066 return instr; | 970 return instr; |
| 1067 } | 971 } |
| 1068 | 972 |
| 1069 // The position is a write-once variable. | 973 // The position is a write-once variable. |
| 1070 SourcePosition position() const override { | 974 SourcePosition position() const override { return position_; } |
| 1071 return SourcePosition(position_.position()); | 975 bool has_position() const { return position_.IsKnown(); } |
| 1072 } | |
| 1073 bool has_position() const { | |
| 1074 return !position().IsUnknown(); | |
| 1075 } | |
| 1076 void set_position(SourcePosition position) { | 976 void set_position(SourcePosition position) { |
| 1077 DCHECK(!has_position()); | 977 DCHECK(position.IsKnown()); |
| 1078 DCHECK(!position.IsUnknown()); | 978 position_ = position; |
| 1079 position_.set_position(position); | |
| 1080 } | |
| 1081 | |
| 1082 SourcePosition operand_position(int index) const override { | |
| 1083 const SourcePosition pos = position_.operand_position(index); | |
| 1084 return pos.IsUnknown() ? position() : pos; | |
| 1085 } | |
| 1086 void set_operand_position(Zone* zone, int index, SourcePosition pos) { | |
| 1087 DCHECK(0 <= index && index < OperandCount()); | |
| 1088 position_.ensure_storage_for_operand_positions(zone, OperandCount()); | |
| 1089 position_.set_operand_position(index, pos); | |
| 1090 } | 979 } |
| 1091 | 980 |
| 1092 bool Dominates(HInstruction* other); | 981 bool Dominates(HInstruction* other); |
| 1093 bool CanTruncateToSmi() const { return CheckFlag(kTruncatingToSmi); } | 982 bool CanTruncateToSmi() const { return CheckFlag(kTruncatingToSmi); } |
| 1094 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); } | 983 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); } |
| 1095 bool CanTruncateToNumber() const { return CheckFlag(kTruncatingToNumber); } | 984 bool CanTruncateToNumber() const { return CheckFlag(kTruncatingToNumber); } |
| 1096 | 985 |
| 1097 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0; | 986 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0; |
| 1098 | 987 |
| 1099 #ifdef DEBUG | 988 #ifdef DEBUG |
| 1100 void Verify() override; | 989 void Verify() override; |
| 1101 #endif | 990 #endif |
| 1102 | 991 |
| 1103 bool CanDeoptimize(); | 992 bool CanDeoptimize(); |
| 1104 | 993 |
| 1105 virtual bool HasStackCheck() { return false; } | 994 virtual bool HasStackCheck() { return false; } |
| 1106 | 995 |
| 1107 DECLARE_ABSTRACT_INSTRUCTION(Instruction) | 996 DECLARE_ABSTRACT_INSTRUCTION(Instruction) |
| 1108 | 997 |
| 1109 protected: | 998 protected: |
| 1110 explicit HInstruction(HType type = HType::Tagged()) | 999 explicit HInstruction(HType type = HType::Tagged()) |
| 1111 : HValue(type), | 1000 : HValue(type), |
| 1112 next_(NULL), | 1001 next_(NULL), |
| 1113 previous_(NULL), | 1002 previous_(NULL), |
| 1114 position_(kNoSourcePosition) { | 1003 position_(SourcePosition::Unknown()) { |
| 1115 SetDependsOnFlag(kOsrEntries); | 1004 SetDependsOnFlag(kOsrEntries); |
| 1116 } | 1005 } |
| 1117 | 1006 |
| 1118 void DeleteFromGraph() override { Unlink(); } | 1007 void DeleteFromGraph() override { Unlink(); } |
| 1119 | 1008 |
| 1120 private: | 1009 private: |
| 1121 void InitializeAsFirst(HBasicBlock* block) { | 1010 void InitializeAsFirst(HBasicBlock* block) { |
| 1122 DCHECK(!IsLinked()); | 1011 DCHECK(!IsLinked()); |
| 1123 SetBlock(block); | 1012 SetBlock(block); |
| 1124 } | 1013 } |
| 1125 | 1014 |
| 1126 HInstruction* next_; | 1015 HInstruction* next_; |
| 1127 HInstruction* previous_; | 1016 HInstruction* previous_; |
| 1128 HPositionInfo position_; | 1017 SourcePosition position_; |
| 1129 | 1018 |
| 1130 friend class HBasicBlock; | 1019 friend class HBasicBlock; |
| 1131 }; | 1020 }; |
| 1132 | 1021 |
| 1133 | 1022 |
| 1134 template<int V> | 1023 template<int V> |
| 1135 class HTemplateInstruction : public HInstruction { | 1024 class HTemplateInstruction : public HInstruction { |
| 1136 public: | 1025 public: |
| 1137 int OperandCount() const final { return V; } | 1026 int OperandCount() const final { return V; } |
| 1138 HValue* OperandAt(int i) const final { return inputs_[i]; } | 1027 HValue* OperandAt(int i) const final { return inputs_[i]; } |
| (...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1913 TailCallMode syntactic_tail_call_mode, Zone* zone) | 1802 TailCallMode syntactic_tail_call_mode, Zone* zone) |
| 1914 : return_id_(return_id), | 1803 : return_id_(return_id), |
| 1915 shared_(handle(closure->shared())), | 1804 shared_(handle(closure->shared())), |
| 1916 closure_(closure), | 1805 closure_(closure), |
| 1917 closure_context_(closure_context), | 1806 closure_context_(closure_context), |
| 1918 arguments_count_(arguments_count), | 1807 arguments_count_(arguments_count), |
| 1919 arguments_pushed_(false), | 1808 arguments_pushed_(false), |
| 1920 function_(function), | 1809 function_(function), |
| 1921 inlining_kind_(inlining_kind), | 1810 inlining_kind_(inlining_kind), |
| 1922 syntactic_tail_call_mode_(syntactic_tail_call_mode), | 1811 syntactic_tail_call_mode_(syntactic_tail_call_mode), |
| 1923 inlining_id_(0), | 1812 inlining_id_(-1), |
| 1924 arguments_var_(arguments_var), | 1813 arguments_var_(arguments_var), |
| 1925 arguments_object_(arguments_object), | 1814 arguments_object_(arguments_object), |
| 1926 return_targets_(2, zone) {} | 1815 return_targets_(2, zone) {} |
| 1927 | 1816 |
| 1928 BailoutId return_id_; | 1817 BailoutId return_id_; |
| 1929 Handle<SharedFunctionInfo> shared_; | 1818 Handle<SharedFunctionInfo> shared_; |
| 1930 Handle<JSFunction> closure_; | 1819 Handle<JSFunction> closure_; |
| 1931 HConstant* closure_context_; | 1820 HConstant* closure_context_; |
| 1932 int arguments_count_; | 1821 int arguments_count_; |
| 1933 bool arguments_pushed_; | 1822 bool arguments_pushed_; |
| (...skipping 1533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3467 | 3356 |
| 3468 virtual bool IsCommutative() const { return false; } | 3357 virtual bool IsCommutative() const { return false; } |
| 3469 | 3358 |
| 3470 std::ostream& PrintDataTo(std::ostream& os) const override; // NOLINT | 3359 std::ostream& PrintDataTo(std::ostream& os) const override; // NOLINT |
| 3471 | 3360 |
| 3472 Representation RequiredInputRepresentation(int index) override { | 3361 Representation RequiredInputRepresentation(int index) override { |
| 3473 if (index == 0) return Representation::Tagged(); | 3362 if (index == 0) return Representation::Tagged(); |
| 3474 return representation(); | 3363 return representation(); |
| 3475 } | 3364 } |
| 3476 | 3365 |
| 3477 void SetOperandPositions(Zone* zone, SourcePosition left_pos, | |
| 3478 SourcePosition right_pos) { | |
| 3479 set_operand_position(zone, 1, left_pos); | |
| 3480 set_operand_position(zone, 2, right_pos); | |
| 3481 } | |
| 3482 | |
| 3483 bool RightIsPowerOf2() { | 3366 bool RightIsPowerOf2() { |
| 3484 if (!right()->IsInteger32Constant()) return false; | 3367 if (!right()->IsInteger32Constant()) return false; |
| 3485 int32_t value = right()->GetInteger32Constant(); | 3368 int32_t value = right()->GetInteger32Constant(); |
| 3486 if (value < 0) { | 3369 if (value < 0) { |
| 3487 return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(-value)); | 3370 return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(-value)); |
| 3488 } | 3371 } |
| 3489 return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(value)); | 3372 return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(value)); |
| 3490 } | 3373 } |
| 3491 | 3374 |
| 3492 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) | 3375 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3885 return representation(); | 3768 return representation(); |
| 3886 } | 3769 } |
| 3887 Representation observed_input_representation(int index) override { | 3770 Representation observed_input_representation(int index) override { |
| 3888 return observed_input_representation_[index]; | 3771 return observed_input_representation_[index]; |
| 3889 } | 3772 } |
| 3890 | 3773 |
| 3891 bool KnownSuccessorBlock(HBasicBlock** block) override; | 3774 bool KnownSuccessorBlock(HBasicBlock** block) override; |
| 3892 | 3775 |
| 3893 std::ostream& PrintDataTo(std::ostream& os) const override; // NOLINT | 3776 std::ostream& PrintDataTo(std::ostream& os) const override; // NOLINT |
| 3894 | 3777 |
| 3895 void SetOperandPositions(Zone* zone, SourcePosition left_pos, | |
| 3896 SourcePosition right_pos) { | |
| 3897 set_operand_position(zone, 0, left_pos); | |
| 3898 set_operand_position(zone, 1, right_pos); | |
| 3899 } | |
| 3900 | |
| 3901 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) | 3778 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) |
| 3902 | 3779 |
| 3903 private: | 3780 private: |
| 3904 HCompareNumericAndBranch(HValue* left, HValue* right, Token::Value token, | 3781 HCompareNumericAndBranch(HValue* left, HValue* right, Token::Value token, |
| 3905 HBasicBlock* true_target, HBasicBlock* false_target) | 3782 HBasicBlock* true_target, HBasicBlock* false_target) |
| 3906 : token_(token) { | 3783 : token_(token) { |
| 3907 SetFlag(kFlexibleRepresentation); | 3784 SetFlag(kFlexibleRepresentation); |
| 3908 DCHECK(Token::IsCompareOp(token)); | 3785 DCHECK(Token::IsCompareOp(token)); |
| 3909 SetOperandAt(0, left); | 3786 SetOperandAt(0, left); |
| 3910 SetOperandAt(1, right); | 3787 SetOperandAt(1, right); |
| (...skipping 2971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6882 bool IsDeletable() const override { return true; } | 6759 bool IsDeletable() const override { return true; } |
| 6883 }; | 6760 }; |
| 6884 | 6761 |
| 6885 #undef DECLARE_INSTRUCTION | 6762 #undef DECLARE_INSTRUCTION |
| 6886 #undef DECLARE_CONCRETE_INSTRUCTION | 6763 #undef DECLARE_CONCRETE_INSTRUCTION |
| 6887 | 6764 |
| 6888 } // namespace internal | 6765 } // namespace internal |
| 6889 } // namespace v8 | 6766 } // namespace v8 |
| 6890 | 6767 |
| 6891 #endif // V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ | 6768 #endif // V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |