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 5172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5183 int CodeCacheHashTable::GetIndex(String* name, Code::Flags flags) { | 5183 int CodeCacheHashTable::GetIndex(String* name, Code::Flags flags) { |
5184 CodeCacheHashTableKey key(name, flags); | 5184 CodeCacheHashTableKey key(name, flags); |
5185 int entry = FindEntry(&key); | 5185 int entry = FindEntry(&key); |
5186 return (entry == kNotFound) ? -1 : entry; | 5186 return (entry == kNotFound) ? -1 : entry; |
5187 } | 5187 } |
5188 | 5188 |
5189 | 5189 |
5190 void CodeCacheHashTable::RemoveByIndex(int index) { | 5190 void CodeCacheHashTable::RemoveByIndex(int index) { |
5191 ASSERT(index >= 0); | 5191 ASSERT(index >= 0); |
5192 Heap* heap = GetHeap(); | 5192 Heap* heap = GetHeap(); |
5193 set(EntryToIndex(index), heap->null_value()); | 5193 set(EntryToIndex(index), heap->the_hole_value()); |
5194 set(EntryToIndex(index) + 1, heap->null_value()); | 5194 set(EntryToIndex(index) + 1, heap->the_hole_value()); |
5195 ElementRemoved(); | 5195 ElementRemoved(); |
5196 } | 5196 } |
5197 | 5197 |
5198 | 5198 |
5199 void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> cache, | 5199 void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> cache, |
5200 MapHandleList* maps, | 5200 MapHandleList* maps, |
5201 Code::Flags flags, | 5201 Code::Flags flags, |
5202 Handle<Code> code) { | 5202 Handle<Code> code) { |
5203 Isolate* isolate = cache->GetIsolate(); | 5203 Isolate* isolate = cache->GetIsolate(); |
5204 CALL_HEAP_FUNCTION_VOID(isolate, cache->Update(maps, flags, *code)); | 5204 CALL_HEAP_FUNCTION_VOID(isolate, cache->Update(maps, flags, *code)); |
(...skipping 5697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10902 uint32_t capacity = Capacity(); | 10902 uint32_t capacity = Capacity(); |
10903 uint32_t entry = FirstProbe(key->Hash(), capacity); | 10903 uint32_t entry = FirstProbe(key->Hash(), capacity); |
10904 uint32_t count = 1; | 10904 uint32_t count = 1; |
10905 | 10905 |
10906 while (true) { | 10906 while (true) { |
10907 int index = EntryToIndex(entry); | 10907 int index = EntryToIndex(entry); |
10908 Object* element = get(index); | 10908 Object* element = get(index); |
10909 if (element->IsUndefined()) break; // Empty entry. | 10909 if (element->IsUndefined()) break; // Empty entry. |
10910 if (key == element) return entry; | 10910 if (key == element) return entry; |
10911 if (!element->IsSymbol() && | 10911 if (!element->IsSymbol() && |
10912 !element->IsNull() && | 10912 !element->IsTheHole() && |
10913 String::cast(element)->Equals(key)) { | 10913 String::cast(element)->Equals(key)) { |
10914 // Replace a non-symbol key by the equivalent symbol for faster further | 10914 // Replace a non-symbol key by the equivalent symbol for faster further |
10915 // lookups. | 10915 // lookups. |
10916 set(index, key); | 10916 set(index, key); |
10917 return entry; | 10917 return entry; |
10918 } | 10918 } |
10919 ASSERT(element->IsNull() || !String::cast(element)->Equals(key)); | 10919 ASSERT(element->IsTheHole() || !String::cast(element)->Equals(key)); |
10920 entry = NextProbe(entry, count++, capacity); | 10920 entry = NextProbe(entry, count++, capacity); |
10921 } | 10921 } |
10922 return kNotFound; | 10922 return kNotFound; |
10923 } | 10923 } |
10924 | 10924 |
10925 | 10925 |
10926 template<typename Shape, typename Key> | 10926 template<typename Shape, typename Key> |
10927 MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) { | 10927 MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) { |
10928 ASSERT(NumberOfElements() < new_table->Capacity()); | 10928 ASSERT(NumberOfElements() < new_table->Capacity()); |
10929 | 10929 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11013 | 11013 |
11014 | 11014 |
11015 template<typename Shape, typename Key> | 11015 template<typename Shape, typename Key> |
11016 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { | 11016 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { |
11017 uint32_t capacity = Capacity(); | 11017 uint32_t capacity = Capacity(); |
11018 uint32_t entry = FirstProbe(hash, capacity); | 11018 uint32_t entry = FirstProbe(hash, capacity); |
11019 uint32_t count = 1; | 11019 uint32_t count = 1; |
11020 // EnsureCapacity will guarantee the hash table is never full. | 11020 // EnsureCapacity will guarantee the hash table is never full. |
11021 while (true) { | 11021 while (true) { |
11022 Object* element = KeyAt(entry); | 11022 Object* element = KeyAt(entry); |
11023 if (element->IsUndefined() || element->IsNull()) break; | 11023 if (element->IsUndefined() || element->IsTheHole()) break; |
11024 entry = NextProbe(entry, count++, capacity); | 11024 entry = NextProbe(entry, count++, capacity); |
11025 } | 11025 } |
11026 return entry; | 11026 return entry; |
11027 } | 11027 } |
11028 | 11028 |
11029 // Force instantiation of template instances class. | 11029 // Force instantiation of template instances class. |
11030 // Please note this list is compiler dependent. | 11030 // Please note this list is compiler dependent. |
11031 | 11031 |
11032 template class HashTable<SymbolTableShape, HashTableKey*>; | 11032 template class HashTable<SymbolTableShape, HashTableKey*>; |
11033 | 11033 |
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11812 // We store the value in the key slot, and compare the search key | 11812 // We store the value in the key slot, and compare the search key |
11813 // to the stored value with a custon IsMatch function during lookups. | 11813 // to the stored value with a custon IsMatch function during lookups. |
11814 cache->set(EntryToIndex(entry), value); | 11814 cache->set(EntryToIndex(entry), value); |
11815 cache->set(EntryToIndex(entry) + 1, value); | 11815 cache->set(EntryToIndex(entry) + 1, value); |
11816 cache->ElementAdded(); | 11816 cache->ElementAdded(); |
11817 return cache; | 11817 return cache; |
11818 } | 11818 } |
11819 | 11819 |
11820 | 11820 |
11821 void CompilationCacheTable::Remove(Object* value) { | 11821 void CompilationCacheTable::Remove(Object* value) { |
11822 Object* null_value = GetHeap()->null_value(); | 11822 Object* the_hole_value = GetHeap()->the_hole_value(); |
11823 for (int entry = 0, size = Capacity(); entry < size; entry++) { | 11823 for (int entry = 0, size = Capacity(); entry < size; entry++) { |
11824 int entry_index = EntryToIndex(entry); | 11824 int entry_index = EntryToIndex(entry); |
11825 int value_index = entry_index + 1; | 11825 int value_index = entry_index + 1; |
11826 if (get(value_index) == value) { | 11826 if (get(value_index) == value) { |
11827 NoWriteBarrierSet(this, entry_index, null_value); | 11827 NoWriteBarrierSet(this, entry_index, the_hole_value); |
11828 NoWriteBarrierSet(this, value_index, null_value); | 11828 NoWriteBarrierSet(this, value_index, the_hole_value); |
11829 ElementRemoved(); | 11829 ElementRemoved(); |
11830 } | 11830 } |
11831 } | 11831 } |
11832 return; | 11832 return; |
11833 } | 11833 } |
11834 | 11834 |
11835 | 11835 |
11836 // SymbolsKey used for HashTable where key is array of symbols. | 11836 // SymbolsKey used for HashTable where key is array of symbols. |
11837 class SymbolsKey : public HashTableKey { | 11837 class SymbolsKey : public HashTableKey { |
11838 public: | 11838 public: |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11977 return HashTable<Shape, Key>::EnsureCapacity(n, key); | 11977 return HashTable<Shape, Key>::EnsureCapacity(n, key); |
11978 } | 11978 } |
11979 | 11979 |
11980 | 11980 |
11981 void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) { | 11981 void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) { |
11982 // Do nothing if the interval [from, to) is empty. | 11982 // Do nothing if the interval [from, to) is empty. |
11983 if (from >= to) return; | 11983 if (from >= to) return; |
11984 | 11984 |
11985 Heap* heap = GetHeap(); | 11985 Heap* heap = GetHeap(); |
11986 int removed_entries = 0; | 11986 int removed_entries = 0; |
11987 Object* sentinel = heap->null_value(); | 11987 Object* the_hole_value = heap->the_hole_value(); |
11988 int capacity = Capacity(); | 11988 int capacity = Capacity(); |
11989 for (int i = 0; i < capacity; i++) { | 11989 for (int i = 0; i < capacity; i++) { |
11990 Object* key = KeyAt(i); | 11990 Object* key = KeyAt(i); |
11991 if (key->IsNumber()) { | 11991 if (key->IsNumber()) { |
11992 uint32_t number = static_cast<uint32_t>(key->Number()); | 11992 uint32_t number = static_cast<uint32_t>(key->Number()); |
11993 if (from <= number && number < to) { | 11993 if (from <= number && number < to) { |
11994 SetEntry(i, sentinel, sentinel); | 11994 SetEntry(i, the_hole_value, the_hole_value); |
11995 removed_entries++; | 11995 removed_entries++; |
11996 } | 11996 } |
11997 } | 11997 } |
11998 } | 11998 } |
11999 | 11999 |
12000 // Update the number of elements. | 12000 // Update the number of elements. |
12001 ElementsRemoved(removed_entries); | 12001 ElementsRemoved(removed_entries); |
12002 } | 12002 } |
12003 | 12003 |
12004 | 12004 |
12005 template<typename Shape, typename Key> | 12005 template<typename Shape, typename Key> |
12006 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, | 12006 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, |
12007 JSReceiver::DeleteMode mode) { | 12007 JSReceiver::DeleteMode mode) { |
12008 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 12008 Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
12009 PropertyDetails details = DetailsAt(entry); | 12009 PropertyDetails details = DetailsAt(entry); |
12010 // Ignore attributes if forcing a deletion. | 12010 // Ignore attributes if forcing a deletion. |
12011 if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) { | 12011 if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) { |
12012 return heap->false_value(); | 12012 return heap->false_value(); |
12013 } | 12013 } |
12014 SetEntry(entry, heap->null_value(), heap->null_value()); | 12014 SetEntry(entry, heap->the_hole_value(), heap->the_hole_value()); |
12015 HashTable<Shape, Key>::ElementRemoved(); | 12015 HashTable<Shape, Key>::ElementRemoved(); |
12016 return heap->true_value(); | 12016 return heap->true_value(); |
12017 } | 12017 } |
12018 | 12018 |
12019 | 12019 |
12020 template<typename Shape, typename Key> | 12020 template<typename Shape, typename Key> |
12021 MaybeObject* Dictionary<Shape, Key>::Shrink(Key key) { | 12021 MaybeObject* Dictionary<Shape, Key>::Shrink(Key key) { |
12022 return HashTable<Shape, Key>::Shrink(key); | 12022 return HashTable<Shape, Key>::Shrink(key); |
12023 } | 12023 } |
12024 | 12024 |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12388 | 12388 |
12389 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); | 12389 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); |
12390 // Check that it really works. | 12390 // Check that it really works. |
12391 ASSERT(obj->HasFastProperties()); | 12391 ASSERT(obj->HasFastProperties()); |
12392 | 12392 |
12393 return obj; | 12393 return obj; |
12394 } | 12394 } |
12395 | 12395 |
12396 | 12396 |
12397 bool ObjectHashSet::Contains(Object* key) { | 12397 bool ObjectHashSet::Contains(Object* key) { |
| 12398 ASSERT(IsKey(key)); |
| 12399 |
12398 // If the object does not have an identity hash, it was never used as a key. | 12400 // If the object does not have an identity hash, it was never used as a key. |
12399 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); | 12401 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); |
12400 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return false; | 12402 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return false; |
12401 } | 12403 } |
12402 return (FindEntry(key) != kNotFound); | 12404 return (FindEntry(key) != kNotFound); |
12403 } | 12405 } |
12404 | 12406 |
12405 | 12407 |
12406 MaybeObject* ObjectHashSet::Add(Object* key) { | 12408 MaybeObject* ObjectHashSet::Add(Object* key) { |
| 12409 ASSERT(IsKey(key)); |
| 12410 |
12407 // Make sure the key object has an identity hash code. | 12411 // Make sure the key object has an identity hash code. |
12408 int hash; | 12412 int hash; |
12409 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); | 12413 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); |
12410 if (maybe_hash->IsFailure()) return maybe_hash; | 12414 if (maybe_hash->IsFailure()) return maybe_hash; |
12411 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); | 12415 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); |
12412 } | 12416 } |
12413 int entry = FindEntry(key); | 12417 int entry = FindEntry(key); |
12414 | 12418 |
12415 // Check whether key is already present. | 12419 // Check whether key is already present. |
12416 if (entry != kNotFound) return this; | 12420 if (entry != kNotFound) return this; |
12417 | 12421 |
12418 // Check whether the hash set should be extended and add entry. | 12422 // Check whether the hash set should be extended and add entry. |
12419 Object* obj; | 12423 Object* obj; |
12420 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 12424 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
12421 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 12425 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
12422 } | 12426 } |
12423 ObjectHashSet* table = ObjectHashSet::cast(obj); | 12427 ObjectHashSet* table = ObjectHashSet::cast(obj); |
12424 entry = table->FindInsertionEntry(hash); | 12428 entry = table->FindInsertionEntry(hash); |
12425 table->set(EntryToIndex(entry), key); | 12429 table->set(EntryToIndex(entry), key); |
12426 table->ElementAdded(); | 12430 table->ElementAdded(); |
12427 return table; | 12431 return table; |
12428 } | 12432 } |
12429 | 12433 |
12430 | 12434 |
12431 MaybeObject* ObjectHashSet::Remove(Object* key) { | 12435 MaybeObject* ObjectHashSet::Remove(Object* key) { |
| 12436 ASSERT(IsKey(key)); |
| 12437 |
12432 // If the object does not have an identity hash, it was never used as a key. | 12438 // If the object does not have an identity hash, it was never used as a key. |
12433 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); | 12439 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); |
12434 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return this; | 12440 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return this; |
12435 } | 12441 } |
12436 int entry = FindEntry(key); | 12442 int entry = FindEntry(key); |
12437 | 12443 |
12438 // Check whether key is actually present. | 12444 // Check whether key is actually present. |
12439 if (entry == kNotFound) return this; | 12445 if (entry == kNotFound) return this; |
12440 | 12446 |
12441 // Remove entry and try to shrink this hash set. | 12447 // Remove entry and try to shrink this hash set. |
12442 set_null(EntryToIndex(entry)); | 12448 set_the_hole(EntryToIndex(entry)); |
12443 ElementRemoved(); | 12449 ElementRemoved(); |
12444 return Shrink(key); | 12450 return Shrink(key); |
12445 } | 12451 } |
12446 | 12452 |
12447 | 12453 |
12448 Object* ObjectHashTable::Lookup(Object* key) { | 12454 Object* ObjectHashTable::Lookup(Object* key) { |
| 12455 ASSERT(IsKey(key)); |
| 12456 |
12449 // If the object does not have an identity hash, it was never used as a key. | 12457 // If the object does not have an identity hash, it was never used as a key. |
12450 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); | 12458 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); |
12451 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) { | 12459 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) { |
12452 return GetHeap()->undefined_value(); | 12460 return GetHeap()->undefined_value(); |
12453 } | 12461 } |
12454 } | 12462 } |
12455 int entry = FindEntry(key); | 12463 int entry = FindEntry(key); |
12456 if (entry == kNotFound) return GetHeap()->undefined_value(); | 12464 if (entry == kNotFound) return GetHeap()->undefined_value(); |
12457 return get(EntryToIndex(entry) + 1); | 12465 return get(EntryToIndex(entry) + 1); |
12458 } | 12466 } |
12459 | 12467 |
12460 | 12468 |
12461 MaybeObject* ObjectHashTable::Put(Object* key, Object* value) { | 12469 MaybeObject* ObjectHashTable::Put(Object* key, Object* value) { |
| 12470 ASSERT(IsKey(key)); |
| 12471 |
12462 // Make sure the key object has an identity hash code. | 12472 // Make sure the key object has an identity hash code. |
12463 int hash; | 12473 int hash; |
12464 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); | 12474 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); |
12465 if (maybe_hash->IsFailure()) return maybe_hash; | 12475 if (maybe_hash->IsFailure()) return maybe_hash; |
12466 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); | 12476 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); |
12467 } | 12477 } |
12468 int entry = FindEntry(key); | 12478 int entry = FindEntry(key); |
12469 | 12479 |
12470 // Check whether to perform removal operation. | 12480 // Check whether to perform removal operation. |
12471 if (value->IsUndefined()) { | 12481 if (value->IsUndefined()) { |
(...skipping 19 matching lines...) Expand all Loading... |
12491 } | 12501 } |
12492 | 12502 |
12493 | 12503 |
12494 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) { | 12504 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) { |
12495 set(EntryToIndex(entry), key); | 12505 set(EntryToIndex(entry), key); |
12496 set(EntryToIndex(entry) + 1, value); | 12506 set(EntryToIndex(entry) + 1, value); |
12497 ElementAdded(); | 12507 ElementAdded(); |
12498 } | 12508 } |
12499 | 12509 |
12500 | 12510 |
12501 void ObjectHashTable::RemoveEntry(int entry, Heap* heap) { | 12511 void ObjectHashTable::RemoveEntry(int entry) { |
12502 set_null(heap, EntryToIndex(entry)); | 12512 set_the_hole(EntryToIndex(entry)); |
12503 set_null(heap, EntryToIndex(entry) + 1); | 12513 set_the_hole(EntryToIndex(entry) + 1); |
12504 ElementRemoved(); | 12514 ElementRemoved(); |
12505 } | 12515 } |
12506 | 12516 |
12507 | 12517 |
12508 #ifdef ENABLE_DEBUGGER_SUPPORT | 12518 #ifdef ENABLE_DEBUGGER_SUPPORT |
12509 // Check if there is a break point at this code position. | 12519 // Check if there is a break point at this code position. |
12510 bool DebugInfo::HasBreakPoint(int code_position) { | 12520 bool DebugInfo::HasBreakPoint(int code_position) { |
12511 // Get the break point info object for this code position. | 12521 // Get the break point info object for this code position. |
12512 Object* break_point_info = GetBreakPointInfo(code_position); | 12522 Object* break_point_info = GetBreakPointInfo(code_position); |
12513 | 12523 |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12752 if (break_point_objects()->IsUndefined()) return 0; | 12762 if (break_point_objects()->IsUndefined()) return 0; |
12753 // Single break point. | 12763 // Single break point. |
12754 if (!break_point_objects()->IsFixedArray()) return 1; | 12764 if (!break_point_objects()->IsFixedArray()) return 1; |
12755 // Multiple break points. | 12765 // Multiple break points. |
12756 return FixedArray::cast(break_point_objects())->length(); | 12766 return FixedArray::cast(break_point_objects())->length(); |
12757 } | 12767 } |
12758 #endif // ENABLE_DEBUGGER_SUPPORT | 12768 #endif // ENABLE_DEBUGGER_SUPPORT |
12759 | 12769 |
12760 | 12770 |
12761 } } // namespace v8::internal | 12771 } } // namespace v8::internal |
OLD | NEW |