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 Comment("IntPtrRoundUpToPowerOfTwo32"); |
| 132 CSA_ASSERT(UintPtrLessThanOrEqual(value, IntPtrConstant(0x80000000u))); |
| 133 value = IntPtrSub(value, IntPtrConstant(1)); |
| 134 for (int i = 1; i <= 16; i *= 2) { |
| 135 value = WordOr(value, WordShr(value, IntPtrConstant(i))); |
| 136 } |
| 137 return IntPtrAdd(value, IntPtrConstant(1)); |
| 138 } |
| 139 |
| 140 Node* CodeStubAssembler::WordIsPowerOfTwo(Node* value) { |
| 141 // value && !(value & (value - 1)) |
| 142 return WordEqual( |
| 143 Select(WordEqual(value, IntPtrConstant(0)), IntPtrConstant(1), |
| 144 WordAnd(value, IntPtrSub(value, IntPtrConstant(1)))), |
| 145 IntPtrConstant(0)); |
| 146 } |
| 147 |
130 Node* CodeStubAssembler::Float64Round(Node* x) { | 148 Node* CodeStubAssembler::Float64Round(Node* x) { |
131 Node* one = Float64Constant(1.0); | 149 Node* one = Float64Constant(1.0); |
132 Node* one_half = Float64Constant(0.5); | 150 Node* one_half = Float64Constant(0.5); |
133 | 151 |
134 Variable var_x(this, MachineRepresentation::kFloat64); | 152 Variable var_x(this, MachineRepresentation::kFloat64); |
135 Label return_x(this); | 153 Label return_x(this); |
136 | 154 |
137 // Round up {x} towards Infinity. | 155 // Round up {x} towards Infinity. |
138 var_x.Bind(Float64Ceil(x)); | 156 var_x.Bind(Float64Ceil(x)); |
139 | 157 |
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
768 Goto(&merge_address); | 786 Goto(&merge_address); |
769 | 787 |
770 Bind(&merge_address); | 788 Bind(&merge_address); |
771 // Update the top. | 789 // Update the top. |
772 StoreNoWriteBarrier(MachineType::PointerRepresentation(), top_address, | 790 StoreNoWriteBarrier(MachineType::PointerRepresentation(), top_address, |
773 IntPtrAdd(top, adjusted_size.value())); | 791 IntPtrAdd(top, adjusted_size.value())); |
774 return address.value(); | 792 return address.value(); |
775 } | 793 } |
776 | 794 |
777 Node* CodeStubAssembler::Allocate(Node* size_in_bytes, AllocationFlags flags) { | 795 Node* CodeStubAssembler::Allocate(Node* size_in_bytes, AllocationFlags flags) { |
| 796 Comment("Allocate"); |
778 bool const new_space = !(flags & kPretenured); | 797 bool const new_space = !(flags & kPretenured); |
779 Node* top_address = ExternalConstant( | 798 Node* top_address = ExternalConstant( |
780 new_space | 799 new_space |
781 ? ExternalReference::new_space_allocation_top_address(isolate()) | 800 ? ExternalReference::new_space_allocation_top_address(isolate()) |
782 : ExternalReference::old_space_allocation_top_address(isolate())); | 801 : ExternalReference::old_space_allocation_top_address(isolate())); |
783 Node* limit_address = ExternalConstant( | 802 Node* limit_address = ExternalConstant( |
784 new_space | 803 new_space |
785 ? ExternalReference::new_space_allocation_limit_address(isolate()) | 804 ? ExternalReference::new_space_allocation_limit_address(isolate()) |
786 : ExternalReference::old_space_allocation_limit_address(isolate())); | 805 : ExternalReference::old_space_allocation_limit_address(isolate())); |
787 | 806 |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1098 Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0))); | 1117 Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0))); |
1099 return IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); | 1118 return IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); |
1100 } | 1119 } |
1101 | 1120 |
1102 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) { | 1121 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) { |
1103 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); | 1122 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); |
1104 return Int32LessThanOrEqual(instance_type, | 1123 return Int32LessThanOrEqual(instance_type, |
1105 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)); | 1124 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)); |
1106 } | 1125 } |
1107 | 1126 |
| 1127 Node* CodeStubAssembler::IsDictionaryMap(Node* map) { |
| 1128 Node* bit_field3 = LoadMapBitField3(map); |
| 1129 return Word32NotEqual(IsSetWord32<Map::DictionaryMap>(bit_field3), |
| 1130 Int32Constant(0)); |
| 1131 } |
| 1132 |
1108 Node* CodeStubAssembler::LoadNameHashField(Node* name) { | 1133 Node* CodeStubAssembler::LoadNameHashField(Node* name) { |
1109 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); | 1134 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); |
1110 } | 1135 } |
1111 | 1136 |
1112 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) { | 1137 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) { |
1113 Node* hash_field = LoadNameHashField(name); | 1138 Node* hash_field = LoadNameHashField(name); |
1114 if (if_hash_not_computed != nullptr) { | 1139 if (if_hash_not_computed != nullptr) { |
1115 GotoIf(Word32Equal( | 1140 GotoIf(Word32Equal( |
1116 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), | 1141 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), |
1117 Int32Constant(0)), | 1142 Int32Constant(0)), |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1652 AllocateFixedArray(elements_kind, length_intptr, parameter_mode); | 1677 AllocateFixedArray(elements_kind, length_intptr, parameter_mode); |
1653 StoreObjectField(result, JSArray::kElementsOffset, elements); | 1678 StoreObjectField(result, JSArray::kElementsOffset, elements); |
1654 | 1679 |
1655 // Fill in the elements with undefined. | 1680 // Fill in the elements with undefined. |
1656 FillFixedArrayWithValue(elements_kind, elements, zero, length_intptr, | 1681 FillFixedArrayWithValue(elements_kind, elements, zero, length_intptr, |
1657 Heap::kUndefinedValueRootIndex, parameter_mode); | 1682 Heap::kUndefinedValueRootIndex, parameter_mode); |
1658 | 1683 |
1659 return result; | 1684 return result; |
1660 } | 1685 } |
1661 | 1686 |
| 1687 Node* CodeStubAssembler::AllocateNameDictionary(int at_least_space_for) { |
| 1688 return AllocateNameDictionary(IntPtrConstant(at_least_space_for)); |
| 1689 } |
| 1690 |
| 1691 Node* CodeStubAssembler::AllocateNameDictionary(Node* at_least_space_for) { |
| 1692 CSA_ASSERT(UintPtrLessThanOrEqual( |
| 1693 at_least_space_for, IntPtrConstant(NameDictionary::kMaxCapacity))); |
| 1694 |
| 1695 Node* capacity = HashTableComputeCapacity(at_least_space_for); |
| 1696 CSA_ASSERT(WordIsPowerOfTwo(capacity)); |
| 1697 |
| 1698 Node* length = EntryToIndex<NameDictionary>(capacity); |
| 1699 Node* store_size = |
| 1700 IntPtrAddFoldConstants(WordShl(length, IntPtrConstant(kPointerSizeLog2)), |
| 1701 IntPtrConstant(NameDictionary::kHeaderSize)); |
| 1702 |
| 1703 Node* result = Allocate(store_size); |
| 1704 Comment("Initialize NameDictionary"); |
| 1705 // Initialize FixedArray fields. |
| 1706 StoreObjectFieldRoot(result, FixedArray::kMapOffset, |
| 1707 Heap::kHashTableMapRootIndex); |
| 1708 StoreObjectFieldNoWriteBarrier(result, FixedArray::kLengthOffset, |
| 1709 SmiFromWord(length)); |
| 1710 // Initialized HashTable fields. |
| 1711 Node* zero = SmiConstant(0); |
| 1712 StoreFixedArrayElement(result, NameDictionary::kNumberOfElementsIndex, zero, |
| 1713 SKIP_WRITE_BARRIER); |
| 1714 StoreFixedArrayElement(result, NameDictionary::kNumberOfDeletedElementsIndex, |
| 1715 zero, SKIP_WRITE_BARRIER); |
| 1716 StoreFixedArrayElement(result, NameDictionary::kCapacityIndex, |
| 1717 SmiTag(capacity), SKIP_WRITE_BARRIER); |
| 1718 // Initialize Dictionary fields. |
| 1719 Node* filler = LoadRoot(Heap::kUndefinedValueRootIndex); |
| 1720 StoreFixedArrayElement(result, NameDictionary::kMaxNumberKeyIndex, filler, |
| 1721 SKIP_WRITE_BARRIER); |
| 1722 StoreFixedArrayElement(result, NameDictionary::kNextEnumerationIndexIndex, |
| 1723 SmiConstant(PropertyDetails::kInitialIndex), |
| 1724 SKIP_WRITE_BARRIER); |
| 1725 |
| 1726 // Initialize NameDictionary elements. |
| 1727 Node* start_address = IntPtrAdd( |
| 1728 result, IntPtrConstant(NameDictionary::OffsetOfElementAt( |
| 1729 NameDictionary::kElementsStartIndex) - |
| 1730 kHeapObjectTag)); |
| 1731 Node* end_address = IntPtrAdd( |
| 1732 result, |
| 1733 IntPtrSubFoldConstants(store_size, IntPtrConstant(kHeapObjectTag))); |
| 1734 StoreFieldsNoWriteBarrier(start_address, end_address, filler); |
| 1735 return result; |
| 1736 } |
| 1737 |
1662 Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties, | 1738 Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties, |
1663 Node* elements) { | 1739 Node* elements) { |
1664 Node* size = | 1740 Node* size = |
1665 IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize)); | 1741 IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize)); |
1666 CSA_ASSERT(IsRegularHeapObjectSize(size)); | 1742 CSA_ASSERT(IsRegularHeapObjectSize(size)); |
1667 Node* object = Allocate(size); | 1743 Node* object = Allocate(size); |
1668 StoreMapNoWriteBarrier(object, map); | 1744 StoreMapNoWriteBarrier(object, map); |
1669 InitializeJSObjectFromMap(object, map, size, properties, elements); | 1745 InitializeJSObjectFromMap(object, map, size, properties, elements); |
1670 return object; | 1746 return object; |
1671 } | 1747 } |
1672 | 1748 |
1673 void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map, | 1749 void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map, |
1674 Node* size, Node* properties, | 1750 Node* size, Node* properties, |
1675 Node* elements) { | 1751 Node* elements) { |
1676 // This helper assumes that the object is in new-space, as guarded by the | 1752 // This helper assumes that the object is in new-space, as guarded by the |
1677 // check in AllocatedJSObjectFromMap. | 1753 // check in AllocatedJSObjectFromMap. |
1678 if (properties == nullptr) { | 1754 if (properties == nullptr) { |
| 1755 CSA_ASSERT(Word32BinaryNot(IsDictionaryMap((map)))); |
1679 StoreObjectFieldRoot(object, JSObject::kPropertiesOffset, | 1756 StoreObjectFieldRoot(object, JSObject::kPropertiesOffset, |
1680 Heap::kEmptyFixedArrayRootIndex); | 1757 Heap::kEmptyFixedArrayRootIndex); |
1681 } else { | 1758 } else { |
1682 StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset, | 1759 StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset, |
1683 properties); | 1760 properties); |
1684 } | 1761 } |
1685 if (elements == nullptr) { | 1762 if (elements == nullptr) { |
1686 StoreObjectFieldRoot(object, JSObject::kElementsOffset, | 1763 StoreObjectFieldRoot(object, JSObject::kElementsOffset, |
1687 Heap::kEmptyFixedArrayRootIndex); | 1764 Heap::kEmptyFixedArrayRootIndex); |
1688 } else { | 1765 } else { |
(...skipping 2139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3828 Goto(if_keyisindex); | 3905 Goto(if_keyisindex); |
3829 } | 3906 } |
3830 | 3907 |
3831 template <typename Dictionary> | 3908 template <typename Dictionary> |
3832 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { | 3909 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { |
3833 Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize)); | 3910 Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize)); |
3834 return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex + | 3911 return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex + |
3835 field_index)); | 3912 field_index)); |
3836 } | 3913 } |
3837 | 3914 |
| 3915 template Node* CodeStubAssembler::EntryToIndex<NameDictionary>(Node*, int); |
| 3916 template Node* CodeStubAssembler::EntryToIndex<GlobalDictionary>(Node*, int); |
| 3917 |
| 3918 Node* CodeStubAssembler::HashTableComputeCapacity(Node* at_least_space_for) { |
| 3919 Node* capacity = IntPtrRoundUpToPowerOfTwo32( |
| 3920 WordShl(at_least_space_for, IntPtrConstant(1))); |
| 3921 return IntPtrMax(capacity, IntPtrConstant(HashTableBase::kMinCapacity)); |
| 3922 } |
| 3923 |
| 3924 Node* CodeStubAssembler::IntPtrMax(Node* left, Node* right) { |
| 3925 return Select(IntPtrGreaterThanOrEqual(left, right), left, right); |
| 3926 } |
| 3927 |
3838 template <typename Dictionary> | 3928 template <typename Dictionary> |
3839 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary, | 3929 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary, |
3840 Node* unique_name, Label* if_found, | 3930 Node* unique_name, Label* if_found, |
3841 Variable* var_name_index, | 3931 Variable* var_name_index, |
3842 Label* if_not_found, | 3932 Label* if_not_found, |
3843 int inlined_probes) { | 3933 int inlined_probes) { |
3844 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); | 3934 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); |
3845 Comment("NameDictionaryLookup"); | 3935 Comment("NameDictionaryLookup"); |
3846 | 3936 |
3847 Node* capacity = SmiUntag(LoadFixedArrayElement( | 3937 Node* capacity = SmiUntag(LoadFixedArrayElement( |
(...skipping 4489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8337 Node* buffer_bit_field = LoadObjectField( | 8427 Node* buffer_bit_field = LoadObjectField( |
8338 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); | 8428 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); |
8339 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); | 8429 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); |
8340 | 8430 |
8341 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), | 8431 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), |
8342 Int32Constant(0)); | 8432 Int32Constant(0)); |
8343 } | 8433 } |
8344 | 8434 |
8345 } // namespace internal | 8435 } // namespace internal |
8346 } // namespace v8 | 8436 } // namespace v8 |
OLD | NEW |