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

Unified Diff: src/code-stub-assembler.cc

Issue 2430273007: [runtime] Object.create(null) creates a slow object (Closed)
Patch Set: addressing comments Created 4 years, 2 months 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 side-by-side diff with in-line comments
Download patch
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,

Powered by Google App Engine
This is Rietveld 408576698