Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index 454a1e8cfd9cd2ee42465ca192b65b06c72e22c3..7f8c683fd6d3b9a2e3acb499e62a5728809f3434 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -1028,7 +1028,7 @@ Object* Object::GetPrototype(Isolate* isolate) { |
| } |
| -MaybeObject* Object::GetHash(CreationFlag flag) { |
| +Object* Object::GetHash() { |
| // The object is either a number, a name, an odd-ball, |
| // a real JS object, or a Harmony proxy. |
| if (IsNumber()) { |
| @@ -1043,12 +1043,20 @@ MaybeObject* Object::GetHash(CreationFlag flag) { |
| 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); |
| + ASSERT(IsJSReceiver()); |
|
rafaelw
2013/11/04 15:12:01
Note that I've changed this for consistency with G
|
| + return JSReceiver::cast(this)->GetIdentityHash(); |
| +} |
| + |
| + |
| +Handle<Object> Object::GetOrCreateHash(Handle<Object> object, |
| + Isolate* isolate) { |
| + Handle<Object> hash(object->GetHash(), isolate); |
| + if (hash->IsSmi()) |
| + return hash; |
| + |
| + ASSERT(object->IsJSReceiver()); |
| + return JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver>::cast(object)); |
| } |
| @@ -3755,7 +3763,7 @@ void JSProxy::Fix(Handle<JSProxy> proxy) { |
| Isolate* isolate = proxy->GetIsolate(); |
| // Save identity hash. |
| - Handle<Object> hash = JSProxy::GetIdentityHash(proxy, OMIT_CREATION); |
| + Handle<Object> hash(proxy->GetIdentityHash(), isolate); |
| if (proxy->IsJSFunctionProxy()) { |
| isolate->factory()->BecomeJSFunction(proxy); |
| @@ -3767,7 +3775,8 @@ void JSProxy::Fix(Handle<JSProxy> proxy) { |
| // Inherit identity, if it was present. |
| if (hash->IsSmi()) { |
| - JSObject::SetIdentityHash(Handle<JSObject>::cast(proxy), Smi::cast(*hash)); |
| + JSObject::SetIdentityHash(Handle<JSObject>::cast(proxy), |
| + Handle<Smi>::cast(hash)); |
| } |
| } |
| @@ -4788,52 +4797,59 @@ Smi* JSReceiver::GenerateIdentityHash() { |
| } |
| -void JSObject::SetIdentityHash(Handle<JSObject> object, Smi* hash) { |
| - CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), |
| - object->SetHiddenProperty( |
| - object->GetHeap()->identity_hash_string(), hash)); |
| +void JSObject::SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash) { |
| + Isolate* isolate = object->GetIsolate(); |
| + JSObject::SetHiddenProperty( |
|
Michael Starzinger
2013/11/04 17:58:58
nit: The explicit name-space prefix "JSObject::" s
rafaelw
2013/11/05 09:56:54
Done.
|
| + object, isolate->factory()->identity_hash_string(), hash); |
| } |
| int JSObject::GetIdentityHash(Handle<JSObject> object) { |
| - CALL_AND_RETRY_OR_DIE(object->GetIsolate(), |
| - object->GetIdentityHash(ALLOW_CREATION), |
| - return Smi::cast(__object__)->value(), |
| - return 0); |
| + Handle<Object> hash = JSObject::GetOrCreateIdentityHash(object); |
|
rafaelw
2013/11/04 15:12:01
I *think* this is right. It's a bit hard for me to
Michael Starzinger
2013/11/04 17:58:58
AFAICT, the return value of JSObject::GetOrCreateI
rafaelw
2013/11/05 09:56:54
Done.
|
| + return hash->IsSmi() ? Handle<Smi>::cast(hash)->value() : 0; |
| } |
| -MaybeObject* JSObject::GetIdentityHash(CreationFlag flag) { |
| +Object* JSObject::GetIdentityHash() { |
| Object* stored_value = GetHiddenProperty(GetHeap()->identity_hash_string()); |
| - if (stored_value->IsSmi()) return stored_value; |
| + return stored_value->IsSmi() ? stored_value : GetHeap()->undefined_value(); |
| +} |
| + |
| + |
| +Handle<Object> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) { |
| + Handle<Object> hash(object->GetIdentityHash(), object->GetIsolate()); |
| + if (hash->IsSmi()) |
| + return hash; |
| + |
| + Isolate* isolate = object->GetIsolate(); |
| - // Do not generate permanent identity hash code if not requested. |
| - if (flag == OMIT_CREATION) return GetHeap()->undefined_value(); |
| + hash = handle(object->GenerateIdentityHash(), isolate); |
| + Handle<Object> result = JSObject::SetHiddenProperty(object, |
| + isolate->factory()->identity_hash_string(), hash); |
| - Smi* hash = GenerateIdentityHash(); |
| - MaybeObject* result = SetHiddenProperty(GetHeap()->identity_hash_string(), |
| - hash); |
| - if (result->IsFailure()) return result; |
| - if (result->ToObjectUnchecked()->IsUndefined()) { |
| + if (result->IsUndefined()) { |
| // Trying to get hash of detached proxy. |
| - return Smi::FromInt(0); |
| + return handle(Smi::FromInt(0), isolate); |
| } |
| + |
| return hash; |
| } |
| -Handle<Object> JSProxy::GetIdentityHash(Handle<JSProxy> proxy, |
| - CreationFlag flag) { |
| - CALL_HEAP_FUNCTION(proxy->GetIsolate(), proxy->GetIdentityHash(flag), Object); |
| +Object* JSProxy::GetIdentityHash() { |
| + return this->hash(); |
| } |
| -MaybeObject* JSProxy::GetIdentityHash(CreationFlag flag) { |
| - Object* hash = this->hash(); |
| - if (!hash->IsSmi() && flag == ALLOW_CREATION) { |
| - hash = GenerateIdentityHash(); |
| - set_hash(hash); |
| - } |
| +Handle<Object> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) { |
| + Isolate* isolate = proxy->GetIsolate(); |
| + |
| + Handle<Object> hash(proxy->GetIdentityHash(), isolate); |
| + if (hash->IsSmi()) |
| + return hash; |
| + |
| + hash = handle(proxy->GenerateIdentityHash(), isolate); |
| + proxy->set_hash(*hash); |
| return hash; |
| } |
| @@ -4849,9 +4865,7 @@ Object* JSObject::GetHiddenProperty(Name* key) { |
| return JSObject::cast(proxy_parent)->GetHiddenProperty(key); |
| } |
| ASSERT(!IsJSGlobalProxy()); |
| - MaybeObject* hidden_lookup = |
| - GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE); |
| - Object* inline_value = hidden_lookup->ToObjectUnchecked(); |
| + Object* inline_value = GetHiddenPropertiesHashTable(); |
| if (inline_value->IsSmi()) { |
| // Handle inline-stored identity hash. |
| @@ -4870,53 +4884,47 @@ Object* JSObject::GetHiddenProperty(Name* key) { |
| } |
| -Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj, |
| +Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, |
| Handle<Name> key, |
| Handle<Object> value) { |
| - CALL_HEAP_FUNCTION(obj->GetIsolate(), |
| - obj->SetHiddenProperty(*key, *value), |
| - Object); |
| -} |
| - |
| + Isolate* isolate = object->GetIsolate(); |
| -MaybeObject* JSObject::SetHiddenProperty(Name* key, Object* value) { |
| ASSERT(key->IsUniqueName()); |
| - if (IsJSGlobalProxy()) { |
| + if (object->IsJSGlobalProxy()) { |
| // For a proxy, use the prototype as target object. |
| - Object* proxy_parent = GetPrototype(); |
| + Handle<Object> proxy_parent(object->GetPrototype(), isolate); |
| // If the proxy is detached, return undefined. |
| - if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); |
| + if (proxy_parent->IsNull()) return isolate->factory()->undefined_value(); |
| ASSERT(proxy_parent->IsJSGlobalObject()); |
| - return JSObject::cast(proxy_parent)->SetHiddenProperty(key, value); |
| + return JSObject::SetHiddenProperty(Handle<JSObject>::cast(proxy_parent), |
| + key, |
| + value); |
| } |
| - ASSERT(!IsJSGlobalProxy()); |
| - MaybeObject* hidden_lookup = |
| - GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE); |
| - Object* inline_value = hidden_lookup->ToObjectUnchecked(); |
| + ASSERT(!object->IsJSGlobalProxy()); |
| + |
| + Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); |
| // If there is no backing store yet, store the identity hash inline. |
| if (value->IsSmi() && |
| - key == GetHeap()->identity_hash_string() && |
| + *key == *isolate->factory()->identity_hash_string() && |
| (inline_value->IsUndefined() || inline_value->IsSmi())) { |
| - return SetHiddenPropertiesHashTable(value); |
| + return JSObject::SetHiddenPropertiesHashTable(object, value); |
| } |
| - hidden_lookup = GetHiddenPropertiesHashTable(CREATE_NEW_IF_ABSENT); |
| - ObjectHashTable* hashtable; |
| - if (!hidden_lookup->To(&hashtable)) return hidden_lookup; |
| + Handle<ObjectHashTable> hashtable = |
| + JSObject::GetOrCreateHiddenPropertiesHashtable(object); |
| // If it was found, check if the key is already in the dictionary. |
| - MaybeObject* insert_result = hashtable->Put(key, value); |
| - ObjectHashTable* new_table; |
| - if (!insert_result->To(&new_table)) return insert_result; |
| - if (new_table != hashtable) { |
| + Handle<ObjectHashTable> new_table = ObjectHashTable::Put(hashtable, key, |
| + value); |
| + if (*new_table != *hashtable) { |
| // If adding the key expanded the dictionary (i.e., Add returned a new |
| // dictionary), store it back to the object. |
| - MaybeObject* store_result = SetHiddenPropertiesHashTable(new_table); |
| - if (store_result->IsFailure()) return store_result; |
| + JSObject::SetHiddenPropertiesHashTable(object, new_table); |
| } |
| + |
| // Return this to mark success. |
| - return this; |
| + return object; |
| } |
| @@ -4931,16 +4939,14 @@ void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) { |
| return DeleteHiddenProperty(Handle<JSObject>::cast(proto), key); |
| } |
| - MaybeObject* hidden_lookup = |
| - object->GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE); |
| - Object* inline_value = hidden_lookup->ToObjectUnchecked(); |
| + Object* inline_value = object->GetHiddenPropertiesHashTable(); |
| // We never delete (inline-stored) identity hashes. |
| - ASSERT(*key != isolate->heap()->identity_hash_string()); |
| + ASSERT(*key != *isolate->factory()->identity_hash_string()); |
| if (inline_value->IsUndefined() || inline_value->IsSmi()) return; |
| Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); |
| - PutIntoObjectHashTable(hashtable, key, isolate->factory()->the_hole_value()); |
| + ObjectHashTable::Put(hashtable, key, isolate->factory()->the_hole_value()); |
| } |
| @@ -4951,8 +4957,7 @@ bool JSObject::HasHiddenProperties() { |
| } |
| -MaybeObject* JSObject::GetHiddenPropertiesHashTable( |
| - InitializeHiddenProperties init_option) { |
| +Object* JSObject::GetHiddenPropertiesHashTable() { |
| ASSERT(!IsJSGlobalProxy()); |
| Object* inline_value; |
|
Michael Starzinger
2013/11/04 17:58:58
nit: The local "inline_value" variable is (almost)
rafaelw
2013/11/05 09:56:54
Done.
|
| if (HasFastProperties()) { |
| @@ -4970,89 +4975,95 @@ MaybeObject* JSObject::GetHiddenPropertiesHashTable( |
| IsCompatibleForLoad(Representation::Tagged())); |
| inline_value = this->RawFastPropertyAt( |
| descriptors->GetFieldIndex(sorted_index)); |
| + return inline_value; |
| } else { |
| - inline_value = GetHeap()->undefined_value(); |
| + return GetHeap()->undefined_value(); |
| } |
| } else { |
| - inline_value = GetHeap()->undefined_value(); |
| + return GetHeap()->undefined_value(); |
| } |
| } else { |
| PropertyAttributes attributes; |
| // You can't install a getter on a property indexed by the hidden string, |
| // so we can be sure that GetLocalPropertyPostInterceptor returns a real |
| // object. |
| - inline_value = |
| - GetLocalPropertyPostInterceptor(this, |
| - GetHeap()->hidden_string(), |
| - &attributes)->ToObjectUnchecked(); |
| + return GetLocalPropertyPostInterceptor(this, |
| + GetHeap()->hidden_string(), |
| + &attributes)->ToObjectUnchecked(); |
| } |
| +} |
| - if (init_option == ONLY_RETURN_INLINE_VALUE || |
| - inline_value->IsHashTable()) { |
| - return inline_value; |
| - } |
| +Handle<ObjectHashTable> JSObject::GetOrCreateHiddenPropertiesHashtable( |
| + Handle<JSObject> object) { |
| + Isolate* isolate = object->GetIsolate(); |
| - ObjectHashTable* hashtable; |
| static const int kInitialCapacity = 4; |
| - MaybeObject* maybe_obj = |
| - ObjectHashTable::Allocate(GetHeap(), |
| - kInitialCapacity, |
| - ObjectHashTable::USE_CUSTOM_MINIMUM_CAPACITY); |
| - if (!maybe_obj->To<ObjectHashTable>(&hashtable)) return maybe_obj; |
| + Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); |
| + if (inline_value->IsHashTable()) { |
| + return Handle<ObjectHashTable>::cast(inline_value); |
| + } |
| + |
| + Handle<ObjectHashTable> hashtable = isolate->factory()->NewObjectHashTable( |
| + kInitialCapacity, |
| + USE_CUSTOM_MINIMUM_CAPACITY); |
| if (inline_value->IsSmi()) { |
| // We were storing the identity hash inline and now allocated an actual |
| // dictionary. Put the identity hash into the new dictionary. |
| - MaybeObject* insert_result = |
| - hashtable->Put(GetHeap()->identity_hash_string(), inline_value); |
| - ObjectHashTable* new_table; |
| - if (!insert_result->To(&new_table)) return insert_result; |
| - // We expect no resizing for the first insert. |
| - ASSERT_EQ(hashtable, new_table); |
| + hashtable = ObjectHashTable::Put(hashtable, |
| + isolate->factory()->identity_hash_string(), |
| + inline_value); |
| } |
| - MaybeObject* store_result = SetLocalPropertyIgnoreAttributesTrampoline( |
| - GetHeap()->hidden_string(), |
| + JSObject::SetLocalPropertyIgnoreAttributes( |
| + object, |
| + isolate->factory()->hidden_string(), |
| hashtable, |
| DONT_ENUM, |
| OPTIMAL_REPRESENTATION, |
| ALLOW_AS_CONSTANT, |
| OMIT_EXTENSIBILITY_CHECK); |
| - if (store_result->IsFailure()) return store_result; |
| + |
| return hashtable; |
| } |
| -MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) { |
| - ASSERT(!IsJSGlobalProxy()); |
| +Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object, |
| + Handle<Object> value) { |
| + ASSERT(!object->IsJSGlobalProxy()); |
| + |
| + Isolate* isolate = object->GetIsolate(); |
| + |
| // We can store the identity hash inline iff there is no backing store |
| // for hidden properties yet. |
| - ASSERT(HasHiddenProperties() != value->IsSmi()); |
| - if (HasFastProperties()) { |
| + ASSERT(object->HasHiddenProperties() != value->IsSmi()); |
| + if (object->HasFastProperties()) { |
| // If the object has fast properties, check whether the first slot |
| // in the descriptor array matches the hidden string. Since the |
| // hidden strings hash code is zero (and no other name has hash |
| // code zero) it will always occupy the first entry if present. |
| - DescriptorArray* descriptors = this->map()->instance_descriptors(); |
| + DescriptorArray* descriptors = object->map()->instance_descriptors(); |
| if (descriptors->number_of_descriptors() > 0) { |
| int sorted_index = descriptors->GetSortedKeyIndex(0); |
| - if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && |
| - sorted_index < map()->NumberOfOwnDescriptors()) { |
| + if (descriptors->GetKey(sorted_index) == isolate->heap()->hidden_string() |
| + && sorted_index < object->map()->NumberOfOwnDescriptors()) { |
| ASSERT(descriptors->GetType(sorted_index) == FIELD); |
| - FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), value); |
| - return this; |
| + object->FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), |
| + *value); |
| + return object; |
| } |
| } |
| } |
| - MaybeObject* store_result = SetLocalPropertyIgnoreAttributesTrampoline( |
| - GetHeap()->hidden_string(), |
| + |
| + JSObject::SetLocalPropertyIgnoreAttributes( |
| + object, |
| + isolate->factory()->hidden_string(), |
| value, |
| DONT_ENUM, |
| OPTIMAL_REPRESENTATION, |
| ALLOW_AS_CONSTANT, |
| OMIT_EXTENSIBILITY_CHECK); |
| - if (store_result->IsFailure()) return store_result; |
| - return this; |
| + return object; |
| } |
| @@ -15138,7 +15149,7 @@ MaybeObject* Dictionary<Shape, Key>::Allocate(Heap* heap, |
| HashTable<Shape, Key>::Allocate( |
| heap, |
| at_least_space_for, |
| - HashTable<Shape, Key>::USE_DEFAULT_MINIMUM_CAPACITY, |
| + USE_DEFAULT_MINIMUM_CAPACITY, |
| pretenure); |
| if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| } |
| @@ -15704,61 +15715,99 @@ MaybeObject* NameDictionary::TransformPropertiesToFastFor( |
| } |
| +Handle<ObjectHashSet> ObjectHashSet::EnsureCapacity( |
| + Handle<ObjectHashSet> table, |
| + int n, |
| + Handle<Object> key, |
| + PretenureFlag pretenure) { |
| + Handle<HashTable<ObjectHashTableShape<1>, Object*> > table_base = table; |
| + CALL_HEAP_FUNCTION(table_base->GetIsolate(), |
| + table_base->EnsureCapacity(n, *key, pretenure), |
| + ObjectHashSet); |
| +} |
| + |
| + |
| +Handle<ObjectHashSet> ObjectHashSet::Shrink(Handle<ObjectHashSet> table, |
| + Handle<Object> key) { |
| + Handle<HashTable<ObjectHashTableShape<1>, Object*> > table_base = table; |
| + CALL_HEAP_FUNCTION(table_base->GetIsolate(), |
| + table_base->Shrink(*key), |
| + ObjectHashSet); |
| +} |
| + |
| + |
| bool ObjectHashSet::Contains(Object* key) { |
| ASSERT(IsKey(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->ToObjectUnchecked()->IsUndefined()) return false; |
| - } |
| + Object* hash = key->GetHash(); |
| + if (hash->IsUndefined()) return false; |
| + |
| return (FindEntry(key) != kNotFound); |
| } |
| -MaybeObject* ObjectHashSet::Add(Object* key) { |
| - ASSERT(IsKey(key)); |
| +Handle<ObjectHashSet> ObjectHashSet::Add(Handle<ObjectHashSet> table, |
| + Handle<Object> key) { |
| + ASSERT(table->IsKey(*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; |
| - ASSERT(key->GetHash(OMIT_CREATION) == maybe_hash); |
| - hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); |
| - } |
| - int entry = FindEntry(key); |
| + Handle<Object> object_hash = Object::GetOrCreateHash(key, |
| + table->GetIsolate()); |
| + |
| + int entry = table->FindEntry(*key); |
| // Check whether key is already present. |
| - if (entry != kNotFound) return this; |
| + if (entry != kNotFound) return table; |
| // 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; |
| + Handle<ObjectHashSet> new_table = |
| + ObjectHashSet::EnsureCapacity(table, 1, key); |
| + entry = new_table->FindInsertionEntry(Smi::cast(*object_hash)->value()); |
| + new_table->set(ObjectHashSet::EntryToIndex(entry), *key); |
| + new_table->ElementAdded(); |
| + return new_table; |
| } |
| -MaybeObject* ObjectHashSet::Remove(Object* key) { |
| - ASSERT(IsKey(key)); |
| +Handle<ObjectHashSet> ObjectHashSet::Remove(Handle<ObjectHashSet> table, |
| + Handle<Object> key) { |
| + ASSERT(table->IsKey(*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->ToObjectUnchecked()->IsUndefined()) return this; |
| - } |
| - int entry = FindEntry(key); |
| + if (key->GetHash()->IsUndefined()) return table; |
| + |
| + int entry = table->FindEntry(*key); |
| // Check whether key is actually present. |
| - if (entry == kNotFound) return this; |
| + if (entry == kNotFound) return table; |
| // Remove entry and try to shrink this hash set. |
| - set_the_hole(EntryToIndex(entry)); |
| - ElementRemoved(); |
| - return Shrink(key); |
| + table->set_the_hole(ObjectHashSet::EntryToIndex(entry)); |
| + table->ElementRemoved(); |
| + |
| + return ObjectHashSet::Shrink(table, key); |
| +} |
| + |
| + |
| +Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity( |
| + Handle<ObjectHashTable> table, |
| + int n, |
| + Handle<Object> key, |
| + PretenureFlag pretenure) { |
| + Handle<HashTable<ObjectHashTableShape<2>, Object*> > table_base = table; |
| + CALL_HEAP_FUNCTION(table_base->GetIsolate(), |
| + table_base->EnsureCapacity(n, *key, pretenure), |
| + ObjectHashTable); |
| +} |
| + |
| + |
| +Handle<ObjectHashTable> ObjectHashTable::Shrink( |
| + Handle<ObjectHashTable> table, Handle<Object> key) { |
| + Handle<HashTable<ObjectHashTableShape<2>, Object*> > table_base = table; |
| + CALL_HEAP_FUNCTION(table_base->GetIsolate(), |
| + table_base->Shrink(*key), |
| + ObjectHashTable); |
| } |
| @@ -15766,10 +15815,9 @@ Object* ObjectHashTable::Lookup(Object* key) { |
| ASSERT(IsKey(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->ToObjectUnchecked()->IsUndefined()) { |
| - return GetHeap()->the_hole_value(); |
| - } |
| + Object* hash = key->GetHash(); |
| + if (hash->IsUndefined()) { |
| + return GetHeap()->the_hole_value(); |
| } |
| int entry = FindEntry(key); |
| if (entry == kNotFound) return GetHeap()->the_hole_value(); |
| @@ -15777,38 +15825,36 @@ Object* ObjectHashTable::Lookup(Object* key) { |
| } |
| -MaybeObject* ObjectHashTable::Put(Object* key, Object* value) { |
| - ASSERT(IsKey(key)); |
| +Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, |
| + Handle<Object> key, |
| + Handle<Object> value) { |
| + ASSERT(table->IsKey(*key)); |
| + |
| + Isolate* isolate = table->GetIsolate(); |
| // 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; |
| - ASSERT(key->GetHash(OMIT_CREATION) == maybe_hash); |
| - hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); |
| - } |
| - int entry = FindEntry(key); |
| + Handle<Object> hash = Object::GetOrCreateHash(key, isolate); |
| + |
| + int entry = table->FindEntry(*key); |
| // Check whether to perform removal operation. |
| if (value->IsTheHole()) { |
| - if (entry == kNotFound) return this; |
| - RemoveEntry(entry); |
| - return Shrink(key); |
| + if (entry == kNotFound) return table; |
| + table->RemoveEntry(entry); |
| + return ObjectHashTable::Shrink(table, key); |
| } |
| // Key is already in table, just overwrite value. |
| if (entry != kNotFound) { |
| - set(EntryToIndex(entry) + 1, value); |
| - return this; |
| + table->set(ObjectHashTable::EntryToIndex(entry) + 1, *value); |
| + return table; |
| } |
| // Check whether the hash table should be extended. |
| - Object* obj; |
| - { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| - if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| - } |
| - ObjectHashTable* table = ObjectHashTable::cast(obj); |
| - table->AddEntry(table->FindInsertionEntry(hash), key, value); |
| + table = ObjectHashTable::EnsureCapacity(table, 1, key); |
| + table->AddEntry(table->FindInsertionEntry(Handle<Smi>::cast(hash)->value()), |
| + *key, |
| + *value); |
| return table; |
| } |