diff --git a/src/heap/heap.cc b/src/heap/heap.cc index 8161056681a..1a768fbc920 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -2342,6 +2342,7 @@ bool Heap::CreateInitialMaps() { ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, hash_table) ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, ordered_hash_table) + ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, unseeded_number_dictionary) ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, function_context) ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, catch_context) diff --git a/src/heap/heap.h b/src/heap/heap.h index 7f03d89abe4..1badd964393 100644 --- a/src/heap/heap.h +++ b/src/heap/heap.h @@ -46,6 +46,7 @@ using v8::MemoryPressureLevel; V(Map, fixed_array_map, FixedArrayMap) \ V(Map, fixed_cow_array_map, FixedCOWArrayMap) \ V(Map, hash_table_map, HashTableMap) \ + V(Map, unseeded_number_dictionary_map, UnseededNumberDictionaryMap) \ V(Map, symbol_map, SymbolMap) \ V(Map, one_byte_string_map, OneByteStringMap) \ V(Map, one_byte_internalized_string_map, OneByteInternalizedStringMap) \ diff --git a/src/objects-inl.h b/src/objects-inl.h index 5d59cd3e19e..b30e9626c5e 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -850,9 +850,8 @@ bool Object::IsSeededNumberDictionary() const { return IsDictionary(); } - -bool Object::IsUnseededNumberDictionary() const { - return IsDictionary(); +bool HeapObject::IsUnseededNumberDictionary() const { + return map() == GetHeap()->unseeded_number_dictionary_map(); } bool HeapObject::IsStringTable() const { return IsHashTable(); } @@ -3063,6 +3062,10 @@ void HashTableBase::SetNumberOfDeletedElements(int nod) { set(kNumberOfDeletedElementsIndex, Smi::FromInt(nod)); } +template +Map* BaseShape::GetMap(Isolate* isolate) { + return isolate->heap()->hash_table_map(); +} template int HashTable::FindEntry(Key key) { @@ -7473,14 +7476,16 @@ void BaseDictionaryShape::SetEntry(Dictionary* dict, int entry, Handle key, Handle value, PropertyDetails details) { - STATIC_ASSERT(Dictionary::kEntrySize == 3); + STATIC_ASSERT(Dictionary::kEntrySize == 2 || Dictionary::kEntrySize == 3); DCHECK(!key->IsName() || details.dictionary_index() > 0); int index = dict->EntryToIndex(entry); DisallowHeapAllocation no_gc; WriteBarrierMode mode = dict->GetWriteBarrierMode(no_gc); dict->set(index + Dictionary::kEntryKeyIndex, *key, mode); dict->set(index + Dictionary::kEntryValueIndex, *value, mode); - dict->set(index + Dictionary::kEntryDetailsIndex, details.AsSmi()); + if (Dictionary::kEntrySize == 3) { + dict->set(index + Dictionary::kEntryDetailsIndex, details.AsSmi()); + } } @@ -7517,6 +7522,9 @@ uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key, return ComputeIntegerHash(static_cast(other->Number()), 0); } +Map* UnseededNumberDictionaryShape::GetMap(Isolate* isolate) { + return *isolate->factory()->unseeded_number_dictionary_map(); +} uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) { return ComputeIntegerHash(key, seed); diff --git a/src/objects.cc b/src/objects.cc index 64655281009..8a97b2d7852 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -16189,7 +16189,7 @@ Handle HashTable::New( Factory* factory = isolate->factory(); int length = EntryToIndex(capacity); Handle array = factory->NewFixedArray(length, pretenure); - array->set_map_no_write_barrier(*factory->hash_table_map()); + array->set_map_no_write_barrier(Shape::GetMap(isolate)); Handle table = Handle::cast(array); table->SetNumberOfElements(0); diff --git a/src/objects.h b/src/objects.h index c52a17bef61..eb5fc790900 100644 --- a/src/objects.h +++ b/src/objects.h @@ -980,6 +980,7 @@ template inline bool Is(Object* obj); V(JSRegExp) \ V(HashTable) \ V(Dictionary) \ + V(UnseededNumberDictionary) \ V(StringTable) \ V(StringSet) \ V(NormalizedMapCache) \ @@ -1078,7 +1079,6 @@ class Object { INLINE(bool IsNameDictionary() const); INLINE(bool IsGlobalDictionary() const); INLINE(bool IsSeededNumberDictionary() const); - INLINE(bool IsUnseededNumberDictionary() const); INLINE(bool IsOrderedHashSet() const); INLINE(bool IsOrderedHashMap() const); @@ -3124,6 +3124,7 @@ class BaseShape { DCHECK(UsesSeed); return HashForObject(key, object); } + static inline Map* GetMap(Isolate* isolate); }; @@ -3646,7 +3647,6 @@ class NumberDictionaryShape : public BaseDictionaryShape { public: static inline bool IsMatch(uint32_t key, Object* other); static inline Handle AsHandle(Isolate* isolate, uint32_t key); - static const int kEntrySize = 3; static const bool kIsEnumerable = false; }; @@ -3655,6 +3655,7 @@ class SeededNumberDictionaryShape : public NumberDictionaryShape { public: static const bool UsesSeed = true; static const int kPrefixSize = 2; + static const int kEntrySize = 3; static inline uint32_t SeededHash(uint32_t key, uint32_t seed); static inline uint32_t SeededHashForObject(uint32_t key, @@ -3666,9 +3667,24 @@ class SeededNumberDictionaryShape : public NumberDictionaryShape { class UnseededNumberDictionaryShape : public NumberDictionaryShape { public: static const int kPrefixSize = 0; + static const int kEntrySize = 2; static inline uint32_t Hash(uint32_t key); static inline uint32_t HashForObject(uint32_t key, Object* object); + + template + static inline PropertyDetails DetailsAt(Dictionary* dict, int entry) { + UNREACHABLE(); + return PropertyDetails::Empty(); + } + + template + static inline void DetailsAtPut(Dictionary* dict, int entry, + PropertyDetails value) { + UNREACHABLE(); + } + + static inline Map* GetMap(Isolate* isolate); }; diff --git a/src/type-feedback-vector.cc b/src/type-feedback-vector.cc index bc2f1c288bc..661aa2feac4 100644 --- a/src/type-feedback-vector.cc +++ b/src/type-feedback-vector.cc @@ -39,20 +39,13 @@ FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind( String* TypeFeedbackMetadata::GetName(FeedbackVectorSlot slot) const { DCHECK(SlotRequiresName(GetKind(slot))); - FixedArray* names = FixedArray::cast(get(kNamesTableIndex)); - // TODO(ishell): consider using binary search here or even Dictionary when we - // have more ICs with names. - Smi* key = Smi::FromInt(slot.ToInt()); - for (int entry = 0; entry < names->length(); entry += kNameTableEntrySize) { - Object* current_key = names->get(entry + kNameTableSlotIndex); - if (current_key == key) { - Object* name = names->get(entry + kNameTableNameIndex); - DCHECK(name->IsString()); - return String::cast(name); - } - } - UNREACHABLE(); - return nullptr; + UnseededNumberDictionary* names = + UnseededNumberDictionary::cast(get(kNamesTableIndex)); + int entry = names->FindEntry(GetIsolate(), slot.ToInt()); + CHECK_NE(UnseededNumberDictionary::kNotFound, entry); + Object* name = names->ValueAt(entry); + DCHECK(name->IsString()); + return String::cast(name); } void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot slot, @@ -107,10 +100,9 @@ Handle TypeFeedbackMetadata::New(Isolate* isolate, // Add names to NamesTable. const int name_count = spec->name_count(); - Handle names = - name_count == 0 - ? factory->empty_fixed_array() - : factory->NewFixedArray(name_count * kNameTableEntrySize); + Handle names = + UnseededNumberDictionary::New(isolate, name_count); + int name_index = 0; for (int i = 0; i < slot_count; i++) { FeedbackVectorSlotKind kind = spec->GetKind(i); @@ -118,9 +110,7 @@ Handle TypeFeedbackMetadata::New(Isolate* isolate, if (SlotRequiresName(kind)) { Handle name = spec->GetName(name_index); DCHECK(!name.is_null()); - int entry = name_index * kNameTableEntrySize; - names->set(entry + kNameTableSlotIndex, Smi::FromInt(i)); - names->set(entry + kNameTableNameIndex, *name); + names = UnseededNumberDictionary::AtNumberPut(names, i, name); name_index++; } } diff --git a/src/type-info.cc b/src/type-info.cc index 5f5c1e87311..61af125c47c 100644 --- a/src/type-info.cc +++ b/src/type-info.cc @@ -20,7 +20,7 @@ TypeFeedbackOracle::TypeFeedbackOracle( Handle feedback_vector, Handle native_context) : native_context_(native_context), isolate_(isolate), zone_(zone) { BuildDictionary(code); - DCHECK(dictionary_->IsDictionary()); + DCHECK(dictionary_->IsUnseededNumberDictionary()); // We make a copy of the feedback vector because a GC could clear // the type feedback info contained therein. // TODO(mvstanton): revisit the decision to copy when we weakly