Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/code-stub-assembler.cc

Issue 2430273007: [runtime] Object.create(null) creates a slow object (Closed)
Patch Set: addressing comments Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698