Chromium Code Reviews| 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 |