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_HYDROGEN_INSTRUCTIONS_H_ | 5 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_ |
6 #define V8_HYDROGEN_INSTRUCTIONS_H_ | 6 #define V8_HYDROGEN_INSTRUCTIONS_H_ |
7 | 7 |
8 #include <cstring> | 8 #include <cstring> |
9 #include <iosfwd> | 9 #include <iosfwd> |
10 | 10 |
(...skipping 6230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6241 static HObjectAccess ForJSArrayBufferBitField() { | 6241 static HObjectAccess ForJSArrayBufferBitField() { |
6242 return HObjectAccess::ForObservableJSObjectOffset( | 6242 return HObjectAccess::ForObservableJSObjectOffset( |
6243 JSArrayBuffer::kBitFieldOffset, Representation::Integer32()); | 6243 JSArrayBuffer::kBitFieldOffset, Representation::Integer32()); |
6244 } | 6244 } |
6245 | 6245 |
6246 static HObjectAccess ForJSArrayBufferBitFieldSlot() { | 6246 static HObjectAccess ForJSArrayBufferBitFieldSlot() { |
6247 return HObjectAccess::ForObservableJSObjectOffset( | 6247 return HObjectAccess::ForObservableJSObjectOffset( |
6248 JSArrayBuffer::kBitFieldSlot, Representation::Smi()); | 6248 JSArrayBuffer::kBitFieldSlot, Representation::Smi()); |
6249 } | 6249 } |
6250 | 6250 |
| 6251 static HObjectAccess ForExternalArrayExternalPointer() { |
| 6252 return HObjectAccess::ForObservableJSObjectOffset( |
| 6253 ExternalArray::kExternalPointerOffset, Representation::External()); |
| 6254 } |
| 6255 |
6251 static HObjectAccess ForJSArrayBufferViewBuffer() { | 6256 static HObjectAccess ForJSArrayBufferViewBuffer() { |
6252 return HObjectAccess::ForObservableJSObjectOffset( | 6257 return HObjectAccess::ForObservableJSObjectOffset( |
6253 JSArrayBufferView::kBufferOffset); | 6258 JSArrayBufferView::kBufferOffset); |
6254 } | 6259 } |
6255 | 6260 |
6256 static HObjectAccess ForJSArrayBufferViewByteOffset() { | 6261 static HObjectAccess ForJSArrayBufferViewByteOffset() { |
6257 return HObjectAccess::ForObservableJSObjectOffset( | 6262 return HObjectAccess::ForObservableJSObjectOffset( |
6258 JSArrayBufferView::kByteOffsetOffset); | 6263 JSArrayBufferView::kByteOffsetOffset); |
6259 } | 6264 } |
6260 | 6265 |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6610 class HLoadKeyed final : public HTemplateInstruction<3>, | 6615 class HLoadKeyed final : public HTemplateInstruction<3>, |
6611 public ArrayInstructionInterface { | 6616 public ArrayInstructionInterface { |
6612 public: | 6617 public: |
6613 DECLARE_INSTRUCTION_FACTORY_P4(HLoadKeyed, HValue*, HValue*, HValue*, | 6618 DECLARE_INSTRUCTION_FACTORY_P4(HLoadKeyed, HValue*, HValue*, HValue*, |
6614 ElementsKind); | 6619 ElementsKind); |
6615 DECLARE_INSTRUCTION_FACTORY_P5(HLoadKeyed, HValue*, HValue*, HValue*, | 6620 DECLARE_INSTRUCTION_FACTORY_P5(HLoadKeyed, HValue*, HValue*, HValue*, |
6616 ElementsKind, LoadKeyedHoleMode); | 6621 ElementsKind, LoadKeyedHoleMode); |
6617 DECLARE_INSTRUCTION_FACTORY_P6(HLoadKeyed, HValue*, HValue*, HValue*, | 6622 DECLARE_INSTRUCTION_FACTORY_P6(HLoadKeyed, HValue*, HValue*, HValue*, |
6618 ElementsKind, LoadKeyedHoleMode, int); | 6623 ElementsKind, LoadKeyedHoleMode, int); |
6619 | 6624 |
| 6625 bool is_external() const { |
| 6626 return IsExternalArrayElementsKind(elements_kind()); |
| 6627 } |
6620 bool is_fixed_typed_array() const { | 6628 bool is_fixed_typed_array() const { |
6621 return IsFixedTypedArrayElementsKind(elements_kind()); | 6629 return IsFixedTypedArrayElementsKind(elements_kind()); |
6622 } | 6630 } |
| 6631 bool is_typed_elements() const { |
| 6632 return is_external() || is_fixed_typed_array(); |
| 6633 } |
6623 HValue* elements() const { return OperandAt(0); } | 6634 HValue* elements() const { return OperandAt(0); } |
6624 HValue* key() const { return OperandAt(1); } | 6635 HValue* key() const { return OperandAt(1); } |
6625 HValue* dependency() const { | 6636 HValue* dependency() const { |
6626 DCHECK(HasDependency()); | 6637 DCHECK(HasDependency()); |
6627 return OperandAt(2); | 6638 return OperandAt(2); |
6628 } | 6639 } |
6629 bool HasDependency() const { return OperandAt(0) != OperandAt(2); } | 6640 bool HasDependency() const { return OperandAt(0) != OperandAt(2); } |
6630 uint32_t base_offset() const { return BaseOffsetField::decode(bit_field_); } | 6641 uint32_t base_offset() const { return BaseOffsetField::decode(bit_field_); } |
6631 bool TryIncreaseBaseOffset(uint32_t increase_by_value) override; | 6642 bool TryIncreaseBaseOffset(uint32_t increase_by_value) override; |
6632 HValue* GetKey() override { return key(); } | 6643 HValue* GetKey() override { return key(); } |
(...skipping 10 matching lines...) Expand all Loading... |
6643 LoadKeyedHoleMode hole_mode() const { | 6654 LoadKeyedHoleMode hole_mode() const { |
6644 return HoleModeField::decode(bit_field_); | 6655 return HoleModeField::decode(bit_field_); |
6645 } | 6656 } |
6646 | 6657 |
6647 Representation RequiredInputRepresentation(int index) override { | 6658 Representation RequiredInputRepresentation(int index) override { |
6648 // kind_fast: tagged[int32] (none) | 6659 // kind_fast: tagged[int32] (none) |
6649 // kind_double: tagged[int32] (none) | 6660 // kind_double: tagged[int32] (none) |
6650 // kind_fixed_typed_array: external[int32] (none) | 6661 // kind_fixed_typed_array: external[int32] (none) |
6651 // kind_external: external[int32] (none) | 6662 // kind_external: external[int32] (none) |
6652 if (index == 0) { | 6663 if (index == 0) { |
6653 return is_fixed_typed_array() ? Representation::External() | 6664 return is_typed_elements() ? Representation::External() |
6654 : Representation::Tagged(); | 6665 : Representation::Tagged(); |
6655 } | 6666 } |
6656 if (index == 1) { | 6667 if (index == 1) { |
6657 return ArrayInstructionInterface::KeyedAccessIndexRequirement( | 6668 return ArrayInstructionInterface::KeyedAccessIndexRequirement( |
6658 OperandAt(1)->representation()); | 6669 OperandAt(1)->representation()); |
6659 } | 6670 } |
6660 return Representation::None(); | 6671 return Representation::None(); |
6661 } | 6672 } |
6662 | 6673 |
6663 Representation observed_input_representation(int index) override { | 6674 Representation observed_input_representation(int index) override { |
6664 return RequiredInputRepresentation(index); | 6675 return RequiredInputRepresentation(index); |
(...skipping 28 matching lines...) Expand all Loading... |
6693 ? GetDefaultHeaderSizeForElementsKind(elements_kind) | 6704 ? GetDefaultHeaderSizeForElementsKind(elements_kind) |
6694 : offset; | 6705 : offset; |
6695 bit_field_ = ElementsKindField::encode(elements_kind) | | 6706 bit_field_ = ElementsKindField::encode(elements_kind) | |
6696 HoleModeField::encode(mode) | | 6707 HoleModeField::encode(mode) | |
6697 BaseOffsetField::encode(offset); | 6708 BaseOffsetField::encode(offset); |
6698 | 6709 |
6699 SetOperandAt(0, obj); | 6710 SetOperandAt(0, obj); |
6700 SetOperandAt(1, key); | 6711 SetOperandAt(1, key); |
6701 SetOperandAt(2, dependency != NULL ? dependency : obj); | 6712 SetOperandAt(2, dependency != NULL ? dependency : obj); |
6702 | 6713 |
6703 if (!is_fixed_typed_array()) { | 6714 if (!is_typed_elements()) { |
6704 // I can detect the case between storing double (holey and fast) and | 6715 // I can detect the case between storing double (holey and fast) and |
6705 // smi/object by looking at elements_kind_. | 6716 // smi/object by looking at elements_kind_. |
6706 DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) || | 6717 DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) || |
6707 IsFastDoubleElementsKind(elements_kind)); | 6718 IsFastDoubleElementsKind(elements_kind)); |
6708 | 6719 |
6709 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 6720 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
6710 if (IsFastSmiElementsKind(elements_kind) && | 6721 if (IsFastSmiElementsKind(elements_kind) && |
6711 (!IsHoleyElementsKind(elements_kind) || | 6722 (!IsHoleyElementsKind(elements_kind) || |
6712 mode == NEVER_RETURN_HOLE)) { | 6723 mode == NEVER_RETURN_HOLE)) { |
6713 set_type(HType::Smi()); | 6724 set_type(HType::Smi()); |
6714 if (SmiValuesAre32Bits() && !RequiresHoleCheck()) { | 6725 if (SmiValuesAre32Bits() && !RequiresHoleCheck()) { |
6715 set_representation(Representation::Integer32()); | 6726 set_representation(Representation::Integer32()); |
6716 } else { | 6727 } else { |
6717 set_representation(Representation::Smi()); | 6728 set_representation(Representation::Smi()); |
6718 } | 6729 } |
6719 } else { | 6730 } else { |
6720 set_representation(Representation::Tagged()); | 6731 set_representation(Representation::Tagged()); |
6721 } | 6732 } |
6722 | 6733 |
6723 SetDependsOnFlag(kArrayElements); | 6734 SetDependsOnFlag(kArrayElements); |
6724 } else { | 6735 } else { |
6725 set_representation(Representation::Double()); | 6736 set_representation(Representation::Double()); |
6726 SetDependsOnFlag(kDoubleArrayElements); | 6737 SetDependsOnFlag(kDoubleArrayElements); |
6727 } | 6738 } |
6728 } else { | 6739 } else { |
6729 if (elements_kind == FLOAT32_ELEMENTS || | 6740 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 6741 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
| 6742 elements_kind == FLOAT32_ELEMENTS || |
6730 elements_kind == FLOAT64_ELEMENTS) { | 6743 elements_kind == FLOAT64_ELEMENTS) { |
6731 set_representation(Representation::Double()); | 6744 set_representation(Representation::Double()); |
6732 } else { | 6745 } else { |
6733 set_representation(Representation::Integer32()); | 6746 set_representation(Representation::Integer32()); |
6734 } | 6747 } |
6735 | 6748 |
6736 if (is_fixed_typed_array()) { | 6749 if (is_external()) { |
6737 SetDependsOnFlag(kExternalMemory); | 6750 SetDependsOnFlag(kExternalMemory); |
| 6751 } else if (is_fixed_typed_array()) { |
6738 SetDependsOnFlag(kTypedArrayElements); | 6752 SetDependsOnFlag(kTypedArrayElements); |
6739 } else { | 6753 } else { |
6740 UNREACHABLE(); | 6754 UNREACHABLE(); |
6741 } | 6755 } |
6742 // Native code could change the specialized array. | 6756 // Native code could change the specialized array. |
6743 SetDependsOnFlag(kCalls); | 6757 SetDependsOnFlag(kCalls); |
6744 } | 6758 } |
6745 | 6759 |
6746 SetFlag(kUseGVN); | 6760 SetFlag(kUseGVN); |
6747 } | 6761 } |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7102 DECLARE_INSTRUCTION_FACTORY_P6(HStoreKeyed, HValue*, HValue*, HValue*, | 7116 DECLARE_INSTRUCTION_FACTORY_P6(HStoreKeyed, HValue*, HValue*, HValue*, |
7103 ElementsKind, StoreFieldOrKeyedMode, int); | 7117 ElementsKind, StoreFieldOrKeyedMode, int); |
7104 | 7118 |
7105 Representation RequiredInputRepresentation(int index) override { | 7119 Representation RequiredInputRepresentation(int index) override { |
7106 // kind_fast: tagged[int32] = tagged | 7120 // kind_fast: tagged[int32] = tagged |
7107 // kind_double: tagged[int32] = double | 7121 // kind_double: tagged[int32] = double |
7108 // kind_smi : tagged[int32] = smi | 7122 // kind_smi : tagged[int32] = smi |
7109 // kind_fixed_typed_array: tagged[int32] = (double | int32) | 7123 // kind_fixed_typed_array: tagged[int32] = (double | int32) |
7110 // kind_external: external[int32] = (double | int32) | 7124 // kind_external: external[int32] = (double | int32) |
7111 if (index == 0) { | 7125 if (index == 0) { |
7112 return is_fixed_typed_array() ? Representation::External() | 7126 return is_typed_elements() ? Representation::External() |
7113 : Representation::Tagged(); | 7127 : Representation::Tagged(); |
7114 } else if (index == 1) { | 7128 } else if (index == 1) { |
7115 return ArrayInstructionInterface::KeyedAccessIndexRequirement( | 7129 return ArrayInstructionInterface::KeyedAccessIndexRequirement( |
7116 OperandAt(1)->representation()); | 7130 OperandAt(1)->representation()); |
7117 } | 7131 } |
7118 | 7132 |
7119 DCHECK_EQ(index, 2); | 7133 DCHECK_EQ(index, 2); |
7120 return RequiredValueRepresentation(elements_kind(), store_mode()); | 7134 return RequiredValueRepresentation(elements_kind(), store_mode()); |
7121 } | 7135 } |
7122 | 7136 |
7123 static Representation RequiredValueRepresentation( | 7137 static Representation RequiredValueRepresentation( |
7124 ElementsKind kind, StoreFieldOrKeyedMode mode) { | 7138 ElementsKind kind, StoreFieldOrKeyedMode mode) { |
7125 if (IsDoubleOrFloatElementsKind(kind)) { | 7139 if (IsDoubleOrFloatElementsKind(kind)) { |
7126 return Representation::Double(); | 7140 return Representation::Double(); |
7127 } | 7141 } |
7128 | 7142 |
7129 if (kind == FAST_SMI_ELEMENTS && SmiValuesAre32Bits() && | 7143 if (kind == FAST_SMI_ELEMENTS && SmiValuesAre32Bits() && |
7130 mode == STORE_TO_INITIALIZED_ENTRY) { | 7144 mode == STORE_TO_INITIALIZED_ENTRY) { |
7131 return Representation::Integer32(); | 7145 return Representation::Integer32(); |
7132 } | 7146 } |
7133 | 7147 |
7134 if (IsFastSmiElementsKind(kind)) { | 7148 if (IsFastSmiElementsKind(kind)) { |
7135 return Representation::Smi(); | 7149 return Representation::Smi(); |
7136 } | 7150 } |
7137 | 7151 |
7138 if (IsFixedTypedArrayElementsKind(kind)) { | 7152 return IsExternalArrayElementsKind(kind) || |
7139 return Representation::Integer32(); | 7153 IsFixedTypedArrayElementsKind(kind) |
7140 } | 7154 ? Representation::Integer32() |
7141 return Representation::Tagged(); | 7155 : Representation::Tagged(); |
| 7156 } |
| 7157 |
| 7158 bool is_external() const { |
| 7159 return IsExternalArrayElementsKind(elements_kind()); |
7142 } | 7160 } |
7143 | 7161 |
7144 bool is_fixed_typed_array() const { | 7162 bool is_fixed_typed_array() const { |
7145 return IsFixedTypedArrayElementsKind(elements_kind()); | 7163 return IsFixedTypedArrayElementsKind(elements_kind()); |
7146 } | 7164 } |
7147 | 7165 |
| 7166 bool is_typed_elements() const { |
| 7167 return is_external() || is_fixed_typed_array(); |
| 7168 } |
| 7169 |
7148 Representation observed_input_representation(int index) override { | 7170 Representation observed_input_representation(int index) override { |
7149 if (index < 2) return RequiredInputRepresentation(index); | 7171 if (index < 2) return RequiredInputRepresentation(index); |
7150 if (IsUninitialized()) { | 7172 if (IsUninitialized()) { |
7151 return Representation::None(); | 7173 return Representation::None(); |
7152 } | 7174 } |
7153 Representation r = | 7175 Representation r = |
7154 RequiredValueRepresentation(elements_kind(), store_mode()); | 7176 RequiredValueRepresentation(elements_kind(), store_mode()); |
7155 // For fast object elements kinds, don't assume anything. | 7177 // For fast object elements kinds, don't assume anything. |
7156 if (r.IsTagged()) return Representation::None(); | 7178 if (r.IsTagged()) return Representation::None(); |
7157 return r; | 7179 return r; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7227 ElementsKindField::encode(elements_kind)), | 7249 ElementsKindField::encode(elements_kind)), |
7228 dominator_(NULL) { | 7250 dominator_(NULL) { |
7229 SetOperandAt(0, obj); | 7251 SetOperandAt(0, obj); |
7230 SetOperandAt(1, key); | 7252 SetOperandAt(1, key); |
7231 SetOperandAt(2, val); | 7253 SetOperandAt(2, val); |
7232 | 7254 |
7233 if (IsFastObjectElementsKind(elements_kind)) { | 7255 if (IsFastObjectElementsKind(elements_kind)) { |
7234 SetFlag(kTrackSideEffectDominators); | 7256 SetFlag(kTrackSideEffectDominators); |
7235 SetDependsOnFlag(kNewSpacePromotion); | 7257 SetDependsOnFlag(kNewSpacePromotion); |
7236 } | 7258 } |
7237 if (IsFastDoubleElementsKind(elements_kind)) { | 7259 if (is_external()) { |
| 7260 SetChangesFlag(kExternalMemory); |
| 7261 SetFlag(kAllowUndefinedAsNaN); |
| 7262 } else if (IsFastDoubleElementsKind(elements_kind)) { |
7238 SetChangesFlag(kDoubleArrayElements); | 7263 SetChangesFlag(kDoubleArrayElements); |
7239 } else if (IsFastSmiElementsKind(elements_kind)) { | 7264 } else if (IsFastSmiElementsKind(elements_kind)) { |
7240 SetChangesFlag(kArrayElements); | 7265 SetChangesFlag(kArrayElements); |
7241 } else if (is_fixed_typed_array()) { | 7266 } else if (is_fixed_typed_array()) { |
7242 SetChangesFlag(kTypedArrayElements); | 7267 SetChangesFlag(kTypedArrayElements); |
7243 SetChangesFlag(kExternalMemory); | |
7244 SetFlag(kAllowUndefinedAsNaN); | 7268 SetFlag(kAllowUndefinedAsNaN); |
7245 } else { | 7269 } else { |
7246 SetChangesFlag(kArrayElements); | 7270 SetChangesFlag(kArrayElements); |
7247 } | 7271 } |
7248 | 7272 |
7249 // {UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | 7273 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. |
7250 if (elements_kind >= UINT8_ELEMENTS && elements_kind <= INT32_ELEMENTS) { | 7274 if ((elements_kind >= EXTERNAL_INT8_ELEMENTS && |
| 7275 elements_kind <= EXTERNAL_UINT32_ELEMENTS) || |
| 7276 (elements_kind >= UINT8_ELEMENTS && |
| 7277 elements_kind <= INT32_ELEMENTS)) { |
7251 SetFlag(kTruncatingToInt32); | 7278 SetFlag(kTruncatingToInt32); |
7252 } | 7279 } |
7253 } | 7280 } |
7254 | 7281 |
7255 class IsDehoistedField : public BitField<bool, 0, 1> {}; | 7282 class IsDehoistedField : public BitField<bool, 0, 1> {}; |
7256 class IsUninitializedField : public BitField<bool, 1, 1> {}; | 7283 class IsUninitializedField : public BitField<bool, 1, 1> {}; |
7257 class StoreModeField : public BitField<StoreFieldOrKeyedMode, 2, 1> {}; | 7284 class StoreModeField : public BitField<StoreFieldOrKeyedMode, 2, 1> {}; |
7258 class ElementsKindField : public BitField<ElementsKind, 3, 5> {}; | 7285 class ElementsKindField : public BitField<ElementsKind, 3, 5> {}; |
7259 | 7286 |
7260 uint32_t base_offset_; | 7287 uint32_t base_offset_; |
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8068 }; | 8095 }; |
8069 | 8096 |
8070 | 8097 |
8071 | 8098 |
8072 #undef DECLARE_INSTRUCTION | 8099 #undef DECLARE_INSTRUCTION |
8073 #undef DECLARE_CONCRETE_INSTRUCTION | 8100 #undef DECLARE_CONCRETE_INSTRUCTION |
8074 | 8101 |
8075 } } // namespace v8::internal | 8102 } } // namespace v8::internal |
8076 | 8103 |
8077 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 8104 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |