OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1021 return context->symbol_function()->instance_prototype(); | 1021 return context->symbol_function()->instance_prototype(); |
1022 } | 1022 } |
1023 if (heap_object->IsBoolean()) { | 1023 if (heap_object->IsBoolean()) { |
1024 return context->boolean_function()->instance_prototype(); | 1024 return context->boolean_function()->instance_prototype(); |
1025 } else { | 1025 } else { |
1026 return isolate->heap()->null_value(); | 1026 return isolate->heap()->null_value(); |
1027 } | 1027 } |
1028 } | 1028 } |
1029 | 1029 |
1030 | 1030 |
1031 Handle<Object> Object::GetHash(Handle<Object> object, Isolate* isolate, | |
1032 CreationFlag flag) { | |
1033 CALL_HEAP_FUNCTION(isolate, | |
1034 object->GetHash(flag), | |
1035 Object); | |
1036 } | |
1037 | |
1038 | |
1031 MaybeObject* Object::GetHash(CreationFlag flag) { | 1039 MaybeObject* Object::GetHash(CreationFlag flag) { |
1032 // The object is either a number, a name, an odd-ball, | 1040 // The object is either a number, a name, an odd-ball, |
1033 // a real JS object, or a Harmony proxy. | 1041 // a real JS object, or a Harmony proxy. |
1034 if (IsNumber()) { | 1042 if (IsNumber()) { |
1035 uint32_t hash = ComputeLongHash(double_to_uint64(Number())); | 1043 uint32_t hash = ComputeLongHash(double_to_uint64(Number())); |
1036 return Smi::FromInt(hash & Smi::kMaxValue); | 1044 return Smi::FromInt(hash & Smi::kMaxValue); |
1037 } | 1045 } |
1038 if (IsName()) { | 1046 if (IsName()) { |
1039 uint32_t hash = Name::cast(this)->Hash(); | 1047 uint32_t hash = Name::cast(this)->Hash(); |
1040 return Smi::FromInt(hash); | 1048 return Smi::FromInt(hash); |
(...skipping 14656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15697 obj->set_properties(fields); | 15705 obj->set_properties(fields); |
15698 ASSERT(obj->IsJSObject()); | 15706 ASSERT(obj->IsJSObject()); |
15699 | 15707 |
15700 // Check that it really works. | 15708 // Check that it really works. |
15701 ASSERT(obj->HasFastProperties()); | 15709 ASSERT(obj->HasFastProperties()); |
15702 | 15710 |
15703 return obj; | 15711 return obj; |
15704 } | 15712 } |
15705 | 15713 |
15706 | 15714 |
15707 bool ObjectHashSet::Contains(Object* key) { | 15715 Handle<ObjectHashSet> ObjectHashSet::EnsureSetCapacity( |
15708 ASSERT(IsKey(key)); | 15716 Handle<ObjectHashSet> table, |
15709 | 15717 int n, |
15710 // If the object does not have an identity hash, it was never used as a key. | 15718 Handle<Object> key, |
15711 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); | 15719 PretenureFlag pretenure) { |
15712 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return false; | 15720 CALL_HEAP_FUNCTION(table->GetIsolate(), |
15713 } | 15721 table->EnsureCapacity(n, *key, pretenure), |
15714 return (FindEntry(key) != kNotFound); | 15722 ObjectHashSet); |
15715 } | 15723 } |
15716 | 15724 |
15717 | 15725 |
15718 MaybeObject* ObjectHashSet::Add(Object* key) { | 15726 Handle<ObjectHashSet> ObjectHashSet::ShrinkSet(Handle<ObjectHashSet> table, |
15719 ASSERT(IsKey(key)); | 15727 Handle<Object> key) { |
15720 | 15728 CALL_HEAP_FUNCTION(table->GetIsolate(), |
15721 // Make sure the key object has an identity hash code. | 15729 table->Shrink(*key), |
15722 int hash; | 15730 ObjectHashSet); |
15723 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); | |
15724 if (maybe_hash->IsFailure()) return maybe_hash; | |
15725 ASSERT(key->GetHash(OMIT_CREATION) == maybe_hash); | |
15726 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); | |
15727 } | |
15728 int entry = FindEntry(key); | |
15729 | |
15730 // Check whether key is already present. | |
15731 if (entry != kNotFound) return this; | |
15732 | |
15733 // Check whether the hash set should be extended and add entry. | |
15734 Object* obj; | |
15735 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | |
15736 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
15737 } | |
15738 ObjectHashSet* table = ObjectHashSet::cast(obj); | |
15739 entry = table->FindInsertionEntry(hash); | |
15740 table->set(EntryToIndex(entry), key); | |
15741 table->ElementAdded(); | |
15742 return table; | |
15743 } | 15731 } |
15744 | 15732 |
15745 | 15733 |
15746 MaybeObject* ObjectHashSet::Remove(Object* key) { | 15734 bool ObjectHashSet::Contains(Handle<ObjectHashSet> table, Handle<Object> key) { |
15747 ASSERT(IsKey(key)); | 15735 ASSERT(table->IsKey(*key)); |
15748 | 15736 |
15749 // If the object does not have an identity hash, it was never used as a key. | 15737 if (Object::GetHash(key, table->GetIsolate(), OMIT_CREATION)->IsUndefined()) |
15750 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); | 15738 return false; |
15751 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return this; | |
15752 } | |
15753 int entry = FindEntry(key); | |
15754 | 15739 |
15755 // Check whether key is actually present. | 15740 return (table->FindEntry(*key) != kNotFound); |
15756 if (entry == kNotFound) return this; | |
15757 | |
15758 // Remove entry and try to shrink this hash set. | |
15759 set_the_hole(EntryToIndex(entry)); | |
15760 ElementRemoved(); | |
15761 return Shrink(key); | |
15762 } | 15741 } |
15763 | 15742 |
15764 | 15743 |
15744 Handle<ObjectHashSet> ObjectHashSet::Add(Handle<ObjectHashSet> table, | |
15745 Handle<Object> key) { | |
15746 ASSERT(table->IsKey(*key)); | |
15747 | |
15748 Isolate* isolate = table->GetIsolate(); | |
15749 | |
15750 // Make sure the key object has an identity hash code. | |
15751 Handle<Object> object_hash = Object::GetHash(key, isolate, ALLOW_CREATION); | |
15752 ASSERT(*Object::GetHash(key, isolate, OMIT_CREATION) == *object_hash); | |
15753 | |
15754 int hash = Smi::cast(*object_hash)->value(); | |
15755 int entry = table->FindEntry(*key); | |
15756 | |
15757 // Check whether key is already present. | |
15758 if (entry != kNotFound) return table; | |
15759 | |
15760 // Check whether the hash set should be extended and add entry. | |
15761 Handle<ObjectHashSet> new_table = | |
15762 ObjectHashSet::EnsureSetCapacity(table, 1, key); | |
15763 entry = new_table->FindInsertionEntry(hash); | |
15764 new_table->set(table->EntryToIndex(entry), *key); | |
rafaelw
2013/11/04 10:58:06
One question, this probably doesn't matter, but it
Michael Starzinger
2013/11/04 13:46:42
Hmm, HashTable::EntryToIndex() should be a static
rafaelw
2013/11/04 15:12:01
That makes sense. The enclosing methods are now st
| |
15765 new_table->ElementAdded(); | |
15766 return new_table; | |
15767 } | |
15768 | |
15769 | |
15770 Handle<ObjectHashSet> ObjectHashSet::Remove(Handle<ObjectHashSet> table, | |
15771 Handle<Object> key) { | |
15772 ASSERT(table->IsKey(*key)); | |
15773 | |
15774 Isolate* isolate = table->GetIsolate(); | |
15775 | |
15776 // Make sure the key object has an identity hash code. | |
15777 if (Object::GetHash(key, isolate, OMIT_CREATION)->IsUndefined()) return table; | |
15778 | |
15779 int entry = table->FindEntry(*key); | |
15780 | |
15781 // Check whether key is actually present. | |
15782 if (entry == kNotFound) return table; | |
15783 | |
15784 // Remove entry and try to shrink this hash set. | |
15785 table->set_the_hole(table->EntryToIndex(entry)); | |
15786 table->ElementRemoved(); | |
15787 return ObjectHashSet::ShrinkSet(table, key); | |
15788 } | |
15789 | |
15790 | |
15765 Object* ObjectHashTable::Lookup(Object* key) { | 15791 Object* ObjectHashTable::Lookup(Object* key) { |
15766 ASSERT(IsKey(key)); | 15792 ASSERT(IsKey(key)); |
15767 | 15793 |
15768 // If the object does not have an identity hash, it was never used as a key. | 15794 // If the object does not have an identity hash, it was never used as a key. |
15769 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); | 15795 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); |
15770 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) { | 15796 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) { |
15771 return GetHeap()->the_hole_value(); | 15797 return GetHeap()->the_hole_value(); |
15772 } | 15798 } |
15773 } | 15799 } |
15774 int entry = FindEntry(key); | 15800 int entry = FindEntry(key); |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16396 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16422 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16397 static const char* error_messages_[] = { | 16423 static const char* error_messages_[] = { |
16398 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16424 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16399 }; | 16425 }; |
16400 #undef ERROR_MESSAGES_TEXTS | 16426 #undef ERROR_MESSAGES_TEXTS |
16401 return error_messages_[reason]; | 16427 return error_messages_[reason]; |
16402 } | 16428 } |
16403 | 16429 |
16404 | 16430 |
16405 } } // namespace v8::internal | 16431 } } // namespace v8::internal |
OLD | NEW |