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(); |