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