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* value) { | |
131 CSA_ASSERT(UintPtrLessThanOrEqual(value, IntPtrConstant(0x80000000u))); | |
132 value = IntPtrSubWithOverflow(value, IntPtrConstant(1)); | |
Igor Sheludko
2016/10/21 15:01:10
You should use normal IntPtrSub() here since you d
Camillo Bruni
2016/10/24 09:53:07
done.
| |
133 for (int i = 1; i <= 16; i *= 2) { | |
Igor Sheludko
2016/10/21 15:01:10
This implementation is actually for word32. I don'
Camillo Bruni
2016/10/21 16:27:32
The CSA_ASSERT is there for this. Will add a prope
Camillo Bruni
2016/10/24 09:53:07
done.
| |
134 value = WordOr(value, WordShr(value, IntPtrConstant(i))); | |
135 } | |
136 return IntPtrAdd(value, 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, IntPtrSubWithOverflow(value, IntPtrConstant(1)))), | |
Igor Sheludko
2016/10/21 15:01:10
Same here.
Camillo Bruni
2016/10/21 16:27:32
If I do IntPtrSub the whole second part of the sel
Camillo Bruni
2016/10/24 09:53:07
done.
| |
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 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1099 Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0))); | 1116 Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0))); |
1100 return IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); | 1117 return IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); |
1101 } | 1118 } |
1102 | 1119 |
1103 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) { | 1120 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) { |
1104 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); | 1121 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); |
1105 return Int32LessThanOrEqual(instance_type, | 1122 return Int32LessThanOrEqual(instance_type, |
1106 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)); | 1123 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)); |
1107 } | 1124 } |
1108 | 1125 |
1126 Node* CodeStubAssembler::IsDictionaryMap(Node* map) { | |
1127 Node* bit_field3 = LoadMapBitField3(map); | |
1128 return Word32NotEqual(BitFieldDecode<Map::DictionaryMap>(bit_field3), | |
Igor Sheludko
2016/10/21 15:01:09
return IsSetWord32<Map::DictionaryMap>(bit_field3)
Camillo Bruni
2016/10/24 09:53:07
done.
| |
1129 Int32Constant(0)); | |
1130 } | |
1131 | |
1109 Node* CodeStubAssembler::LoadNameHashField(Node* name) { | 1132 Node* CodeStubAssembler::LoadNameHashField(Node* name) { |
1110 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); | 1133 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); |
1111 } | 1134 } |
1112 | 1135 |
1113 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) { | 1136 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) { |
1114 Node* hash_field = LoadNameHashField(name); | 1137 Node* hash_field = LoadNameHashField(name); |
1115 if (if_hash_not_computed != nullptr) { | 1138 if (if_hash_not_computed != nullptr) { |
1116 GotoIf(Word32Equal( | 1139 GotoIf(Word32Equal( |
1117 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), | 1140 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), |
1118 Int32Constant(0)), | 1141 Int32Constant(0)), |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1653 AllocateFixedArray(elements_kind, length_intptr, parameter_mode); | 1676 AllocateFixedArray(elements_kind, length_intptr, parameter_mode); |
1654 StoreObjectField(result, JSArray::kElementsOffset, elements); | 1677 StoreObjectField(result, JSArray::kElementsOffset, elements); |
1655 | 1678 |
1656 // Fill in the elements with undefined. | 1679 // Fill in the elements with undefined. |
1657 FillFixedArrayWithValue(elements_kind, elements, zero, length_intptr, | 1680 FillFixedArrayWithValue(elements_kind, elements, zero, length_intptr, |
1658 Heap::kUndefinedValueRootIndex, parameter_mode); | 1681 Heap::kUndefinedValueRootIndex, parameter_mode); |
1659 | 1682 |
1660 return result; | 1683 return result; |
1661 } | 1684 } |
1662 | 1685 |
1686 Node* CodeStubAssembler::AllocateNameDictionary(int at_least_space_for) { | |
1687 return AllocateNameDictionary(IntPtrConstant(at_least_space_for)); | |
1688 } | |
1689 | |
1690 Node* CodeStubAssembler::AllocateNameDictionary(Node* at_least_space_for) { | |
1691 CSA_ASSERT(UintPtrLessThanOrEqual( | |
1692 at_least_space_for, IntPtrConstant(NameDictionary::kMaxCapacity))); | |
1693 | |
1694 Node* capacity = HashTableComputeCapacity(at_least_space_for); | |
1695 CSA_ASSERT(WordIsPowerOfTwo(capacity)); | |
1696 | |
1697 Node* length = EntryToIndex<NameDictionary>(capacity); | |
1698 Node* store_size = | |
1699 IntPtrAddFoldConstants(WordShl(length, IntPtrConstant(kPointerSizeLog2)), | |
1700 IntPtrConstant(NameDictionary::kHeaderSize)); | |
1701 | |
1702 Node* result = Allocate(store_size); | |
1703 // Initialize FixedArray fields. | |
1704 StoreObjectFieldRoot(result, Internals::kHeapObjectMapOffset, | |
Igor Sheludko
2016/10/21 15:01:10
Why not FixedArray::kMapOffset to be consistent?
Camillo Bruni
2016/10/24 09:53:07
yup, done.
| |
1705 Heap::kHashTableMapRootIndex); | |
1706 StoreObjectFieldNoWriteBarrier(result, FixedArray::kLengthOffset, | |
1707 SmiFromWord(length)); | |
1708 // Initialized HashTable fields. | |
1709 Node* zero = SmiConstant(0); | |
1710 StoreFixedArrayElement(result, NameDictionary::kNumberOfElementsIndex, zero, | |
1711 SKIP_WRITE_BARRIER); | |
1712 StoreFixedArrayElement(result, NameDictionary::kNumberOfDeletedElementsIndex, | |
1713 zero, SKIP_WRITE_BARRIER); | |
1714 StoreFixedArrayElement(result, NameDictionary::kCapacityIndex, | |
1715 SmiTag(capacity), SKIP_WRITE_BARRIER); | |
1716 // Initialize Dictionary fields. | |
1717 Node* filler = LoadRoot(Heap::kUndefinedValueRootIndex); | |
1718 StoreFixedArrayElement(result, NameDictionary::kMaxNumberKeyIndex, filler, | |
1719 SKIP_WRITE_BARRIER); | |
1720 StoreFixedArrayElement(result, NameDictionary::kNextEnumerationIndexIndex, | |
1721 SmiConstant(PropertyDetails::kInitialIndex), | |
1722 SKIP_WRITE_BARRIER); | |
1723 | |
1724 // Initialize NameDictionary elements. | |
1725 Node* start_address = IntPtrAdd( | |
1726 result, | |
1727 IntPtrConstant(NameDictionary::kElementsStartOffset - kHeapObjectTag)); | |
Igor Sheludko
2016/10/21 15:01:10
(NameDictionay::OffsetOfElementAt(NameDictionary::
Camillo Bruni
2016/10/21 16:27:31
oh, somehow missed that :)
| |
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 | |
1663 Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties, | 1735 Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties, |
1664 Node* elements) { | 1736 Node* elements) { |
1665 Node* size = | 1737 Node* size = |
1666 IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize)); | 1738 IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize)); |
1667 CSA_ASSERT(IsRegularHeapObjectSize(size)); | 1739 CSA_ASSERT(IsRegularHeapObjectSize(size)); |
1668 Node* object = Allocate(size); | 1740 Node* object = Allocate(size); |
1669 StoreMapNoWriteBarrier(object, map); | 1741 StoreMapNoWriteBarrier(object, map); |
1670 InitializeJSObjectFromMap(object, map, size, properties, elements); | 1742 InitializeJSObjectFromMap(object, map, size, properties, elements); |
1671 return object; | 1743 return object; |
1672 } | 1744 } |
1673 | 1745 |
1674 void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map, | 1746 void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map, |
1675 Node* size, Node* properties, | 1747 Node* size, Node* properties, |
1676 Node* elements) { | 1748 Node* elements) { |
1677 // 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 |
1678 // check in AllocatedJSObjectFromMap. | 1750 // check in AllocatedJSObjectFromMap. |
1679 if (properties == nullptr) { | 1751 if (properties == nullptr) { |
1752 CSA_ASSERT(Word32BinaryNot(IsDictionaryMap((map)))); | |
1680 StoreObjectFieldRoot(object, JSObject::kPropertiesOffset, | 1753 StoreObjectFieldRoot(object, JSObject::kPropertiesOffset, |
1681 Heap::kEmptyFixedArrayRootIndex); | 1754 Heap::kEmptyFixedArrayRootIndex); |
1682 } else { | 1755 } else { |
1683 StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset, | 1756 StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset, |
1684 properties); | 1757 properties); |
1685 } | 1758 } |
1686 if (elements == nullptr) { | 1759 if (elements == nullptr) { |
1687 StoreObjectFieldRoot(object, JSObject::kElementsOffset, | 1760 StoreObjectFieldRoot(object, JSObject::kElementsOffset, |
1688 Heap::kEmptyFixedArrayRootIndex); | 1761 Heap::kEmptyFixedArrayRootIndex); |
1689 } else { | 1762 } else { |
(...skipping 2128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3818 Goto(if_keyisindex); | 3891 Goto(if_keyisindex); |
3819 } | 3892 } |
3820 | 3893 |
3821 template <typename Dictionary> | 3894 template <typename Dictionary> |
3822 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { | 3895 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { |
3823 Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize)); | 3896 Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize)); |
3824 return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex + | 3897 return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex + |
3825 field_index)); | 3898 field_index)); |
3826 } | 3899 } |
3827 | 3900 |
3901 template Node* CodeStubAssembler::EntryToIndex<NameDictionary>(Node*, int); | |
3902 template Node* CodeStubAssembler::EntryToIndex<GlobalDictionary>(Node*, int); | |
3903 | |
3904 Node* CodeStubAssembler::HashTableComputeCapacity(Node* at_least_space_for) { | |
3905 Node* capacity = IntPtrRoundUpToPowerOfTwo32( | |
3906 WordShl(at_least_space_for, IntPtrConstant(1))); | |
3907 return IntPtrMax(capacity, IntPtrConstant(HashTableBase::kMinCapacity)); | |
3908 } | |
3909 | |
3910 Node* CodeStubAssembler::IntPtrMax(Node* left, Node* right) { | |
3911 return Select(IntPtrGreaterThanOrEqual(left, right), left, right); | |
3912 } | |
3913 | |
3828 template <typename Dictionary> | 3914 template <typename Dictionary> |
3829 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary, | 3915 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary, |
3830 Node* unique_name, Label* if_found, | 3916 Node* unique_name, Label* if_found, |
3831 Variable* var_name_index, | 3917 Variable* var_name_index, |
3832 Label* if_not_found, | 3918 Label* if_not_found, |
3833 int inlined_probes) { | 3919 int inlined_probes) { |
3834 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); | 3920 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); |
3835 Comment("NameDictionaryLookup"); | 3921 Comment("NameDictionaryLookup"); |
3836 | 3922 |
3837 Node* capacity = SmiUntag(LoadFixedArrayElement( | 3923 Node* capacity = SmiUntag(LoadFixedArrayElement( |
(...skipping 4491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8329 Node* buffer_bit_field = LoadObjectField( | 8415 Node* buffer_bit_field = LoadObjectField( |
8330 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); | 8416 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); |
8331 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); | 8417 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); |
8332 | 8418 |
8333 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), | 8419 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), |
8334 Int32Constant(0)); | 8420 Int32Constant(0)); |
8335 } | 8421 } |
8336 | 8422 |
8337 } // namespace internal | 8423 } // namespace internal |
8338 } // namespace v8 | 8424 } // namespace v8 |
OLD | NEW |