Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(282)

Unified Diff: src/objects.cc

Issue 8372027: Implement Harmony sets and maps. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments by Andreas Rossberg. Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 7616c9f62c7ad16e5f95380221b2d6bb0a450fcf..ff7a48aeec1e25166444ff8ef127086ec77eb952 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -723,6 +723,49 @@ Object* Object::GetPrototype() {
}
+MaybeObject* Object::GetHash(CreationFlag flag) {
+ // The object is either a number, a string, an odd-ball,
+ // a real JS object, or a Harmony proxy.
+ if (IsNumber()) {
+ uint32_t hash = ComputeLongHash(double_to_uint64(Number()));
+ return Smi::FromInt(hash & Smi::kMaxValue);
+ }
+ if (IsString()) {
+ uint32_t hash = String::cast(this)->Hash();
+ return Smi::FromInt(hash);
+ }
+ if (IsOddball()) {
+ uint32_t hash = Oddball::cast(this)->to_string()->Hash();
+ return Smi::FromInt(hash);
+ }
+ if (IsJSReceiver()) {
+ return JSReceiver::cast(this)->GetIdentityHash(flag);
+ }
+
+ UNREACHABLE();
+ return Smi::FromInt(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();
+ return (this_value == other_value) ||
+ (isnan(this_value) && isnan(other_value));
+ }
+ 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 +1313,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 +10872,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,20 +12220,72 @@ 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->GetHash(OMIT_CREATION);
+ if (maybe_hash->IsFailure()) return false;
+ }
+ return (FindEntry(key) != kNotFound);
+}
+
+
+MaybeObject* ObjectHashSet::Add(Object* key) {
+ // Make sure the key object has an identity hash code.
+ int hash;
+ { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION);
+ if (maybe_hash->IsFailure()) return maybe_hash;
+ hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
+ }
+ 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.
- MaybeObject* maybe_hash = key->GetIdentityHash(OMIT_CREATION);
- if (maybe_hash->IsFailure()) return GetHeap()->undefined_value();
+ { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
+ if (maybe_hash->IsFailure()) 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.
+ { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
+ if (maybe_hash->IsFailure()) 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);
+ { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION);
if (maybe_hash->IsFailure()) return maybe_hash;
hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
}
@@ -12216,7 +12315,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();

Powered by Google App Engine
This is Rietveld 408576698