Chromium Code Reviews| Index: src/code-stub-assembler.cc |
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
| index bc6477b005d77736f2536643d154504f8e2cca11..3a9ef95c6dfccfac3012e901153a36b428400829 100644 |
| --- a/src/code-stub-assembler.cc |
| +++ b/src/code-stub-assembler.cc |
| @@ -127,6 +127,23 @@ Node* CodeStubAssembler::IntPtrSubFoldConstants(Node* left, Node* right) { |
| return IntPtrSub(left, right); |
| } |
| +Node* CodeStubAssembler::IntPtrRoundUpToPowerOfTwo32(Node* value) { |
| + CSA_ASSERT(UintPtrLessThanOrEqual(value, IntPtrConstant(0x80000000u))); |
| + 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.
|
| + 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.
|
| + value = WordOr(value, WordShr(value, IntPtrConstant(i))); |
| + } |
| + return IntPtrAdd(value, IntPtrConstant(1)); |
| +} |
| + |
| +Node* CodeStubAssembler::WordIsPowerOfTwo(Node* value) { |
| + // value && !(value & (value - 1)) |
| + return WordEqual( |
| + Select(WordEqual(value, IntPtrConstant(0)), IntPtrConstant(1), |
| + 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.
|
| + IntPtrConstant(0)); |
| +} |
| + |
| Node* CodeStubAssembler::Float64Round(Node* x) { |
| Node* one = Float64Constant(1.0); |
| Node* one_half = Float64Constant(0.5); |
| @@ -1106,6 +1123,12 @@ Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) { |
| Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)); |
| } |
| +Node* CodeStubAssembler::IsDictionaryMap(Node* map) { |
| + Node* bit_field3 = LoadMapBitField3(map); |
| + 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.
|
| + Int32Constant(0)); |
| +} |
| + |
| Node* CodeStubAssembler::LoadNameHashField(Node* name) { |
| return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); |
| } |
| @@ -1660,6 +1683,55 @@ Node* CodeStubAssembler::AllocateRegExpResult(Node* context, Node* length, |
| return result; |
| } |
| +Node* CodeStubAssembler::AllocateNameDictionary(int at_least_space_for) { |
| + return AllocateNameDictionary(IntPtrConstant(at_least_space_for)); |
| +} |
| + |
| +Node* CodeStubAssembler::AllocateNameDictionary(Node* at_least_space_for) { |
| + CSA_ASSERT(UintPtrLessThanOrEqual( |
| + at_least_space_for, IntPtrConstant(NameDictionary::kMaxCapacity))); |
| + |
| + Node* capacity = HashTableComputeCapacity(at_least_space_for); |
| + CSA_ASSERT(WordIsPowerOfTwo(capacity)); |
| + |
| + Node* length = EntryToIndex<NameDictionary>(capacity); |
| + Node* store_size = |
| + IntPtrAddFoldConstants(WordShl(length, IntPtrConstant(kPointerSizeLog2)), |
| + IntPtrConstant(NameDictionary::kHeaderSize)); |
| + |
| + Node* result = Allocate(store_size); |
| + // Initialize FixedArray fields. |
| + 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.
|
| + Heap::kHashTableMapRootIndex); |
| + StoreObjectFieldNoWriteBarrier(result, FixedArray::kLengthOffset, |
| + SmiFromWord(length)); |
| + // Initialized HashTable fields. |
| + Node* zero = SmiConstant(0); |
| + StoreFixedArrayElement(result, NameDictionary::kNumberOfElementsIndex, zero, |
| + SKIP_WRITE_BARRIER); |
| + StoreFixedArrayElement(result, NameDictionary::kNumberOfDeletedElementsIndex, |
| + zero, SKIP_WRITE_BARRIER); |
| + StoreFixedArrayElement(result, NameDictionary::kCapacityIndex, |
| + SmiTag(capacity), SKIP_WRITE_BARRIER); |
| + // Initialize Dictionary fields. |
| + Node* filler = LoadRoot(Heap::kUndefinedValueRootIndex); |
| + StoreFixedArrayElement(result, NameDictionary::kMaxNumberKeyIndex, filler, |
| + SKIP_WRITE_BARRIER); |
| + StoreFixedArrayElement(result, NameDictionary::kNextEnumerationIndexIndex, |
| + SmiConstant(PropertyDetails::kInitialIndex), |
| + SKIP_WRITE_BARRIER); |
| + |
| + // Initialize NameDictionary elements. |
| + Node* start_address = IntPtrAdd( |
| + result, |
| + 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 :)
|
| + Node* end_address = IntPtrAdd( |
| + result, |
| + IntPtrSubFoldConstants(store_size, IntPtrConstant(kHeapObjectTag))); |
| + StoreFieldsNoWriteBarrier(start_address, end_address, filler); |
| + return result; |
| +} |
| + |
| Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties, |
| Node* elements) { |
| Node* size = |
| @@ -1677,6 +1749,7 @@ void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map, |
| // This helper assumes that the object is in new-space, as guarded by the |
| // check in AllocatedJSObjectFromMap. |
| if (properties == nullptr) { |
| + CSA_ASSERT(Word32BinaryNot(IsDictionaryMap((map)))); |
| StoreObjectFieldRoot(object, JSObject::kPropertiesOffset, |
| Heap::kEmptyFixedArrayRootIndex); |
| } else { |
| @@ -3825,6 +3898,19 @@ Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { |
| field_index)); |
| } |
| +template Node* CodeStubAssembler::EntryToIndex<NameDictionary>(Node*, int); |
| +template Node* CodeStubAssembler::EntryToIndex<GlobalDictionary>(Node*, int); |
| + |
| +Node* CodeStubAssembler::HashTableComputeCapacity(Node* at_least_space_for) { |
| + Node* capacity = IntPtrRoundUpToPowerOfTwo32( |
| + WordShl(at_least_space_for, IntPtrConstant(1))); |
| + return IntPtrMax(capacity, IntPtrConstant(HashTableBase::kMinCapacity)); |
| +} |
| + |
| +Node* CodeStubAssembler::IntPtrMax(Node* left, Node* right) { |
| + return Select(IntPtrGreaterThanOrEqual(left, right), left, right); |
| +} |
| + |
| template <typename Dictionary> |
| void CodeStubAssembler::NameDictionaryLookup(Node* dictionary, |
| Node* unique_name, Label* if_found, |