OLD | NEW |
---|---|
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
7 #include "src/frames.h" | 7 #include "src/frames.h" |
8 #include "src/ic/handler-configuration.h" | 8 #include "src/ic/handler-configuration.h" |
9 #include "src/ic/stub-cache.h" | 9 #include "src/ic/stub-cache.h" |
10 | 10 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
120 return IntPtrConstant(left_constant - right_constant); | 120 return IntPtrConstant(left_constant - right_constant); |
121 } | 121 } |
122 } else if (is_right_constant) { | 122 } else if (is_right_constant) { |
123 if (right_constant == 0) { | 123 if (right_constant == 0) { |
124 return left; | 124 return left; |
125 } | 125 } |
126 } | 126 } |
127 return IntPtrSub(left, right); | 127 return IntPtrSub(left, right); |
128 } | 128 } |
129 | 129 |
130 Node* CodeStubAssembler::IntPtrRoundUpToPowerOfTwo32(Node* word32) { | |
Igor Sheludko
2016/10/24 12:00:55
I'm sorry for going back and forth. With word32 it
Camillo Bruni
2016/10/24 12:50:45
no problem :)
| |
131 CSA_ASSERT(UintPtrLessThanOrEqual(word32, IntPtrConstant(0x80000000u))); | |
132 word32 = IntPtrSub(word32, IntPtrConstant(1)); | |
133 for (int i = 1; i <= 16; i *= 2) { | |
134 word32 = WordOr(word32, WordShr(word32, IntPtrConstant(i))); | |
135 } | |
136 return IntPtrAdd(word32, IntPtrConstant(1)); | |
137 } | |
138 | |
139 Node* CodeStubAssembler::WordIsPowerOfTwo(Node* value) { | |
140 // value && !(value & (value - 1)) | |
141 return WordEqual( | |
142 Select(WordEqual(value, IntPtrConstant(0)), IntPtrConstant(1), | |
143 WordAnd(value, IntPtrSub(value, IntPtrConstant(1)))), | |
144 IntPtrConstant(0)); | |
145 } | |
146 | |
130 Node* CodeStubAssembler::Float64Round(Node* x) { | 147 Node* CodeStubAssembler::Float64Round(Node* x) { |
131 Node* one = Float64Constant(1.0); | 148 Node* one = Float64Constant(1.0); |
132 Node* one_half = Float64Constant(0.5); | 149 Node* one_half = Float64Constant(0.5); |
133 | 150 |
134 Variable var_x(this, MachineRepresentation::kFloat64); | 151 Variable var_x(this, MachineRepresentation::kFloat64); |
135 Label return_x(this); | 152 Label return_x(this); |
136 | 153 |
137 // Round up {x} towards Infinity. | 154 // Round up {x} towards Infinity. |
138 var_x.Bind(Float64Ceil(x)); | 155 var_x.Bind(Float64Ceil(x)); |
139 | 156 |
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1098 Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0))); | 1115 Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0))); |
1099 return IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); | 1116 return IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); |
1100 } | 1117 } |
1101 | 1118 |
1102 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) { | 1119 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) { |
1103 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); | 1120 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); |
1104 return Int32LessThanOrEqual(instance_type, | 1121 return Int32LessThanOrEqual(instance_type, |
1105 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)); | 1122 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)); |
1106 } | 1123 } |
1107 | 1124 |
1125 Node* CodeStubAssembler::IsDictionaryMap(Node* map) { | |
1126 Node* bit_field3 = LoadMapBitField3(map); | |
1127 return Word32NotEqual(IsSetWord32<Map::DictionaryMap>(bit_field3), | |
1128 Int32Constant(0)); | |
1129 } | |
1130 | |
1108 Node* CodeStubAssembler::LoadNameHashField(Node* name) { | 1131 Node* CodeStubAssembler::LoadNameHashField(Node* name) { |
1109 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); | 1132 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); |
1110 } | 1133 } |
1111 | 1134 |
1112 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) { | 1135 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) { |
1113 Node* hash_field = LoadNameHashField(name); | 1136 Node* hash_field = LoadNameHashField(name); |
1114 if (if_hash_not_computed != nullptr) { | 1137 if (if_hash_not_computed != nullptr) { |
1115 GotoIf(Word32Equal( | 1138 GotoIf(Word32Equal( |
1116 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), | 1139 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), |
1117 Int32Constant(0)), | 1140 Int32Constant(0)), |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1652 AllocateFixedArray(elements_kind, length_intptr, parameter_mode); | 1675 AllocateFixedArray(elements_kind, length_intptr, parameter_mode); |
1653 StoreObjectField(result, JSArray::kElementsOffset, elements); | 1676 StoreObjectField(result, JSArray::kElementsOffset, elements); |
1654 | 1677 |
1655 // Fill in the elements with undefined. | 1678 // Fill in the elements with undefined. |
1656 FillFixedArrayWithValue(elements_kind, elements, zero, length_intptr, | 1679 FillFixedArrayWithValue(elements_kind, elements, zero, length_intptr, |
1657 Heap::kUndefinedValueRootIndex, parameter_mode); | 1680 Heap::kUndefinedValueRootIndex, parameter_mode); |
1658 | 1681 |
1659 return result; | 1682 return result; |
1660 } | 1683 } |
1661 | 1684 |
1685 Node* CodeStubAssembler::AllocateNameDictionary(int at_least_space_for) { | |
1686 return AllocateNameDictionary(IntPtrConstant(at_least_space_for)); | |
1687 } | |
1688 | |
1689 Node* CodeStubAssembler::AllocateNameDictionary(Node* at_least_space_for) { | |
1690 CSA_ASSERT(UintPtrLessThanOrEqual( | |
1691 at_least_space_for, IntPtrConstant(NameDictionary::kMaxCapacity))); | |
1692 | |
1693 Node* capacity = HashTableComputeCapacity(at_least_space_for); | |
1694 CSA_ASSERT(WordIsPowerOfTwo(capacity)); | |
1695 | |
1696 Node* length = EntryToIndex<NameDictionary>(capacity); | |
1697 Node* store_size = | |
1698 IntPtrAddFoldConstants(WordShl(length, IntPtrConstant(kPointerSizeLog2)), | |
1699 IntPtrConstant(NameDictionary::kHeaderSize)); | |
1700 | |
1701 Node* result = Allocate(store_size); | |
1702 // Initialize FixedArray fields. | |
1703 StoreObjectFieldRoot(result, FixedArray::kMapOffset, | |
1704 Heap::kHashTableMapRootIndex); | |
1705 StoreObjectFieldNoWriteBarrier(result, FixedArray::kLengthOffset, | |
1706 SmiFromWord(length)); | |
1707 // Initialized HashTable fields. | |
1708 Node* zero = SmiConstant(0); | |
1709 StoreFixedArrayElement(result, NameDictionary::kNumberOfElementsIndex, zero, | |
1710 SKIP_WRITE_BARRIER); | |
1711 StoreFixedArrayElement(result, NameDictionary::kNumberOfDeletedElementsIndex, | |
1712 zero, SKIP_WRITE_BARRIER); | |
1713 StoreFixedArrayElement(result, NameDictionary::kCapacityIndex, | |
1714 SmiTag(capacity), SKIP_WRITE_BARRIER); | |
1715 // Initialize Dictionary fields. | |
1716 Node* filler = LoadRoot(Heap::kUndefinedValueRootIndex); | |
1717 StoreFixedArrayElement(result, NameDictionary::kMaxNumberKeyIndex, filler, | |
1718 SKIP_WRITE_BARRIER); | |
1719 StoreFixedArrayElement(result, NameDictionary::kNextEnumerationIndexIndex, | |
1720 SmiConstant(PropertyDetails::kInitialIndex), | |
1721 SKIP_WRITE_BARRIER); | |
1722 | |
1723 // Initialize NameDictionary elements. | |
1724 Node* start_address = IntPtrAdd( | |
1725 result, IntPtrConstant(NameDictionary::OffsetOfElementAt( | |
1726 NameDictionary::kElementsStartIndex) - | |
1727 kHeapObjectTag)); | |
1728 Node* end_address = IntPtrAdd( | |
1729 result, | |
1730 IntPtrSubFoldConstants(store_size, IntPtrConstant(kHeapObjectTag))); | |
1731 StoreFieldsNoWriteBarrier(start_address, end_address, filler); | |
1732 return result; | |
1733 } | |
1734 | |
1662 Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties, | 1735 Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties, |
1663 Node* elements) { | 1736 Node* elements) { |
1664 Node* size = | 1737 Node* size = |
1665 IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize)); | 1738 IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize)); |
1666 CSA_ASSERT(IsRegularHeapObjectSize(size)); | 1739 CSA_ASSERT(IsRegularHeapObjectSize(size)); |
1667 Node* object = Allocate(size); | 1740 Node* object = Allocate(size); |
1668 StoreMapNoWriteBarrier(object, map); | 1741 StoreMapNoWriteBarrier(object, map); |
1669 InitializeJSObjectFromMap(object, map, size, properties, elements); | 1742 InitializeJSObjectFromMap(object, map, size, properties, elements); |
1670 return object; | 1743 return object; |
1671 } | 1744 } |
1672 | 1745 |
1673 void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map, | 1746 void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map, |
1674 Node* size, Node* properties, | 1747 Node* size, Node* properties, |
1675 Node* elements) { | 1748 Node* elements) { |
1676 // This helper assumes that the object is in new-space, as guarded by the | 1749 // This helper assumes that the object is in new-space, as guarded by the |
1677 // check in AllocatedJSObjectFromMap. | 1750 // check in AllocatedJSObjectFromMap. |
1678 if (properties == nullptr) { | 1751 if (properties == nullptr) { |
1752 CSA_ASSERT(Word32BinaryNot(IsDictionaryMap((map)))); | |
1679 StoreObjectFieldRoot(object, JSObject::kPropertiesOffset, | 1753 StoreObjectFieldRoot(object, JSObject::kPropertiesOffset, |
1680 Heap::kEmptyFixedArrayRootIndex); | 1754 Heap::kEmptyFixedArrayRootIndex); |
1681 } else { | 1755 } else { |
1682 StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset, | 1756 StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset, |
1683 properties); | 1757 properties); |
1684 } | 1758 } |
1685 if (elements == nullptr) { | 1759 if (elements == nullptr) { |
1686 StoreObjectFieldRoot(object, JSObject::kElementsOffset, | 1760 StoreObjectFieldRoot(object, JSObject::kElementsOffset, |
1687 Heap::kEmptyFixedArrayRootIndex); | 1761 Heap::kEmptyFixedArrayRootIndex); |
1688 } else { | 1762 } else { |
(...skipping 2139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3828 Goto(if_keyisindex); | 3902 Goto(if_keyisindex); |
3829 } | 3903 } |
3830 | 3904 |
3831 template <typename Dictionary> | 3905 template <typename Dictionary> |
3832 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { | 3906 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { |
3833 Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize)); | 3907 Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize)); |
3834 return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex + | 3908 return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex + |
3835 field_index)); | 3909 field_index)); |
3836 } | 3910 } |
3837 | 3911 |
3912 template Node* CodeStubAssembler::EntryToIndex<NameDictionary>(Node*, int); | |
3913 template Node* CodeStubAssembler::EntryToIndex<GlobalDictionary>(Node*, int); | |
3914 | |
3915 Node* CodeStubAssembler::HashTableComputeCapacity(Node* at_least_space_for) { | |
3916 Node* capacity = IntPtrRoundUpToPowerOfTwo32( | |
3917 WordShl(at_least_space_for, IntPtrConstant(1))); | |
3918 return IntPtrMax(capacity, IntPtrConstant(HashTableBase::kMinCapacity)); | |
3919 } | |
3920 | |
3921 Node* CodeStubAssembler::IntPtrMax(Node* left, Node* right) { | |
3922 return Select(IntPtrGreaterThanOrEqual(left, right), left, right); | |
3923 } | |
3924 | |
3838 template <typename Dictionary> | 3925 template <typename Dictionary> |
3839 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary, | 3926 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary, |
3840 Node* unique_name, Label* if_found, | 3927 Node* unique_name, Label* if_found, |
3841 Variable* var_name_index, | 3928 Variable* var_name_index, |
3842 Label* if_not_found, | 3929 Label* if_not_found, |
3843 int inlined_probes) { | 3930 int inlined_probes) { |
3844 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); | 3931 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); |
3845 Comment("NameDictionaryLookup"); | 3932 Comment("NameDictionaryLookup"); |
3846 | 3933 |
3847 Node* capacity = SmiUntag(LoadFixedArrayElement( | 3934 Node* capacity = SmiUntag(LoadFixedArrayElement( |
(...skipping 4489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8337 Node* buffer_bit_field = LoadObjectField( | 8424 Node* buffer_bit_field = LoadObjectField( |
8338 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); | 8425 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); |
8339 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); | 8426 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); |
8340 | 8427 |
8341 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), | 8428 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), |
8342 Int32Constant(0)); | 8429 Int32Constant(0)); |
8343 } | 8430 } |
8344 | 8431 |
8345 } // namespace internal | 8432 } // namespace internal |
8346 } // namespace v8 | 8433 } // namespace v8 |
OLD | NEW |