| Index: src/code-stub-assembler.cc
|
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
|
| index 99097ca92ff8553ff1f68665b5d2f4cb248cc488..c64a01c5f1be65a9c69b7958be9d6694d88aeff4 100644
|
| --- a/src/code-stub-assembler.cc
|
| +++ b/src/code-stub-assembler.cc
|
| @@ -127,6 +127,24 @@ Node* CodeStubAssembler::IntPtrSubFoldConstants(Node* left, Node* right) {
|
| return IntPtrSub(left, right);
|
| }
|
|
|
| +Node* CodeStubAssembler::IntPtrRoundUpToPowerOfTwo32(Node* value) {
|
| + Comment("IntPtrRoundUpToPowerOfTwo32");
|
| + CSA_ASSERT(UintPtrLessThanOrEqual(value, IntPtrConstant(0x80000000u)));
|
| + value = IntPtrSub(value, IntPtrConstant(1));
|
| + for (int i = 1; i <= 16; i *= 2) {
|
| + 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, IntPtrSub(value, IntPtrConstant(1)))),
|
| + IntPtrConstant(0));
|
| +}
|
| +
|
| Node* CodeStubAssembler::Float64Round(Node* x) {
|
| Node* one = Float64Constant(1.0);
|
| Node* one_half = Float64Constant(0.5);
|
| @@ -775,6 +793,7 @@ Node* CodeStubAssembler::AllocateRawAligned(Node* size_in_bytes,
|
| }
|
|
|
| Node* CodeStubAssembler::Allocate(Node* size_in_bytes, AllocationFlags flags) {
|
| + Comment("Allocate");
|
| bool const new_space = !(flags & kPretenured);
|
| Node* top_address = ExternalConstant(
|
| new_space
|
| @@ -1105,6 +1124,12 @@ Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) {
|
| Int32Constant(LAST_SPECIAL_RECEIVER_TYPE));
|
| }
|
|
|
| +Node* CodeStubAssembler::IsDictionaryMap(Node* map) {
|
| + Node* bit_field3 = LoadMapBitField3(map);
|
| + return Word32NotEqual(IsSetWord32<Map::DictionaryMap>(bit_field3),
|
| + Int32Constant(0));
|
| +}
|
| +
|
| Node* CodeStubAssembler::LoadNameHashField(Node* name) {
|
| return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32());
|
| }
|
| @@ -1659,6 +1684,57 @@ 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);
|
| + Comment("Initialize NameDictionary");
|
| + // Initialize FixedArray fields.
|
| + StoreObjectFieldRoot(result, FixedArray::kMapOffset,
|
| + 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::OffsetOfElementAt(
|
| + NameDictionary::kElementsStartIndex) -
|
| + kHeapObjectTag));
|
| + 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 =
|
| @@ -1676,6 +1752,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 {
|
| @@ -3835,6 +3912,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,
|
|
|