OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
716 return context->string_function()->instance_prototype(); | 716 return context->string_function()->instance_prototype(); |
717 } | 717 } |
718 if (heap_object->IsBoolean()) { | 718 if (heap_object->IsBoolean()) { |
719 return context->boolean_function()->instance_prototype(); | 719 return context->boolean_function()->instance_prototype(); |
720 } else { | 720 } else { |
721 return heap->null_value(); | 721 return heap->null_value(); |
722 } | 722 } |
723 } | 723 } |
724 | 724 |
725 | 725 |
726 uint32_t Object::GetHash() { | |
727 // The object is either a number, a string, an odd-ball, | |
728 // a real JS object, or a Harmony proxy. | |
729 if (IsNumber()) return ComputeLongHash(double_to_uint64(Number())); | |
730 if (IsString()) return String::cast(this)->Hash(); | |
731 if (IsOddball()) return Oddball::cast(this)->to_string()->Hash(); | |
732 if (IsJSReceiver()) { | |
733 MaybeObject* maybe_hash = | |
734 JSReceiver::cast(this)->GetIdentityHash(OMIT_CREATION); | |
735 ASSERT(!maybe_hash->IsFailure()); | |
736 return Smi::cast(maybe_hash->ToObjectUnchecked())->value(); | |
737 } | |
738 | |
739 UNREACHABLE(); | |
740 return 0; | |
741 } | |
742 | |
743 | |
744 bool Object::SameValue(Object* other) { | |
745 if (other == this) return true; | |
746 if (!IsHeapObject() || !other->IsHeapObject()) return false; | |
747 | |
748 // The object is either a number, a string, an odd-ball, | |
749 // a real JS object, or a Harmony proxy. | |
750 if (IsNumber() && other->IsNumber()) { | |
751 double this_value = Number(); | |
752 double other_value = other->Number(); | |
753 if (isnan(this_value) && isnan(other_value)) return true; | |
754 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.
| |
755 } | |
756 if (IsString() && other->IsString()) { | |
757 return String::cast(this)->Equals(String::cast(other)); | |
758 } | |
759 return false; | |
760 } | |
761 | |
762 | |
726 void Object::ShortPrint(FILE* out) { | 763 void Object::ShortPrint(FILE* out) { |
727 HeapStringAllocator allocator; | 764 HeapStringAllocator allocator; |
728 StringStream accumulator(&allocator); | 765 StringStream accumulator(&allocator); |
729 ShortPrint(&accumulator); | 766 ShortPrint(&accumulator); |
730 accumulator.OutputToFile(out); | 767 accumulator.OutputToFile(out); |
731 } | 768 } |
732 | 769 |
733 | 770 |
734 void Object::ShortPrint(StringStream* accumulator) { | 771 void Object::ShortPrint(StringStream* accumulator) { |
735 if (IsSmi()) { | 772 if (IsSmi()) { |
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1263 switch (type) { | 1300 switch (type) { |
1264 case FIXED_ARRAY_TYPE: | 1301 case FIXED_ARRAY_TYPE: |
1265 FixedArray::BodyDescriptor::IterateBody(this, object_size, v); | 1302 FixedArray::BodyDescriptor::IterateBody(this, object_size, v); |
1266 break; | 1303 break; |
1267 case FIXED_DOUBLE_ARRAY_TYPE: | 1304 case FIXED_DOUBLE_ARRAY_TYPE: |
1268 break; | 1305 break; |
1269 case JS_OBJECT_TYPE: | 1306 case JS_OBJECT_TYPE: |
1270 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: | 1307 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: |
1271 case JS_VALUE_TYPE: | 1308 case JS_VALUE_TYPE: |
1272 case JS_ARRAY_TYPE: | 1309 case JS_ARRAY_TYPE: |
1310 case JS_SET_TYPE: | |
1311 case JS_MAP_TYPE: | |
1273 case JS_WEAK_MAP_TYPE: | 1312 case JS_WEAK_MAP_TYPE: |
1274 case JS_REGEXP_TYPE: | 1313 case JS_REGEXP_TYPE: |
1275 case JS_GLOBAL_PROXY_TYPE: | 1314 case JS_GLOBAL_PROXY_TYPE: |
1276 case JS_GLOBAL_OBJECT_TYPE: | 1315 case JS_GLOBAL_OBJECT_TYPE: |
1277 case JS_BUILTINS_OBJECT_TYPE: | 1316 case JS_BUILTINS_OBJECT_TYPE: |
1278 case JS_MESSAGE_OBJECT_TYPE: | 1317 case JS_MESSAGE_OBJECT_TYPE: |
1279 JSObject::BodyDescriptor::IterateBody(this, object_size, v); | 1318 JSObject::BodyDescriptor::IterateBody(this, object_size, v); |
1280 break; | 1319 break; |
1281 case JS_FUNCTION_TYPE: | 1320 case JS_FUNCTION_TYPE: |
1282 reinterpret_cast<JSFunction*>(this) | 1321 reinterpret_cast<JSFunction*>(this) |
(...skipping 9537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10820 | 10859 |
10821 // Force instantiation of template instances class. | 10860 // Force instantiation of template instances class. |
10822 // Please note this list is compiler dependent. | 10861 // Please note this list is compiler dependent. |
10823 | 10862 |
10824 template class HashTable<SymbolTableShape, HashTableKey*>; | 10863 template class HashTable<SymbolTableShape, HashTableKey*>; |
10825 | 10864 |
10826 template class HashTable<CompilationCacheShape, HashTableKey*>; | 10865 template class HashTable<CompilationCacheShape, HashTableKey*>; |
10827 | 10866 |
10828 template class HashTable<MapCacheShape, HashTableKey*>; | 10867 template class HashTable<MapCacheShape, HashTableKey*>; |
10829 | 10868 |
10830 template class HashTable<ObjectHashTableShape, JSReceiver*>; | 10869 template class HashTable<ObjectHashTableShape<1>, Object*>; |
10870 | |
10871 template class HashTable<ObjectHashTableShape<2>, Object*>; | |
10831 | 10872 |
10832 template class Dictionary<StringDictionaryShape, String*>; | 10873 template class Dictionary<StringDictionaryShape, String*>; |
10833 | 10874 |
10834 template class Dictionary<NumberDictionaryShape, uint32_t>; | 10875 template class Dictionary<NumberDictionaryShape, uint32_t>; |
10835 | 10876 |
10836 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate( | 10877 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate( |
10837 int); | 10878 int); |
10838 | 10879 |
10839 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( | 10880 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( |
10840 int); | 10881 int); |
(...skipping 1325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12166 ASSERT(obj->IsJSObject()); | 12207 ASSERT(obj->IsJSObject()); |
12167 | 12208 |
12168 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); | 12209 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); |
12169 // Check that it really works. | 12210 // Check that it really works. |
12170 ASSERT(obj->HasFastProperties()); | 12211 ASSERT(obj->HasFastProperties()); |
12171 | 12212 |
12172 return obj; | 12213 return obj; |
12173 } | 12214 } |
12174 | 12215 |
12175 | 12216 |
12176 Object* ObjectHashTable::Lookup(JSReceiver* key) { | 12217 bool ObjectHashSet::Contains(Object* key) { |
12177 // If the object does not have an identity hash, it was never used as a key. | 12218 // If the object does not have an identity hash, it was never used as a key. |
12178 MaybeObject* maybe_hash = key->GetIdentityHash(OMIT_CREATION); | 12219 if (key->IsJSReceiver() && !JSReceiver::cast(key)->HasIdentityHash()) { |
12179 if (maybe_hash->IsFailure()) return GetHeap()->undefined_value(); | 12220 return false; |
12221 } | |
12222 return (FindEntry(key) != kNotFound); | |
12223 } | |
12224 | |
12225 | |
12226 MaybeObject* ObjectHashSet::Add(Object* key) { | |
12227 // Make sure the key object has an identity hash code. | |
12228 int hash; | |
12229 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).
| |
12230 MaybeObject* maybe_hash = | |
12231 JSReceiver::cast(key)->GetIdentityHash(ALLOW_CREATION); | |
12232 if (maybe_hash->IsFailure()) return maybe_hash; | |
12233 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); | |
12234 } else { | |
12235 hash = key->GetHash(); | |
12236 } | |
12237 int entry = FindEntry(key); | |
12238 | |
12239 // Check whether key is already present. | |
12240 if (entry != kNotFound) return this; | |
12241 | |
12242 // Check whether the hash set should be extended and add entry. | |
12243 Object* obj; | |
12244 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | |
12245 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
12246 } | |
12247 ObjectHashSet* table = ObjectHashSet::cast(obj); | |
12248 entry = table->FindInsertionEntry(hash); | |
12249 table->set(EntryToIndex(entry), key); | |
12250 table->ElementAdded(); | |
12251 return table; | |
12252 } | |
12253 | |
12254 | |
12255 MaybeObject* ObjectHashSet::Remove(Object* key) { | |
12256 // If the object does not have an identity hash, it was never used as a key. | |
12257 if (key->IsJSReceiver() && !JSReceiver::cast(key)->HasIdentityHash()) { | |
12258 return this; | |
12259 } | |
12260 int entry = FindEntry(key); | |
12261 | |
12262 // Check whether key is actually present. | |
12263 if (entry == kNotFound) return this; | |
12264 | |
12265 // Remove entry and try to shrink this hash set. | |
12266 set_null(EntryToIndex(entry)); | |
12267 ElementRemoved(); | |
12268 return Shrink(key); | |
12269 } | |
12270 | |
12271 | |
12272 Object* ObjectHashTable::Lookup(Object* key) { | |
12273 // If the object does not have an identity hash, it was never used as a key. | |
12274 if (key->IsJSReceiver() && !JSReceiver::cast(key)->HasIdentityHash()) { | |
12275 return GetHeap()->undefined_value(); | |
12276 } | |
12180 int entry = FindEntry(key); | 12277 int entry = FindEntry(key); |
12181 if (entry == kNotFound) return GetHeap()->undefined_value(); | 12278 if (entry == kNotFound) return GetHeap()->undefined_value(); |
12182 return get(EntryToIndex(entry) + 1); | 12279 return get(EntryToIndex(entry) + 1); |
12183 } | 12280 } |
12184 | 12281 |
12185 | 12282 |
12186 MaybeObject* ObjectHashTable::Put(JSReceiver* key, Object* value) { | 12283 MaybeObject* ObjectHashTable::Put(Object* key, Object* value) { |
12187 // Make sure the key object has an identity hash code. | 12284 // Make sure the key object has an identity hash code. |
12188 int hash; | 12285 int hash; |
12189 { MaybeObject* maybe_hash = key->GetIdentityHash(ALLOW_CREATION); | 12286 if (key->IsJSReceiver()) { |
12287 MaybeObject* maybe_hash = | |
12288 JSReceiver::cast(key)->GetIdentityHash(ALLOW_CREATION); | |
12190 if (maybe_hash->IsFailure()) return maybe_hash; | 12289 if (maybe_hash->IsFailure()) return maybe_hash; |
12191 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); | 12290 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); |
12291 } else { | |
12292 hash = key->GetHash(); | |
12192 } | 12293 } |
12193 int entry = FindEntry(key); | 12294 int entry = FindEntry(key); |
12194 | 12295 |
12195 // Check whether to perform removal operation. | 12296 // Check whether to perform removal operation. |
12196 if (value->IsUndefined()) { | 12297 if (value->IsUndefined()) { |
12197 if (entry == kNotFound) return this; | 12298 if (entry == kNotFound) return this; |
12198 RemoveEntry(entry); | 12299 RemoveEntry(entry); |
12199 return Shrink(key); | 12300 return Shrink(key); |
12200 } | 12301 } |
12201 | 12302 |
12202 // Key is already in table, just overwrite value. | 12303 // Key is already in table, just overwrite value. |
12203 if (entry != kNotFound) { | 12304 if (entry != kNotFound) { |
12204 set(EntryToIndex(entry) + 1, value); | 12305 set(EntryToIndex(entry) + 1, value); |
12205 return this; | 12306 return this; |
12206 } | 12307 } |
12207 | 12308 |
12208 // Check whether the hash table should be extended. | 12309 // Check whether the hash table should be extended. |
12209 Object* obj; | 12310 Object* obj; |
12210 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 12311 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
12211 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 12312 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
12212 } | 12313 } |
12213 ObjectHashTable* table = ObjectHashTable::cast(obj); | 12314 ObjectHashTable* table = ObjectHashTable::cast(obj); |
12214 table->AddEntry(table->FindInsertionEntry(hash), key, value); | 12315 table->AddEntry(table->FindInsertionEntry(hash), key, value); |
12215 return table; | 12316 return table; |
12216 } | 12317 } |
12217 | 12318 |
12218 | 12319 |
12219 void ObjectHashTable::AddEntry(int entry, JSReceiver* key, Object* value) { | 12320 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) { |
12220 set(EntryToIndex(entry), key); | 12321 set(EntryToIndex(entry), key); |
12221 set(EntryToIndex(entry) + 1, value); | 12322 set(EntryToIndex(entry) + 1, value); |
12222 ElementAdded(); | 12323 ElementAdded(); |
12223 } | 12324 } |
12224 | 12325 |
12225 | 12326 |
12226 void ObjectHashTable::RemoveEntry(int entry, Heap* heap) { | 12327 void ObjectHashTable::RemoveEntry(int entry, Heap* heap) { |
12227 set_null(heap, EntryToIndex(entry)); | 12328 set_null(heap, EntryToIndex(entry)); |
12228 set_null(heap, EntryToIndex(entry) + 1); | 12329 set_null(heap, EntryToIndex(entry) + 1); |
12229 ElementRemoved(); | 12330 ElementRemoved(); |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12477 if (break_point_objects()->IsUndefined()) return 0; | 12578 if (break_point_objects()->IsUndefined()) return 0; |
12478 // Single break point. | 12579 // Single break point. |
12479 if (!break_point_objects()->IsFixedArray()) return 1; | 12580 if (!break_point_objects()->IsFixedArray()) return 1; |
12480 // Multiple break points. | 12581 // Multiple break points. |
12481 return FixedArray::cast(break_point_objects())->length(); | 12582 return FixedArray::cast(break_point_objects())->length(); |
12482 } | 12583 } |
12483 #endif // ENABLE_DEBUGGER_SUPPORT | 12584 #endif // ENABLE_DEBUGGER_SUPPORT |
12484 | 12585 |
12485 | 12586 |
12486 } } // namespace v8::internal | 12587 } } // namespace v8::internal |
OLD | NEW |