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, |