Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index 7616c9f62c7ad16e5f95380221b2d6bb0a450fcf..7b6fcb5a83bdafeb8c85aeca8417318b14ba2f52 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -723,6 +723,43 @@ Object* Object::GetPrototype() { |
| } |
| +uint32_t Object::GetHash() { |
| + // The object is either a number, a string, an odd-ball, |
| + // a real JS object, or a Harmony proxy. |
| + if (IsNumber()) return ComputeLongHash(double_to_uint64(Number())); |
| + if (IsString()) return String::cast(this)->Hash(); |
| + if (IsOddball()) return Oddball::cast(this)->to_string()->Hash(); |
| + if (IsJSReceiver()) { |
| + MaybeObject* maybe_hash = |
| + JSReceiver::cast(this)->GetIdentityHash(OMIT_CREATION); |
| + ASSERT(!maybe_hash->IsFailure()); |
| + return Smi::cast(maybe_hash->ToObjectUnchecked())->value(); |
| + } |
| + |
| + UNREACHABLE(); |
| + return 0; |
| +} |
| + |
| + |
| +bool Object::SameValue(Object* other) { |
| + if (other == this) return true; |
| + if (!IsHeapObject() || !other->IsHeapObject()) return false; |
| + |
| + // The object is either a number, a string, an odd-ball, |
| + // a real JS object, or a Harmony proxy. |
| + if (IsNumber() && other->IsNumber()) { |
| + double this_value = Number(); |
| + double other_value = other->Number(); |
| + if (isnan(this_value) && isnan(other_value)) return true; |
| + return this_value == other_value; |
|
rossberg
2011/10/24 15:44:11
Test the common case first. Also, you can condense
Michael Starzinger
2011/10/25 11:17:26
Done.
|
| + } |
| + if (IsString() && other->IsString()) { |
| + return String::cast(this)->Equals(String::cast(other)); |
| + } |
| + return false; |
| +} |
| + |
| + |
| void Object::ShortPrint(FILE* out) { |
| HeapStringAllocator allocator; |
| StringStream accumulator(&allocator); |
| @@ -1270,6 +1307,8 @@ void HeapObject::IterateBody(InstanceType type, int object_size, |
| case JS_CONTEXT_EXTENSION_OBJECT_TYPE: |
| case JS_VALUE_TYPE: |
| case JS_ARRAY_TYPE: |
| + case JS_SET_TYPE: |
| + case JS_MAP_TYPE: |
| case JS_WEAK_MAP_TYPE: |
| case JS_REGEXP_TYPE: |
| case JS_GLOBAL_PROXY_TYPE: |
| @@ -10827,7 +10866,9 @@ template class HashTable<CompilationCacheShape, HashTableKey*>; |
| template class HashTable<MapCacheShape, HashTableKey*>; |
| -template class HashTable<ObjectHashTableShape, JSReceiver*>; |
| +template class HashTable<ObjectHashTableShape<1>, Object*>; |
| + |
| +template class HashTable<ObjectHashTableShape<2>, Object*>; |
| template class Dictionary<StringDictionaryShape, String*>; |
| @@ -12173,22 +12214,82 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor( |
| } |
| -Object* ObjectHashTable::Lookup(JSReceiver* key) { |
| +bool ObjectHashSet::Contains(Object* key) { |
| // If the object does not have an identity hash, it was never used as a key. |
| - MaybeObject* maybe_hash = key->GetIdentityHash(OMIT_CREATION); |
| - if (maybe_hash->IsFailure()) return GetHeap()->undefined_value(); |
| + if (key->IsJSReceiver() && !JSReceiver::cast(key)->HasIdentityHash()) { |
| + return false; |
| + } |
| + return (FindEntry(key) != kNotFound); |
| +} |
| + |
| + |
| +MaybeObject* ObjectHashSet::Add(Object* key) { |
| + // Make sure the key object has an identity hash code. |
| + int hash; |
| + if (key->IsJSReceiver()) { |
|
rossberg
2011/10/24 15:44:11
For example, this conditional is redundant if GetH
Michael Starzinger
2011/10/25 11:17:26
Done (see comment in objects.h).
|
| + MaybeObject* maybe_hash = |
| + JSReceiver::cast(key)->GetIdentityHash(ALLOW_CREATION); |
| + if (maybe_hash->IsFailure()) return maybe_hash; |
| + hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); |
| + } else { |
| + hash = key->GetHash(); |
| + } |
| + int entry = FindEntry(key); |
| + |
| + // Check whether key is already present. |
| + if (entry != kNotFound) return this; |
| + |
| + // Check whether the hash set should be extended and add entry. |
| + Object* obj; |
| + { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| + } |
| + ObjectHashSet* table = ObjectHashSet::cast(obj); |
| + entry = table->FindInsertionEntry(hash); |
| + table->set(EntryToIndex(entry), key); |
| + table->ElementAdded(); |
| + return table; |
| +} |
| + |
| + |
| +MaybeObject* ObjectHashSet::Remove(Object* key) { |
| + // If the object does not have an identity hash, it was never used as a key. |
| + if (key->IsJSReceiver() && !JSReceiver::cast(key)->HasIdentityHash()) { |
| + return this; |
| + } |
| + int entry = FindEntry(key); |
| + |
| + // Check whether key is actually present. |
| + if (entry == kNotFound) return this; |
| + |
| + // Remove entry and try to shrink this hash set. |
| + set_null(EntryToIndex(entry)); |
| + ElementRemoved(); |
| + return Shrink(key); |
| +} |
| + |
| + |
| +Object* ObjectHashTable::Lookup(Object* key) { |
| + // If the object does not have an identity hash, it was never used as a key. |
| + if (key->IsJSReceiver() && !JSReceiver::cast(key)->HasIdentityHash()) { |
| + return GetHeap()->undefined_value(); |
| + } |
| int entry = FindEntry(key); |
| if (entry == kNotFound) return GetHeap()->undefined_value(); |
| return get(EntryToIndex(entry) + 1); |
| } |
| -MaybeObject* ObjectHashTable::Put(JSReceiver* key, Object* value) { |
| +MaybeObject* ObjectHashTable::Put(Object* key, Object* value) { |
| // Make sure the key object has an identity hash code. |
| int hash; |
| - { MaybeObject* maybe_hash = key->GetIdentityHash(ALLOW_CREATION); |
| + if (key->IsJSReceiver()) { |
| + MaybeObject* maybe_hash = |
| + JSReceiver::cast(key)->GetIdentityHash(ALLOW_CREATION); |
| if (maybe_hash->IsFailure()) return maybe_hash; |
| hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); |
| + } else { |
| + hash = key->GetHash(); |
| } |
| int entry = FindEntry(key); |
| @@ -12216,7 +12317,7 @@ MaybeObject* ObjectHashTable::Put(JSReceiver* key, Object* value) { |
| } |
| -void ObjectHashTable::AddEntry(int entry, JSReceiver* key, Object* value) { |
| +void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) { |
| set(EntryToIndex(entry), key); |
| set(EntryToIndex(entry) + 1, value); |
| ElementAdded(); |