Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
[ic] Use UnseededNumberDictionary as a storage for names in TypeFeedb…
Browse files Browse the repository at this point in the history
…ackMetadata.

The serializer does not support serialization of HashTables in general because
after deserialization it might be necessary to rehash the table.
However the UnseededNumberDictionary does not require rehashing and this CL allows
them to be serialized.

This CL also changes the shape of UnseededNumberDictionary: the details field is
no longer part of the entry since no one needs it.

BUG=chromium:576312, chromium:623516

Review-Url: https://codereview.chromium.org/2102073002
Cr-Commit-Position: refs/heads/master@{#37336}
  • Loading branch information
isheludko authored and Commit bot committed Jun 28, 2016
1 parent 61c137c commit 7031861
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 30 deletions.
1 change: 1 addition & 0 deletions src/heap/heap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions src/heap/heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
18 changes: 13 additions & 5 deletions src/objects-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(); }
Expand Down Expand Up @@ -3063,6 +3062,10 @@ void HashTableBase::SetNumberOfDeletedElements(int nod) {
set(kNumberOfDeletedElementsIndex, Smi::FromInt(nod));
}

template <typename Key>
Map* BaseShape<Key>::GetMap(Isolate* isolate) {
return isolate->heap()->hash_table_map();
}

template <typename Derived, typename Shape, typename Key>
int HashTable<Derived, Shape, Key>::FindEntry(Key key) {
Expand Down Expand Up @@ -7473,14 +7476,16 @@ void BaseDictionaryShape<Key>::SetEntry(Dictionary* dict, int entry,
Handle<Object> key,
Handle<Object> 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());
}
}


Expand Down Expand Up @@ -7517,6 +7522,9 @@ uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
return ComputeIntegerHash(static_cast<uint32_t>(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);
Expand Down
2 changes: 1 addition & 1 deletion src/objects.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16189,7 +16189,7 @@ Handle<Derived> HashTable<Derived, Shape, Key>::New(
Factory* factory = isolate->factory();
int length = EntryToIndex(capacity);
Handle<FixedArray> 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<Derived> table = Handle<Derived>::cast(array);

table->SetNumberOfElements(0);
Expand Down
20 changes: 18 additions & 2 deletions src/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,7 @@ template <class C> inline bool Is(Object* obj);
V(JSRegExp) \
V(HashTable) \
V(Dictionary) \
V(UnseededNumberDictionary) \
V(StringTable) \
V(StringSet) \
V(NormalizedMapCache) \
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -3124,6 +3124,7 @@ class BaseShape {
DCHECK(UsesSeed);
return HashForObject(key, object);
}
static inline Map* GetMap(Isolate* isolate);
};


Expand Down Expand Up @@ -3646,7 +3647,6 @@ class NumberDictionaryShape : public BaseDictionaryShape<uint32_t> {
public:
static inline bool IsMatch(uint32_t key, Object* other);
static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
static const int kEntrySize = 3;
static const bool kIsEnumerable = false;
};

Expand All @@ -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,
Expand All @@ -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 <typename Dictionary>
static inline PropertyDetails DetailsAt(Dictionary* dict, int entry) {
UNREACHABLE();
return PropertyDetails::Empty();
}

template <typename Dictionary>
static inline void DetailsAtPut(Dictionary* dict, int entry,
PropertyDetails value) {
UNREACHABLE();
}

static inline Map* GetMap(Isolate* isolate);
};


Expand Down
32 changes: 11 additions & 21 deletions src/type-feedback-vector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -107,20 +100,17 @@ Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(Isolate* isolate,
// Add names to NamesTable.
const int name_count = spec->name_count();

Handle<FixedArray> names =
name_count == 0
? factory->empty_fixed_array()
: factory->NewFixedArray(name_count * kNameTableEntrySize);
Handle<UnseededNumberDictionary> names =
UnseededNumberDictionary::New(isolate, name_count);

int name_index = 0;
for (int i = 0; i < slot_count; i++) {
FeedbackVectorSlotKind kind = spec->GetKind(i);
metadata->SetKind(FeedbackVectorSlot(i), kind);
if (SlotRequiresName(kind)) {
Handle<String> 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++;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/type-info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ TypeFeedbackOracle::TypeFeedbackOracle(
Handle<TypeFeedbackVector> feedback_vector, Handle<Context> 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
Expand Down

0 comments on commit 7031861

Please sign in to comment.