[dictionaries] Use IsKey(Isolate* i, Object* o) everywhere

Using the isolate to check for IsUndefined and IsTheHole is roughly at least
20% faster in the worst-case and up to a factor 2x in the best case.

BUG=

Review-Url: https://codereview.chromium.org/2031533002
Cr-Commit-Position: refs/heads/master@{#36787}
This commit is contained in:
cbruni 2016-06-07 05:21:50 -07:00 committed by Commit bot
parent 3cfcc7e111
commit 764d4e6103
11 changed files with 111 additions and 122 deletions

View File

@ -2661,7 +2661,7 @@ void NativeWeakMap::Set(Local<Value> v8_key, Local<Value> v8_value) {
}
i::Handle<i::ObjectHashTable> table(
i::ObjectHashTable::cast(weak_collection->table()));
if (!table->IsKey(*key)) {
if (!table->IsKey(isolate, *key)) {
DCHECK(false);
return;
}
@ -2681,7 +2681,7 @@ Local<Value> NativeWeakMap::Get(Local<Value> v8_key) {
}
i::Handle<i::ObjectHashTable> table(
i::ObjectHashTable::cast(weak_collection->table()));
if (!table->IsKey(*key)) {
if (!table->IsKey(isolate, *key)) {
DCHECK(false);
return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
}
@ -2704,7 +2704,7 @@ bool NativeWeakMap::Has(Local<Value> v8_key) {
}
i::Handle<i::ObjectHashTable> table(
i::ObjectHashTable::cast(weak_collection->table()));
if (!table->IsKey(*key)) {
if (!table->IsKey(isolate, *key)) {
DCHECK(false);
return false;
}
@ -2725,7 +2725,7 @@ bool NativeWeakMap::Delete(Local<Value> v8_key) {
}
i::Handle<i::ObjectHashTable> table(
i::ObjectHashTable::cast(weak_collection->table()));
if (!table->IsKey(*key)) {
if (!table->IsKey(isolate, *key)) {
DCHECK(false);
return false;
}

View File

@ -3570,7 +3570,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
int capacity = properties->Capacity();
for (int i = 0; i < capacity; i++) {
Object* raw_key(properties->KeyAt(i));
if (properties->IsKey(raw_key)) {
if (properties->IsKey(isolate(), raw_key)) {
DCHECK(raw_key->IsName());
// If the property is already there we skip it.
Handle<Name> key(Name::cast(raw_key));
@ -3593,7 +3593,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
int capacity = properties->Capacity();
for (int i = 0; i < capacity; i++) {
Object* raw_key(properties->KeyAt(i));
if (properties->IsKey(raw_key)) {
if (properties->IsKey(isolate(), raw_key)) {
DCHECK(raw_key->IsName());
// If the property is already there we skip it.
Handle<Name> key(Name::cast(raw_key));

View File

@ -865,6 +865,7 @@ class ArrayConcatVisitor {
uint32_t EstimateElementCount(Handle<JSArray> array) {
DisallowHeapAllocation no_gc;
uint32_t length = static_cast<uint32_t>(array->length()->Number());
int element_count = 0;
switch (array->GetElementsKind()) {
@ -877,7 +878,7 @@ uint32_t EstimateElementCount(Handle<JSArray> array) {
DCHECK(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
int fast_length = static_cast<int>(length);
Isolate* isolate = array->GetIsolate();
Handle<FixedArray> elements(FixedArray::cast(array->elements()), isolate);
FixedArray* elements = FixedArray::cast(array->elements());
for (int i = 0; i < fast_length; i++) {
if (!elements->get(i)->IsTheHole(isolate)) element_count++;
}
@ -893,20 +894,20 @@ uint32_t EstimateElementCount(Handle<JSArray> array) {
DCHECK(FixedArray::cast(array->elements())->length() == 0);
break;
}
Handle<FixedDoubleArray> elements(
FixedDoubleArray::cast(array->elements()));
FixedDoubleArray* elements = FixedDoubleArray::cast(array->elements());
for (int i = 0; i < fast_length; i++) {
if (!elements->is_the_hole(i)) element_count++;
}
break;
}
case DICTIONARY_ELEMENTS: {
Handle<SeededNumberDictionary> dictionary(
SeededNumberDictionary::cast(array->elements()));
SeededNumberDictionary* dictionary =
SeededNumberDictionary::cast(array->elements());
Isolate* isolate = dictionary->GetIsolate();
int capacity = dictionary->Capacity();
for (int i = 0; i < capacity; i++) {
Handle<Object> key(dictionary->KeyAt(i), array->GetIsolate());
if (dictionary->IsKey(*key)) {
Object* key = dictionary->KeyAt(i);
if (dictionary->IsKey(isolate, key)) {
element_count++;
}
}
@ -983,13 +984,9 @@ void CollectElementIndices(Handle<JSObject> object, uint32_t range,
SeededNumberDictionary* dict =
SeededNumberDictionary::cast(object->elements());
uint32_t capacity = dict->Capacity();
Heap* heap = isolate->heap();
Object* undefined = heap->undefined_value();
Object* the_hole = heap->the_hole_value();
FOR_WITH_HANDLE_SCOPE(isolate, uint32_t, j = 0, j, j < capacity, j++, {
Object* k = dict->KeyAt(j);
if (k == undefined) continue;
if (k == the_hole) continue;
if (!dict->IsKey(isolate, k)) continue;
DCHECK(k->IsNumber());
uint32_t index = static_cast<uint32_t>(k->Number());
if (index < range) {

View File

@ -1186,12 +1186,10 @@ class DictionaryElementsAccessor
SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store);
if (!dict->requires_slow_elements()) return false;
int capacity = dict->Capacity();
Heap* heap = holder->GetHeap();
Object* undefined = heap->undefined_value();
Object* the_hole = heap->the_hole_value();
Isolate* isolate = dict->GetIsolate();
for (int i = 0; i < capacity; i++) {
Object* key = dict->KeyAt(i);
if (key == the_hole || key == undefined) continue;
if (!dict->IsKey(isolate, key)) continue;
DCHECK(!dict->IsDeleted(i));
PropertyDetails details = dict->DetailsAt(i);
if (details.type() == ACCESSOR_CONSTANT) return true;
@ -1301,23 +1299,12 @@ class DictionaryElementsAccessor
return static_cast<uint32_t>(raw_key->Number());
}
static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary,
static uint32_t GetKeyForEntryImpl(Isolate* isolate,
Handle<SeededNumberDictionary> dictionary,
int entry, PropertyFilter filter) {
DisallowHeapAllocation no_gc;
Object* raw_key = dictionary->KeyAt(entry);
if (!dictionary->IsKey(raw_key)) return kMaxUInt32;
return FilterKey(dictionary, entry, raw_key, filter);
}
static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary,
int entry, PropertyFilter filter,
Object* undefined, Object* the_hole) {
DisallowHeapAllocation no_gc;
Object* raw_key = dictionary->KeyAt(entry);
// Replace the IsKey check with a direct comparison which is much faster.
if (raw_key == undefined || raw_key == the_hole) {
return kMaxUInt32;
}
if (!dictionary->IsKey(isolate, raw_key)) return kMaxUInt32;
return FilterKey(dictionary, entry, raw_key, filter);
}
@ -1325,21 +1312,18 @@ class DictionaryElementsAccessor
Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) {
if (keys->filter() & SKIP_STRINGS) return;
Factory* factory = keys->isolate()->factory();
Handle<Object> undefined = factory->undefined_value();
Handle<Object> the_hole = factory->the_hole_value();
Isolate* isolate = keys->isolate();
Handle<SeededNumberDictionary> dictionary =
Handle<SeededNumberDictionary>::cast(backing_store);
int capacity = dictionary->Capacity();
Handle<FixedArray> elements =
factory->NewFixedArray(GetMaxNumberOfEntries(*object, *backing_store));
Handle<FixedArray> elements = isolate->factory()->NewFixedArray(
GetMaxNumberOfEntries(*object, *backing_store));
int insertion_index = 0;
PropertyFilter filter = keys->filter();
for (int i = 0; i < capacity; i++) {
uint32_t key =
GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole);
uint32_t key = GetKeyForEntryImpl(isolate, dictionary, i, filter);
if (key == kMaxUInt32) continue;
Handle<Object> key_handle = factory->NewNumberFromUint(key);
Handle<Object> key_handle = isolate->factory()->NewNumberFromUint(key);
elements->set(insertion_index, *key_handle);
insertion_index++;
}
@ -1357,14 +1341,11 @@ class DictionaryElementsAccessor
if (filter & SKIP_STRINGS) return list;
if (filter & ONLY_ALL_CAN_READ) return list;
Handle<Object> undefined = isolate->factory()->undefined_value();
Handle<Object> the_hole = isolate->factory()->the_hole_value();
Handle<SeededNumberDictionary> dictionary =
Handle<SeededNumberDictionary>::cast(backing_store);
uint32_t capacity = dictionary->Capacity();
for (uint32_t i = 0; i < capacity; i++) {
uint32_t key =
GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole);
uint32_t key = GetKeyForEntryImpl(isolate, dictionary, i, filter);
if (key == kMaxUInt32) continue;
Handle<Object> index = isolate->factory()->NewNumberFromUint(key);
list->set(insertion_index, *index);

View File

@ -473,9 +473,10 @@ static void PatchIncrementalMarkingRecordWriteStubs(
UnseededNumberDictionary* stubs = heap->code_stubs();
int capacity = stubs->Capacity();
Isolate* isolate = heap->isolate();
for (int i = 0; i < capacity; i++) {
Object* k = stubs->KeyAt(i);
if (stubs->IsKey(k)) {
if (stubs->IsKey(isolate, k)) {
uint32_t key = NumberToUint32(k);
if (CodeStub::MajorKeyFromKey(key) == CodeStub::RecordWrite) {

View File

@ -2464,7 +2464,7 @@ void MarkCompactCollector::MarkDependentCodeForDeoptimization(
for (uint32_t i = 0; i < capacity; i++) {
uint32_t key_index = table->EntryToIndex(i);
Object* key = table->get(key_index);
if (!table->IsKey(key)) continue;
if (!table->IsKey(isolate, key)) continue;
uint32_t value_index = table->EntryToValueIndex(i);
Object* value = table->get(value_index);
DCHECK(key->IsWeakCell());

View File

@ -3052,7 +3052,8 @@ int HashTableBase::ComputeCapacity(int at_least_space_for) {
return Max(capacity, kMinCapacity);
}
bool HashTableBase::IsKey(Heap* heap, Object* k) {
bool HashTableBase::IsKey(Isolate* isolate, Object* k) {
Heap* heap = isolate->heap();
return k != heap->the_hole_value() && k != heap->undefined_value();
}

View File

@ -1520,10 +1520,10 @@ Map* Object::GetRootMap(Isolate* isolate) {
Object* Object::GetHash() {
DisallowHeapAllocation no_gc;
Object* hash = GetSimpleHash();
if (hash->IsSmi()) return hash;
DisallowHeapAllocation no_gc;
DCHECK(IsJSReceiver());
JSReceiver* receiver = JSReceiver::cast(this);
Isolate* isolate = receiver->GetIsolate();
@ -5701,7 +5701,7 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
// Compute the length of the instance descriptor.
for (int i = 0; i < instance_descriptor_length; i++) {
int index = Smi::cast(iteration_order->get(i))->value();
DCHECK(dictionary->IsKey(dictionary->KeyAt(index)));
DCHECK(dictionary->IsKey(isolate, dictionary->KeyAt(index)));
Object* value = dictionary->ValueAt(index);
PropertyType type = dictionary->DetailsAt(index).type();
@ -7636,9 +7636,10 @@ template <typename Dictionary>
static void ApplyAttributesToDictionary(Dictionary* dictionary,
const PropertyAttributes attributes) {
int capacity = dictionary->Capacity();
Isolate* isolate = dictionary->GetIsolate();
for (int i = 0; i < capacity; i++) {
Object* k = dictionary->KeyAt(i);
if (dictionary->IsKey(k) &&
if (dictionary->IsKey(isolate, k) &&
!(k->IsSymbol() && Symbol::cast(k)->is_private())) {
PropertyDetails details = dictionary->DetailsAt(i);
int attrs = attributes;
@ -7965,7 +7966,7 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
int capacity = element_dictionary->Capacity();
for (int i = 0; i < capacity; i++) {
Object* k = element_dictionary->KeyAt(i);
if (element_dictionary->IsKey(k)) {
if (element_dictionary->IsKey(isolate, k)) {
Handle<Object> value(element_dictionary->ValueAt(i), isolate);
if (value->IsJSObject()) {
Handle<JSObject> result;
@ -15373,10 +15374,11 @@ int JSObject::GetFastElementsUsage() {
#ifdef OBJECT_PRINT
template <typename Derived, typename Shape, typename Key>
void Dictionary<Derived, Shape, Key>::Print(std::ostream& os) { // NOLINT
Isolate* isolate = this->GetIsolate();
int capacity = this->Capacity();
for (int i = 0; i < capacity; i++) {
Object* k = this->KeyAt(i);
if (this->IsKey(k)) {
if (this->IsKey(isolate, k)) {
os << "\n ";
if (k->IsString()) {
String::cast(k)->StringPrint(os);
@ -15397,13 +15399,14 @@ void Dictionary<Derived, Shape, Key>::Print() {
template<typename Derived, typename Shape, typename Key>
void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) {
Isolate* isolate = this->GetIsolate();
int pos = 0;
int capacity = this->Capacity();
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
for (int i = 0; i < capacity; i++) {
Object* k = this->KeyAt(i);
if (this->IsKey(k)) {
if (this->IsKey(isolate, k)) {
elements->set(pos++, this->ValueAt(i), mode);
}
}
@ -16208,6 +16211,7 @@ template<typename Derived, typename Shape, typename Key>
void HashTable<Derived, Shape, Key>::Rehash(Key key) {
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = GetWriteBarrierMode(no_gc);
Isolate* isolate = GetIsolate();
uint32_t capacity = Capacity();
bool done = false;
for (int probe = 1; !done; probe++) {
@ -16216,7 +16220,7 @@ void HashTable<Derived, Shape, Key>::Rehash(Key key) {
done = true;
for (uint32_t current = 0; current < capacity; current++) {
Object* current_key = get(EntryToIndex(current));
if (IsKey(current_key)) {
if (IsKey(isolate, current_key)) {
uint32_t target = EntryForProbe(key, current_key, probe, current);
if (current == target) continue;
Object* target_key = get(EntryToIndex(target));
@ -16235,9 +16239,8 @@ void HashTable<Derived, Shape, Key>::Rehash(Key key) {
}
}
// Wipe deleted entries.
Heap* heap = GetHeap();
Object* the_hole = heap->the_hole_value();
Object* undefined = heap->undefined_value();
Object* the_hole = isolate->heap()->the_hole_value();
Object* undefined = isolate->heap()->undefined_value();
for (uint32_t current = 0; current < capacity; current++) {
if (get(EntryToIndex(current)) == the_hole) {
set(EntryToIndex(current), undefined);
@ -16328,12 +16331,10 @@ uint32_t HashTable<Derived, Shape, Key>::FindInsertionEntry(uint32_t hash) {
uint32_t entry = FirstProbe(hash, capacity);
uint32_t count = 1;
// EnsureCapacity will guarantee the hash table is never full.
Heap* heap = GetHeap();
Object* the_hole = heap->the_hole_value();
Object* undefined = heap->undefined_value();
Isolate* isolate = GetIsolate();
while (true) {
Object* element = KeyAt(entry);
if (element == the_hole || element == undefined) break;
if (!IsKey(isolate, element)) break;
entry = NextProbe(entry, count++, capacity);
}
return entry;
@ -16525,7 +16526,7 @@ Handle<Object> JSObject::PrepareSlowElementsForSort(
DisallowHeapAllocation no_gc;
for (int i = 0; i < capacity; i++) {
Object* k = dict->KeyAt(i);
if (!dict->IsKey(k)) continue;
if (!dict->IsKey(isolate, k)) continue;
DCHECK(k->IsNumber());
DCHECK(!k->IsSmi() || Smi::cast(k)->value() >= 0);
@ -17164,7 +17165,8 @@ Handle<Derived> Dictionary<Derived, Shape, Key>::New(
template <typename Derived, typename Shape, typename Key>
Handle<FixedArray> Dictionary<Derived, Shape, Key>::BuildIterationIndicesArray(
Handle<Derived> dictionary) {
Factory* factory = dictionary->GetIsolate()->factory();
Isolate* isolate = dictionary->GetIsolate();
Factory* factory = isolate->factory();
int length = dictionary->NumberOfElements();
Handle<FixedArray> iteration_order = factory->NewFixedArray(length);
@ -17175,7 +17177,7 @@ Handle<FixedArray> Dictionary<Derived, Shape, Key>::BuildIterationIndicesArray(
int capacity = dictionary->Capacity();
int pos = 0;
for (int i = 0; i < capacity; i++) {
if (dictionary->IsKey(dictionary->KeyAt(i))) {
if (dictionary->IsKey(isolate, dictionary->KeyAt(i))) {
int index = dictionary->DetailsAt(i).dictionary_index();
iteration_order->set(pos, Smi::FromInt(i));
enumeration_order->set(pos, Smi::FromInt(index));
@ -17322,17 +17324,17 @@ void Dictionary<Derived, Shape, Key>::AddEntry(
bool SeededNumberDictionary::HasComplexElements() {
if (!requires_slow_elements()) return false;
Isolate* isolate = this->GetIsolate();
int capacity = this->Capacity();
for (int i = 0; i < capacity; i++) {
Object* k = this->KeyAt(i);
if (this->IsKey(k)) {
if (!this->IsKey(isolate, k)) continue;
DCHECK(!IsDeleted(i));
PropertyDetails details = this->DetailsAt(i);
if (details.type() == ACCESSOR_CONSTANT) return true;
PropertyAttributes attr = details.attributes();
if (attr & ALL_ATTRIBUTES_MASK) return true;
}
}
return false;
}
@ -17427,11 +17429,12 @@ Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set(
template <typename Derived, typename Shape, typename Key>
int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes(
PropertyFilter filter) {
Isolate* isolate = this->GetIsolate();
int capacity = this->Capacity();
int result = 0;
for (int i = 0; i < capacity; i++) {
Object* k = this->KeyAt(i);
if (this->IsKey(k) && !k->FilterKey(filter)) {
if (this->IsKey(isolate, k) && !k->FilterKey(filter)) {
if (this->IsDeleted(i)) continue;
PropertyDetails details = this->DetailsAt(i);
PropertyAttributes attr = details.attributes();
@ -17456,12 +17459,13 @@ struct EnumIndexComparator {
template <typename Derived, typename Shape, typename Key>
void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo(FixedArray* storage) {
Isolate* isolate = this->GetIsolate();
int length = storage->length();
int capacity = this->Capacity();
int properties = 0;
for (int i = 0; i < capacity; i++) {
Object* k = this->KeyAt(i);
if (this->IsKey(k) && !k->IsSymbol()) {
if (this->IsKey(isolate, k) && !k->IsSymbol()) {
PropertyDetails details = this->DetailsAt(i);
if (details.IsDontEnum() || this->IsDeleted(i)) continue;
storage->set(properties, Smi::FromInt(i));
@ -17483,9 +17487,10 @@ template <typename Derived, typename Shape, typename Key>
void Dictionary<Derived, Shape, Key>::CollectKeysTo(
Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys,
PropertyFilter filter) {
Isolate* isolate = keys->isolate();
int capacity = dictionary->Capacity();
Handle<FixedArray> array =
keys->isolate()->factory()->NewFixedArray(dictionary->NumberOfElements());
isolate->factory()->NewFixedArray(dictionary->NumberOfElements());
int array_size = 0;
{
@ -17493,7 +17498,7 @@ void Dictionary<Derived, Shape, Key>::CollectKeysTo(
Dictionary<Derived, Shape, Key>* raw_dict = *dictionary;
for (int i = 0; i < capacity; i++) {
Object* k = raw_dict->KeyAt(i);
if (!raw_dict->IsKey(k) || k->FilterKey(filter)) continue;
if (!raw_dict->IsKey(isolate, k) || k->FilterKey(filter)) continue;
if (raw_dict->IsDeleted(i)) continue;
PropertyDetails details = raw_dict->DetailsAt(i);
if ((details.attributes() & filter) != 0) continue;
@ -17538,10 +17543,11 @@ void Dictionary<Derived, Shape, Key>::CollectKeysTo(
// Backwards lookup (slow).
template<typename Derived, typename Shape, typename Key>
Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) {
Isolate* isolate = this->GetIsolate();
int capacity = this->Capacity();
for (int i = 0; i < capacity; i++) {
Object* k = this->KeyAt(i);
if (this->IsKey(k)) {
if (!this->IsKey(isolate, k)) continue;
Object* e = this->ValueAt(i);
// TODO(dcarney): this should be templatized.
if (e->IsPropertyCell()) {
@ -17549,16 +17555,14 @@ Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) {
}
if (e == value) return k;
}
}
Heap* heap = Dictionary::GetHeap();
return heap->undefined_value();
return isolate->heap()->undefined_value();
}
Object* ObjectHashTable::Lookup(Isolate* isolate, Handle<Object> key,
int32_t hash) {
DisallowHeapAllocation no_gc;
DCHECK(IsKey(*key));
DCHECK(IsKey(isolate, *key));
int entry = FindEntry(isolate, key, hash);
if (entry == kNotFound) return isolate->heap()->the_hole_value();
@ -17568,9 +17572,9 @@ Object* ObjectHashTable::Lookup(Isolate* isolate, Handle<Object> key,
Object* ObjectHashTable::Lookup(Handle<Object> key) {
DisallowHeapAllocation no_gc;
DCHECK(IsKey(*key));
Isolate* isolate = GetIsolate();
DCHECK(IsKey(isolate, *key));
// If the object does not have an identity hash, it was never used as a key.
Object* hash = key->GetHash();
@ -17590,8 +17594,7 @@ Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
Handle<Object> key,
Handle<Object> value) {
Isolate* isolate = table->GetIsolate();
DCHECK(table->IsKey(*key));
DCHECK(table->IsKey(isolate, *key));
DCHECK(!value->IsTheHole(isolate));
// Make sure the key object has an identity hash code.
@ -17606,8 +17609,7 @@ Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
Handle<Object> value,
int32_t hash) {
Isolate* isolate = table->GetIsolate();
DCHECK(table->IsKey(*key));
DCHECK(table->IsKey(isolate, *key));
DCHECK(!value->IsTheHole(isolate));
int entry = table->FindEntry(isolate, key, hash);
@ -17634,7 +17636,7 @@ Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table,
Handle<Object> key,
bool* was_present) {
DCHECK(table->IsKey(*key));
DCHECK(table->IsKey(table->GetIsolate(), *key));
Object* hash = key->GetHash();
if (hash->IsUndefined(table->GetIsolate())) {
@ -17650,9 +17652,10 @@ Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table,
Handle<Object> key,
bool* was_present,
int32_t hash) {
DCHECK(table->IsKey(*key));
Isolate* isolate = table->GetIsolate();
DCHECK(table->IsKey(isolate, *key));
int entry = table->FindEntry(table->GetIsolate(), key, hash);
int entry = table->FindEntry(isolate, key, hash);
if (entry == kNotFound) {
*was_present = false;
return table;
@ -17680,9 +17683,10 @@ void ObjectHashTable::RemoveEntry(int entry) {
Object* WeakHashTable::Lookup(Handle<HeapObject> key) {
DisallowHeapAllocation no_gc;
DCHECK(IsKey(*key));
Isolate* isolate = GetIsolate();
DCHECK(IsKey(isolate, *key));
int entry = FindEntry(key);
if (entry == kNotFound) return GetHeap()->the_hole_value();
if (entry == kNotFound) return isolate->heap()->the_hole_value();
return get(EntryToValueIndex(entry));
}
@ -17690,7 +17694,8 @@ Object* WeakHashTable::Lookup(Handle<HeapObject> key) {
Handle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table,
Handle<HeapObject> key,
Handle<HeapObject> value) {
DCHECK(table->IsKey(*key));
Isolate* isolate = key->GetIsolate();
DCHECK(table->IsKey(isolate, *key));
int entry = table->FindEntry(key);
// Key is already in table, just overwrite value.
if (entry != kNotFound) {
@ -17698,7 +17703,7 @@ Handle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table,
return table;
}
Handle<WeakCell> key_cell = key->GetIsolate()->factory()->NewWeakCell(key);
Handle<WeakCell> key_cell = isolate->factory()->NewWeakCell(key);
// Check whether the hash table should be extended.
table = EnsureCapacity(table, 1, key, TENURED);
@ -17792,11 +17797,14 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Clear(
template <class Derived, class Iterator, int entrysize>
bool OrderedHashTable<Derived, Iterator, entrysize>::HasKey(
Handle<Derived> table, Handle<Object> key) {
int entry = table->KeyToFirstEntry(*key);
DisallowHeapAllocation no_gc;
Isolate* isolate = table->GetIsolate();
Object* raw_key = *key;
int entry = table->KeyToFirstEntry(isolate, raw_key);
// Walk the chain in the bucket to find the key.
while (entry != kNotFound) {
Object* candidate_key = table->KeyAt(entry);
if (candidate_key->SameValueZero(*key)) return true;
if (candidate_key->SameValueZero(raw_key)) return true;
entry = table->NextChainEntry(entry);
}
return false;
@ -17856,11 +17864,11 @@ template<class Derived, class Iterator, int entrysize>
Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash(
Handle<Derived> table, int new_capacity) {
Isolate* isolate = table->GetIsolate();
Heap* heap = isolate->heap();
DCHECK(!table->IsObsolete());
Handle<Derived> new_table = Allocate(
isolate, new_capacity, heap->InNewSpace(*table) ? NOT_TENURED : TENURED);
Handle<Derived> new_table =
Allocate(isolate, new_capacity,
isolate->heap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
int nof = table->NumberOfElements();
int nod = table->NumberOfDeletedElements();
int new_buckets = new_table->NumberOfBuckets();
@ -17868,10 +17876,9 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash(
int removed_holes_index = 0;
DisallowHeapAllocation no_gc;
Object* the_hole = heap->the_hole_value();
for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) {
Object* key = table->KeyAt(old_entry);
if (key == the_hole) {
if (key->IsTheHole(isolate)) {
table->SetRemovedIndexAt(removed_holes_index++, old_entry);
continue;
}

View File

@ -3154,7 +3154,7 @@ class HashTableBase : public FixedArray {
// Tells whether k is a real key. The hole and undefined are not allowed
// as keys and can be used to indicate missing or deleted elements.
inline bool IsKey(Object* k);
inline bool IsKey(Heap* heap, Object* k);
inline bool IsKey(Isolate* isolate, Object* k);
// Compute the probe offset (quadratic probing).
INLINE(static uint32_t GetProbeOffset(uint32_t n)) {
@ -3879,10 +3879,10 @@ class OrderedHashTable: public FixedArray {
return Smi::cast(entry)->value();
}
int KeyToFirstEntry(Object* key) {
int KeyToFirstEntry(Isolate* isolate, Object* key) {
Object* hash = key->GetHash();
// If the object does not have an identity hash, it was never used as a key
if (hash->IsUndefined(GetIsolate())) return kNotFound;
if (hash->IsUndefined(isolate)) return kNotFound;
return HashToEntry(Smi::cast(hash)->value());
}

View File

@ -1558,6 +1558,7 @@ void V8HeapExplorer::ExtractFixedArrayReferences(int entry, FixedArray* array) {
void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
Isolate* isolate = js_obj->GetIsolate();
if (js_obj->HasFastProperties()) {
DescriptorArray* descs = js_obj->map()->instance_descriptors();
int real_size = js_obj->map()->NumberOfOwnDescriptors();
@ -1591,7 +1592,7 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
int length = dictionary->Capacity();
for (int i = 0; i < length; ++i) {
Object* k = dictionary->KeyAt(i);
if (dictionary->IsKey(k)) {
if (dictionary->IsKey(isolate, k)) {
DCHECK(dictionary->ValueAt(i)->IsPropertyCell());
PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(i));
Object* value = cell->value();
@ -1605,7 +1606,7 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
int length = dictionary->Capacity();
for (int i = 0; i < length; ++i) {
Object* k = dictionary->KeyAt(i);
if (dictionary->IsKey(k)) {
if (dictionary->IsKey(isolate, k)) {
Object* value = dictionary->ValueAt(i);
PropertyDetails details = dictionary->DetailsAt(i);
SetDataOrAccessorPropertyReference(details.kind(), js_obj, entry,
@ -1635,13 +1636,14 @@ void V8HeapExplorer::ExtractAccessorPairProperty(JSObject* js_obj, int entry,
void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj, int entry) {
Isolate* isolate = js_obj->GetIsolate();
if (js_obj->HasFastObjectElements()) {
FixedArray* elements = FixedArray::cast(js_obj->elements());
int length = js_obj->IsJSArray() ?
Smi::cast(JSArray::cast(js_obj)->length())->value() :
elements->length();
for (int i = 0; i < length; ++i) {
if (!elements->get(i)->IsTheHole(heap_->isolate())) {
if (!elements->get(i)->IsTheHole(isolate)) {
SetElementReference(js_obj, entry, i, elements->get(i));
}
}
@ -1650,7 +1652,7 @@ void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj, int entry) {
int length = dictionary->Capacity();
for (int i = 0; i < length; ++i) {
Object* k = dictionary->KeyAt(i);
if (dictionary->IsKey(heap_, k)) {
if (dictionary->IsKey(isolate, k)) {
DCHECK(k->IsNumber());
uint32_t index = static_cast<uint32_t>(k->Number());
SetElementReference(js_obj, entry, index, dictionary->ValueAt(i));

View File

@ -250,7 +250,7 @@ RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) {
int count = 0;
for (int i = 0; count / 2 < max_entries && i < table->Capacity(); i++) {
Handle<Object> key(table->KeyAt(i), isolate);
if (table->IsKey(*key)) {
if (table->IsKey(isolate, *key)) {
entries->set(count++, *key);
Object* value = table->Lookup(key);
entries->set(count++, value);
@ -289,7 +289,7 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionGet) {
RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
Handle<ObjectHashTable> table(
ObjectHashTable::cast(weak_collection->table()));
RUNTIME_ASSERT(table->IsKey(*key));
RUNTIME_ASSERT(table->IsKey(isolate, *key));
Handle<Object> lookup(table->Lookup(key, hash), isolate);
return lookup->IsTheHole(isolate) ? isolate->heap()->undefined_value()
: *lookup;
@ -305,7 +305,7 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionHas) {
RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
Handle<ObjectHashTable> table(
ObjectHashTable::cast(weak_collection->table()));
RUNTIME_ASSERT(table->IsKey(*key));
RUNTIME_ASSERT(table->IsKey(isolate, *key));
Handle<Object> lookup(table->Lookup(key, hash), isolate);
return isolate->heap()->ToBoolean(!lookup->IsTheHole(isolate));
}
@ -320,7 +320,7 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
Handle<ObjectHashTable> table(
ObjectHashTable::cast(weak_collection->table()));
RUNTIME_ASSERT(table->IsKey(*key));
RUNTIME_ASSERT(table->IsKey(isolate, *key));
bool was_present = JSWeakCollection::Delete(weak_collection, key, hash);
return isolate->heap()->ToBoolean(was_present);
}
@ -336,7 +336,7 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
CONVERT_SMI_ARG_CHECKED(hash, 3)
Handle<ObjectHashTable> table(
ObjectHashTable::cast(weak_collection->table()));
RUNTIME_ASSERT(table->IsKey(*key));
RUNTIME_ASSERT(table->IsKey(isolate, *key));
JSWeakCollection::Set(weak_collection, key, value, hash);
return *weak_collection;
}
@ -362,8 +362,8 @@ RUNTIME_FUNCTION(Runtime_GetWeakSetValues) {
DisallowHeapAllocation no_gc;
int count = 0;
for (int i = 0; count < max_values && i < table->Capacity(); i++) {
Handle<Object> key(table->KeyAt(i), isolate);
if (table->IsKey(*key)) values->set(count++, *key);
Object* key = table->KeyAt(i);
if (table->IsKey(isolate, key)) values->set(count++, key);
}
DCHECK_EQ(max_values, count);
}